在编程中使用dplyr合并

kar*_*ldw 6 r dplyr rlang

我想将dplyr的编程魔术(新于0.7.0版)用于coalesce两列。在下面,我列出了一些尝试。

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
Run Code Online (Sandbox Code Playgroud)

我以为fn1可以用,但是它varname在右侧被视为角色。

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. 
Run Code Online (Sandbox Code Playgroud)

另一个尝试enquo

fn2 <- function(varname) {
  varname <- enquo(varname)
  mutate(df, varname := coalesce(x, !!varname))
}
fn2("y")  # same error
Run Code Online (Sandbox Code Playgroud)

也许我可以改嫁!!!吗?(剧透:我不能。)

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 
Run Code Online (Sandbox Code Playgroud)

Psi*_*dom 3

你需要在右侧使用!!symforvarname

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
Run Code Online (Sandbox Code Playgroud)

或者使用UQ

fn1 <- function(varname) {
    mutate(df, UQ(varname) := coalesce(x, UQ(sym(varname))))
}
Run Code Online (Sandbox Code Playgroud)