Search code examples
rdplyrcoalesce

Pass a string as variable name in dplyr::coalesce


I'm trying to create a new column with the first NA value from a set of columns using a variable for the column names in dplyr::coalesce(). How to make it work?

I have tried using coalesce() with the actual column names and it works. It fails when I pass it a variable.

tb <- tibble(a = c("a", NA, "a", NA, "a"), 
            b = c(NA, "b", NA, NA, NA), 
            c = c('c', 'c', 'c', 'c', NA))

df <- tb %>%
  mutate(combined = coalesce(a, b, c))

This works with the following output

# A tibble: 5 x 4
  a     b     c     combined
  <chr> <chr> <chr> <chr>   
1 a     NA    c     a       
2 NA    b     c     b       
3 a     NA    c     a       
4 NA    NA    c     c       
5 a     NA    NA    a 

However, when I create a variable for the column names:

uCols <- c("a", "b", "c")

and run similar code:

df <- tb %>%
  mutate(combined = coalesce(uCols))

I get the following error:

Error: Column `combined` must be length 5 (the number of rows) or one, not 3

I have tried using enexprs(uCols) but that does not work.

How do I pass the uCols variable to coalesce() so that it works as desired?


Solution

  • An option would be to convert the strings to symbols (syms from rlang) and then evaluate (!!!)

    library(dplyr)
    tb %>%
       mutate(combined = coalesce(!!! rlang::syms(uCols)))
    # A tibble: 5 x 4
    #  a     b     c     combined
    #  <chr> <chr> <chr> <chr>   
    #1 a     <NA>  c     a       
    #2 <NA>  b     c     b       
    #3 a     <NA>  c     a       
    #4 <NA>  <NA>  c     c       
    #5 a     <NA>  <NA>  a       
    

    Or another option is do.call

    tb %>%
       mutate(combined = select(., uCols) %>% 
                              do.call(coalesce, .))