Home > OS >  Applying the same operation with multiple columns of similar names in R
Applying the same operation with multiple columns of similar names in R

Time:04-14

I'm wondering if there is a way to simplify this code to avoid repetition givent that the column names are similar excepting one character that increases for each operation.

out <- df %>%    
mutate (ATN1.1 = ifelse(Status == 1, NA_integer_, -100 * log(Sen1Ch1/RefCh1)),
             ATN2.1 = ifelse(Status == 1, NA_integer_, -100 * log(Sen1Ch2/RefCh2)),
             ATN3.1 = ifelse(Status == 1, NA_integer_, -100 * log(Sen1Ch3/RefCh3)),
             ATN4.1 = ifelse(Status == 1, NA_integer_, -100 * log(Sen1Ch4/RefCh4)),
             ATN5.1 = ifelse(Status == 1, NA_integer_, -100 * log(Sen1Ch5/RefCh5)),
             ATN6.1 = ifelse(Status == 1, NA_integer_, -100 * log(Sen1Ch6/RefCh6)),
             ATN7.1 = ifelse(Status == 1, NA_integer_, -100 * log(Sen1Ch7/RefCh7)))

This is a small subset of my data if you wanna play with it

df = structure(list(Status = c(1, 17, 1, 1, 1, 1, 2, 0, 0, 0), ATN1.1 = c(NA, 
NA, NA, NA, NA, NA, 0, 0.187761662304176, 0.373310604025045, 
0.570139498143909), ATN2.1 = c(NA, NA, NA, NA, NA, NA, 0, 0.136443172947395, 
0.269071359915515, 0.407552762179439), ATN3.1 = c(NA, NA, NA, 
NA, NA, NA, 0, 0.113733164068766, 0.224219770615697, 0.336923929839777
), ATN4.1 = c(NA, NA, NA, NA, NA, NA, 0, 0.0942969310983806, 
0.186894753425896, 0.279629737677226), ATN5.1 = c(NA, NA, NA, 
NA, NA, NA, 0, 0.0753327883349684, 0.149617411430523, 0.22690457078205
), ATN6.1 = c(NA, NA, NA, NA, NA, NA, 0, 0.0493106158715682, 
0.100348708536177, 0.155828822066352), ATN7.1 = c(NA, NA, NA, 
NA, NA, NA, 0, 0.0526398637123631, 0.103191368342497, 0.154644102801848
), ATN0.1.1 = c(NA, NA, NA, NA, NA, NA, 15.054824247419, 15.054824247419, 
15.054824247419, 15.054824247419), ATN0.2.1 = c(NA, NA, NA, NA, 
NA, NA, 24.1338734012274, 24.1338734012274, 24.1338734012274, 
24.1338734012274), ATN0.3.1 = c(NA, NA, NA, NA, NA, NA, 27.4233147524393, 
27.4233147524393, 27.4233147524393, 27.4233147524393), ATN0.4.1 = c(NA, 
NA, NA, NA, NA, NA, 20.8560560826831, 20.8560560826831, 20.8560560826831, 
20.8560560826831), ATN0.5.1 = c(NA, NA, NA, NA, NA, NA, 17.1645092239121, 
17.1645092239121, 17.1645092239121, 17.1645092239121), ATN0.6.1 = c(NA, 
NA, NA, NA, NA, NA, 4.4180613710882, 4.4180613710882, 4.4180613710882, 
4.4180613710882), ATN0.7.1 = c(NA, NA, NA, NA, NA, NA, 10.8192165605015, 
10.8192165605015, 10.8192165605015, 10.8192165605015), Sen1Ch1 = c(0, 
99, 0, 783198, 785643, 787093, 786717, 785935, 784922, 783784
), Sen2Ch1 = c(0, 324, 0, 793643, 796398, 798041, 798658, 798957, 
799003, 798951), Sen1Ch2 = c(0, 53, 0, 739627, 741339, 742308, 
741804, 741195, 740403, 739520), Sen2Ch2 = c(0, 416, 0, 743716, 
745420, 746399, 746532, 746599, 746467, 746279), Sen1Ch3 = c(0, 
49, 0, 720709, 722113, 722900, 722515, 722002, 721364, 720681
), Sen2Ch3 = c(0, 294, 0, 734485, 735877, 736650, 736749, 736783, 
736664, 736513), Sen1Ch4 = c(0, 61, 0, 732332, 732529, 732487, 
731524, 730678, 729723, 728756), Sen2Ch4 = c(0, 222, 0, 737261, 
737172, 736976, 736329, 735869, 735302, 734762), Sen1Ch5 = c(0, 
59, 0, 765776, 767327, 768116, 767883, 767617, 767121, 766567
), Sen2Ch5 = c(0, 248, 0, 775632, 777074, 777800, 777883, 777970, 
777832, 777655), Sen1Ch6 = c(0, 57, 0, 899145, 901398, 902644, 
902723, 902737, 902436, 902095), Sen2Ch6 = c(0, 352, 0, 926157, 
928263, 929423, 929746, 930043, 930042, 930025), Sen1Ch7 = c(0, 
45, 0, 845802, 848332, 849736, 849960, 850137, 849979, 849764
), Sen2Ch7 = c(0, 360, 0, 867160, 869852, 871321, 871830, 872308, 
872428, 872500), RefCh1 = c(0, 10100, 0, 908802, 911770, 913546, 
914536, 915344, 915862, 916336), RefCh2 = c(0, 6200, 0, 940232, 
942473, 943743, 944281, 944794, 945037, 945218), RefCh3 = c(0, 
6200, 0, 947069, 948944, 950017, 950484, 950890, 951100, 951271
), RefCh4 = c(0, 14700, 0, 900977, 901433, 901543, 901167, 900974, 
900630, 900271), RefCh5 = c(0, 8250, 0, 908355, 910304, 911295, 
911674, 912045, 912133, 912179), RefCh6 = c(0, 6200, 0, 939365, 
941703, 942978, 943500, 943980, 944147, 944314), RefCh7 = c(0, 
6200, 0, 941728, 944713, 946375, 947078, 947774, 948077, 948325
)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
))

