在编程中使用 dplyr coalesce
Use dplyr coalesce in programming
我想使用 dplyr 的 programming magic,版本 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
我认为 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.
再次尝试 enquo
:
fn2 <- function(varname) {
varname <- enquo(varname)
mutate(df, varname := coalesce(x, !!varname))
}
fn2("y") # same error
也许我可以用!!!
拼接? (剧透:我不能。)
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
以下两种方法都行得通。
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
或者试试这个。
# 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
右边的varname
需要用!!sym
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
或使用UQ
:
fn1 <- function(varname) {
mutate(df, UQ(varname) := coalesce(x, UQ(sym(varname))))
}
我想使用 dplyr 的 programming magic,版本 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
我认为 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.
再次尝试 enquo
:
fn2 <- function(varname) {
varname <- enquo(varname)
mutate(df, varname := coalesce(x, !!varname))
}
fn2("y") # same error
也许我可以用!!!
拼接? (剧透:我不能。)
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
以下两种方法都行得通。
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
或者试试这个。
# 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
右边的varname
需要用!!sym
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
或使用UQ
:
fn1 <- function(varname) {
mutate(df, UQ(varname) := coalesce(x, UQ(sym(varname))))
}