Search code examples
rloopspurrrmutatesym

How to perform a loop with sym() in r?


I have a data frame with several continuous variables. I need to generate the logarithm of each continuous variable. The names of each new variables must be made up of the original variable name adding _ln. I would like to generate a loop to do this task. The code to do it for a single variable was:

dat <- data.frame(fev1 = c(3.4, 5.8, 3.1, NA),
                  fvc = c(3.9, 6.2, 4.5, 6.0),
                  rat = c(0.8, 0.91, 0.9, NA),
                  sex = c(0, 1, 0, 1))

var <- sym('fev1')

dat <- 
  dat %>% 
  mutate('{{vari}}_ln':= log({{vari}}))

names(dat)

[1] "fev1"    "fvc"     "rat"     "sex"     "fev1_ln"

I used the following code to make a loop:

vars <- c('fev1', 'fvc', 'rat')

purrr::map(dat[vars], ~.x %>% 
             vs <- sym(~.x) %>% 
           mutate('{{vs}}_ln':= log({{vs}})))

However, it did not work. The error message was:

Error in sym(): ! Can't convert a object to a symbol.

What I want to get is a data frame with the original variables plus the new variables.

dat

fev1 fvc  rat sex  fev1_ln   fvc_ln      rat_ln
1  3.4 3.9 0.80   0 1.223775 1.360977 -0.22314355
2  5.8 6.2 0.91   1 1.757858 1.824549 -0.09431068
3  3.1 4.5 0.90   0 1.131402 1.504077 -0.10536052
4   NA 6.0   NA   1       NA 1.791759          NA

How could I make a loop for this task?

Thanks


Solution

  • dat %>%
      mutate(across(all_of(vars), log, .names = "{col}_ln"), .keep = 'none')
    
       fev1_ln   fvc_ln      rat_ln
    1 1.223775 1.360977 -0.22314355
    2 1.757858 1.824549 -0.09431068
    3 1.131402 1.504077 -0.10536052
    4       NA 1.791759          NA
    

     dat %>%
       mutate(across(all_of(vars), log, .names = "{col}_ln"), .keep = 'unused')
    
      sex  fev1_ln   fvc_ln      rat_ln
    1   0 1.223775 1.360977 -0.22314355
    2   1 1.757858 1.824549 -0.09431068
    3   0 1.131402 1.504077 -0.10536052
    4   1       NA 1.791759          NA
    

    dat %>%
      mutate(across(all_of(vars), log, .names = "{col}_ln"), .keep = 'used')
    
      fev1 fvc  rat  fev1_ln   fvc_ln      rat_ln
    1  3.4 3.9 0.80 1.223775 1.360977 -0.22314355
    2  5.8 6.2 0.91 1.757858 1.824549 -0.09431068
    3  3.1 4.5 0.90 1.131402 1.504077 -0.10536052
    4   NA 6.0   NA       NA 1.791759          NA
    

    dat %>%
     mutate(across(all_of(vars), log, .names = "{col}_ln"))
    
      fev1 fvc  rat sex  fev1_ln   fvc_ln      rat_ln
    1  3.4 3.9 0.80   0 1.223775 1.360977 -0.22314355
    2  5.8 6.2 0.91   1 1.757858 1.824549 -0.09431068
    3  3.1 4.5 0.90   0 1.131402 1.504077 -0.10536052
    4   NA 6.0   NA   1       NA 1.791759          NA