I'd like to use dplyr's programming magic, new to version 0.7.0, to coalesce two columns together.  Below, I've listed out a few of my attempts.
df <- data_frame(x = c(1, 2, NA), y = c(2, NA, 3))
# What I want to do:
mutate(df, y = coalesce(x, y))
# Here's the expected output:
#> # A tibble: 3 x 2
#>       x     y
#>   <dbl> <dbl>
#> 1     1     1
#> 2     2     2
#> 3    NA     3
I thought fn1 would work, but it's treating varname as character on the right-hand side.
fn1 <- function(varname) {
  mutate(df, UQ(varname) := coalesce(x, !!varname))
}
fn1("y")
# Error in mutate_impl(.data, dots) : 
#   Evaluation error: Argument 2 must be type double, not character. 
Another attempt with enquo:
fn2 <- function(varname) {
  varname <- enquo(varname)
  mutate(df, varname := coalesce(x, !!varname))
}
fn2("y")  # same error
Maybe I can splice with !!! instead?  (Spoiler: I can't.)
fn3 <- function(varname) {
  varnames <- c("x", varname)
  mutate(df, UQ(varname) := coalesce(!!! varnames))
}
fn3("y")
#> # A tibble: 3 x 2
#>       x     y
#>   <dbl> <chr>
#> 1     1     x
#> 2     2     x
#> 3    NA     x
fn4 <- function(varname) {
  varnames <- quo(c("x", varname))
  mutate(df, UQ(varname) := coalesce(!!! varnames))
}
fn4("y")
# Error in mutate_impl(.data, dots) : 
#   Column `y` must be length 3 (the number of rows) or one, not 2 
                You need to use !!sym for varname on the right side
library(rlang)
fn1 <- function(varname) {
  mutate(df, !!varname := coalesce(x, !!sym(varname)))
}
fn1("y")
# A tibble: 3 x 2
#      x     y
#  <dbl> <dbl>
#1     1     1
#2     2     2
#3    NA     3
Or use UQ:
fn1 <- function(varname) {
    mutate(df, UQ(varname) := coalesce(x, UQ(sym(varname))))
}
                        The following two approaches will work.
library(dplyr)
# Define a function to apply coalesce
col_fun1 <- function(df, Cols){
  df2 <- df %>%
    mutate(y = coalesce(!!!as.list(df %>% select(UQ(Cols)))))
  return(df2)
}
# Test the function
col_fun1(df = df, Cols = c("x", "y"))
# A tibble: 3 x 2
      x     y
  <dbl> <dbl>
1     1     1
2     2     2
3    NA     3
Or Try this.
# Define a function to apply coalesce
col_fun2 <- function(df, Cols){
  df2 <- df %>%
    mutate(y = coalesce(!!!as.list(df[, Cols])))
  return(df2)
}
# Test the function
col_fun2(df = df, Cols = c("x", "y"))
# A tibble: 3 x 2
      x     y
  <dbl> <dbl>
1     1     1
2     2     2
3    NA     3
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With