angusjoshi
angusjoshi

Reputation: 65

Mutate a dynamic column name with conditions using other dynamic column names

I'm trying to use dplyr::mutate to change a dynamic column with conditions using other columns dynamically.

I've got this bit of code:

d <- mtcars %>% tibble
fld_name <-  "mpg"
other_fld_name <- "cyl"
d <- d %>% mutate(!!fld_name := ifelse(!!other_fld_name < 5,NA,!!fld_name))

which sets mpg to

mpg  
   <chr>
 1 mpg  
 2 mpg  
 3 mpg  
 4 mpg  
 5 mpg  
 6 mpg  
 7 mpg  
 8 mpg  
 9 mpg  
10 mpg  

it seems to select the field on the LHS of assignment operator, but just pastes the field name on the RHS.

Removing the unquotes on the RHS yields the same result.

Any help is much appreciated.

Upvotes: 4

Views: 4000

Answers (3)

akrun
akrun

Reputation: 887951

We could also use .data

library(dplyr)
d %>%
    mutate(!! fld_name := case_when(.data[[other_fld_name]] >=5 ~ 
         .data[[fld_name]]))

-output

# A tibble: 32 x 11
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
 2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
 3  NA       4  108     93  3.85  2.32  18.6     1     1     4     1
 4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
 5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
 6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
 7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
 8  NA       4  147.    62  3.69  3.19  20       1     0     4     2
 9  NA       4  141.    95  3.92  3.15  22.9     1     0     4     2
10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
# … with 22 more rows

data

d <- mtcars %>% 
         as_tibble
fld_name <-  "mpg"
other_fld_name <- "cyl"

Upvotes: 2

Anoushiravan R
Anoushiravan R

Reputation: 21938

We can also use ensym function to quote variable name stored as string and unquote it with !! like the following:

library(rlang)

d <- mtcars %>% tibble
fld_name <-  "mpg"
other_fld_name <- "cyl"

d %>% 
  mutate(!!ensym(fld_name) := ifelse(!!ensym(other_fld_name) < 5, NA, !!ensym(fld_name)))

# A tibble: 32 x 11
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
 2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
 3  NA       4  108     93  3.85  2.32  18.6     1     1     4     1
 4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
 5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
 6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
 7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
 8  NA       4  147.    62  3.69  3.19  20       1     0     4     2
 9  NA       4  141.    95  3.92  3.15  22.9     1     0     4     2
10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
# ... with 22 more rows

Upvotes: 3

AnilGoyal
AnilGoyal

Reputation: 26238

use get to retreive column value instead

library(tidyverse)

d <- mtcars %>% tibble
fld_name <-  "mpg"
other_fld_name <- "cyl"

d %>% mutate(!!fld_name := ifelse(get(other_fld_name) < 5 ,NA, get(fld_name)))

#> # A tibble: 32 x 11
#>      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#>  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
#>  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
#>  3  NA       4  108     93  3.85  2.32  18.6     1     1     4     1
#>  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
#>  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
#>  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
#>  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
#>  8  NA       4  147.    62  3.69  3.19  20       1     0     4     2
#>  9  NA       4  141.    95  3.92  3.15  22.9     1     0     4     2
#> 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
#> # ... with 22 more rows

Created on 2021-06-22 by the reprex package (v2.0.0)

Upvotes: 6

Related Questions