Search code examples
rdplyrnserlang

Dplyr conditional column ifelse with vector input


I am trying to use dplyr's new NSE language approach to create a conditional mutate, using a vector input. Where I am having trouble is setting the column equal to itself, see mwe below:

df <- data.frame("Name" = c(rep("A", 3), rep("B", 3), rep("C", 4)), 
                 "X" = runif(1:10), 
                 "Y" = runif(1:10)) %>% 
    tbl_df() %>% 
    mutate_if(is.factor, as.character)

ColToChange <- "Name"
ToChangeTo <- "Big"

Now, using the following:

df %>% mutate( !!ColToChange := ifelse(X >= 0.5 & Y >= 0.5, ToChangeTo, !!ColToChange))

Sets the ColToChange value to Name, not back to its original value. I am thus trying to use the syntax above to achieve this:

df %>% mutate( !!ColToChange := ifelse(X >= 0.5 & Y >= 0.5, ToChangeTo, Name))

But instead of Name, have it be the vector.


Solution

  • You need to use rlang:sym to evaluate ColToChange as a symbol Name first, then evaluate it as a column with !!:

    library(rlang); library(dplyr);
    
    df %>% mutate(!!ColToChange := ifelse(X >= 0.5 & Y >= 0.5, ToChangeTo, !!sym(ColToChange)))
    
    # A tibble: 10 x 3
    #    Name          X         Y
    #   <chr>      <dbl>     <dbl>
    # 1     A 0.05593119 0.3586310
    # 2     A 0.70024660 0.4258297
    # 3   Big 0.95444388 0.7152358
    # 4     B 0.45809482 0.5256475
    # 5   Big 0.71348123 0.5114379
    # 6     B 0.80382633 0.2665391
    # 7   Big 0.99618062 0.5788778
    # 8   Big 0.76520307 0.6558515
    # 9     C 0.63928001 0.1972674
    #10     C 0.29963517 0.5855646