`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.

我如何调用任何 ensymboled *_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

另一个选项是 mutateacross,但请确保我们只需要 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, .)