`r`/`rlang`/`dplyr`:如何使 `sym` 对 `NULL` 有弹性?
`r`/`rlang`/`dplyr`: How to render `sym` resilient to `NULL`?
根据@akrun 的见解进行编辑:
这个有效:
require("magrittr")
requireNamespace("dplyr")
df <- data.frame(a = 1:5)
b_column <- c_column <- "a"
df %>% dplyr::mutate(
b = !!dplyr::sym(b_column),
c = !!dplyr::sym(c_column))
但是当 *_column
中的任何一个是 NULL
时,它不是:
c_column <- NULL
df %>% dplyr::mutate(
b = !!dplyr::sym(b_column),
c = !!dplyr::sym(c_column))
产生的错误是:
Error: Only strings can be converted to symbols
Run `rlang::last_error()` to see where the error occurred.
我如何调用任何 ensym
boled *_column
变量以使其适应 NULL
?
如果我们需要检查 NULL
个案例,请使用 if
条件
df1 <- if(!is.null(c)) {
df %>%
dplyr::mutate(b = !!dplyr::sym(c))
} else df
对于多列,一个选项是map
library(purrr)
b_column <- c_column <- "a"
map2_dfc(list(b_column, c_column), c("b", "c"), ~
if(!is.null(.x)) df %>%
transmute(!! .y := !! sym(.x))) %>%
bind_cols(df, .)
-输出
# a b c
#1 1 1 1
#2 2 2 2
#3 3 3 3
#4 4 4 4
#5 5 5 5
如果其中之一是NULL
c_column <- NULL
map2_dfc(list(b_column, c_column), c("b", "c"), ~
if(!is.null(.x)) df %>%
transmute(!! .y := !! sym(.x))) %>%
bind_cols(df, .)
# a b
#1 1 1
#2 2 2
#3 3 3
#4 4 4
#5 5 5
另一个选项是 mutate
和 across
,但请确保我们只需要 rename
非 NULL
的列
nm1 <- c("b", "c")
i1 <- !map_lgl(list(b_column, c_column), is.null)
nm2 <- nm1[i1]
df %>%
mutate(across(all_of(c(b_column, c_column)), ~ .)) %>%
rename_at(vars(everything()), ~ nm2) %>%
bind_cols(df, .)
根据@akrun 的见解进行编辑:
这个有效:
require("magrittr")
requireNamespace("dplyr")
df <- data.frame(a = 1:5)
b_column <- c_column <- "a"
df %>% dplyr::mutate(
b = !!dplyr::sym(b_column),
c = !!dplyr::sym(c_column))
但是当 *_column
中的任何一个是 NULL
时,它不是:
c_column <- NULL
df %>% dplyr::mutate(
b = !!dplyr::sym(b_column),
c = !!dplyr::sym(c_column))
产生的错误是:
Error: Only strings can be converted to symbols
Run `rlang::last_error()` to see where the error occurred.
我如何调用任何 ensym
boled *_column
变量以使其适应 NULL
?
如果我们需要检查 NULL
个案例,请使用 if
条件
df1 <- if(!is.null(c)) {
df %>%
dplyr::mutate(b = !!dplyr::sym(c))
} else df
对于多列,一个选项是map
library(purrr)
b_column <- c_column <- "a"
map2_dfc(list(b_column, c_column), c("b", "c"), ~
if(!is.null(.x)) df %>%
transmute(!! .y := !! sym(.x))) %>%
bind_cols(df, .)
-输出
# a b c
#1 1 1 1
#2 2 2 2
#3 3 3 3
#4 4 4 4
#5 5 5 5
如果其中之一是NULL
c_column <- NULL
map2_dfc(list(b_column, c_column), c("b", "c"), ~
if(!is.null(.x)) df %>%
transmute(!! .y := !! sym(.x))) %>%
bind_cols(df, .)
# a b
#1 1 1
#2 2 2
#3 3 3
#4 4 4
#5 5 5
另一个选项是 mutate
和 across
,但请确保我们只需要 rename
非 NULL
nm1 <- c("b", "c")
i1 <- !map_lgl(list(b_column, c_column), is.null)
nm2 <- nm1[i1]
df %>%
mutate(across(all_of(c(b_column, c_column)), ~ .)) %>%
rename_at(vars(everything()), ~ nm2) %>%
bind_cols(df, .)