CodePudding user response:

You can feed dynamic variable names to mutate with !!sym for example:

for(i in 1:7){
  out <- df %>%    
    mutate(!!sym(sprintf("ATN%s.1",i)) := ifelse(Status == 1, NA_integer_, -100 * log(!!sym(paste0("Sen1Ch",i))/!!sym(paste0("RefCh",i)))))
}

Note you need := inside the mutate.

CodePudding user response:

Here is a base r solution with mapply. First define an auxiliary function f to make the code more readable, then get the column names to be changed and that take part in the formula with regular expressions, finally, csall the function f in a mapply loop.

f <- function(x, y, Status) {
  ifelse(Status == 1, NA_integer_, -100 * log(x/y))
}

atn <- grep("^ATN\\d\\.1$", names(df), value = TRUE)
sen1ch <- grep("^Sen1Ch", names(df), value = TRUE)
refch <- grep("^RefCh", names(df), value = TRUE)

df[atn] <- mapply(f, df[sen1ch], df[refch], MoreArgs = list(Status = df$Status))
df
#> # A tibble: 10 x 36
#>    Status ATN1.1 ATN2.1 ATN3.1 ATN4.1 ATN5.1 ATN6.1 ATN7.1 ATN0.1.1 ATN0.2.1
#>     <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>    <dbl>    <dbl>
#>  1      1   NA     NA     NA     NA     NA    NA      NA       NA       NA  
#>  2     17  463.   476.   484.   548.   494.  469.    493.      NA       NA  
#>  3      1   NA     NA     NA     NA     NA    NA      NA       NA       NA  
#>  4      1   NA     NA     NA     NA     NA    NA      NA       NA       NA  
#>  5      1   NA     NA     NA     NA     NA    NA      NA       NA       NA  
#>  6      1   NA     NA     NA     NA     NA    NA      NA       NA       NA  
#>  7      2   15.1   24.1   27.4   20.9   17.2   4.42   10.8     15.1     24.1
#>  8      0   15.2   24.3   27.5   21.0   17.2   4.47   10.9     15.1     24.1
#>  9      0   15.4   24.4   27.6   21.0   17.3   4.52   10.9     15.1     24.1
#> 10      0   15.6   24.5   27.8   21.1   17.4   4.57   11.0     15.1     24.1
#> # ... with 26 more variables: ATN0.3.1 <dbl>, ATN0.4.1 <dbl>, ATN0.5.1 <dbl>,
#> #   ATN0.6.1 <dbl>, ATN0.7.1 <dbl>, Sen1Ch1 <dbl>, Sen2Ch1 <dbl>,
#> #   Sen1Ch2 <dbl>, Sen2Ch2 <dbl>, Sen1Ch3 <dbl>, Sen2Ch3 <dbl>, Sen1Ch4 <dbl>,
#> #   Sen2Ch4 <dbl>, Sen1Ch5 <dbl>, Sen2Ch5 <dbl>, Sen1Ch6 <dbl>, Sen2Ch6 <dbl>,
#> #   Sen1Ch7 <dbl>, Sen2Ch7 <dbl>, RefCh1 <dbl>, RefCh2 <dbl>, RefCh3 <dbl>,
#> #   RefCh4 <dbl>, RefCh5 <dbl>, RefCh6 <dbl>, RefCh7 <dbl>

Created on 2022-04-14 by the reprex package (v2.0.1)

  • Related