Отредактировано в ответ на понимание @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.
Как мне сделать вызов ЛЮБОЙ из enboled переменных sym устойчивым к тому, чтобы он был *_column?
Хорошо, но при сопоставлении аргументов довольно часто потенциальная строка по умолчанию имеет значение NULL...
Вам нужно if (!is.null(c)) df %>% dplyr::mutate(b = !!dplyr::sym(c))
Если нам нужно проверить регистр 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, .)
@balin Я предполагаю, что вы хотите вернуть исходный набор данных, когда значение для c равно NULL
Это действительно близко к варианту использования. Но смотрите мои правки выше...
@balin Можете ли вы проверить обновленное решение?
NULL
не является строкой, и имена столбцов не могут бытьNULL