Я хочу написать функцию, которая будет принимать как символические имена столбцов, так и имена, переданные как переменная (строка).
Позвольте мне показать вам пример:
Данные:
> ( d <- data.frame(A=1:3, B=3:1) )
A B
1 1 3
2 2 2
3 3 1
Теперь моя функция:
fn <- function(data, cols) {
return(data %>% mutate(across({{cols}}, ~. * 2)))
}
Он хорошо работает для:
А) символические имена
> d %>% fn(cols = A)
A B
1 2 3
2 4 2
3 6 1
> d %>% fn(cols = B)
A B
1 1 6
2 2 4
3 3 2
> d %>% fn(cols = c(A, B))
A B
1 2 6
2 4 4
3 6 2
Б) имена передаются как строки
> column <- "A"
> d %>% fn(cols = column)
A B
1 2 3
2 4 2
3 6 1
> d %>% fn(cols = c("A", "B"))
A B
1 2 6
2 4 4
3 6 2
Все идет нормально!
Теперь, когда я предоставляю внешний вектор › 1 столбец, он выдает предупреждение.
> d %>% fn(cols = columns)
Note: Using an external vector in selections is ambiguous.
i Use `all_of(columns)` instead of `columns` to silence this message.
i See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
This message is displayed once per session.
A B
1 2 6
2 4 4
3 6 2
Поэтому я добавил функцию all_of, которая хорошо работает со строками:
fn <- function(data, cols) {
return(data %>% mutate(across(all_of({{cols}}), ~. * 2)))
}
> d %>% fn(cols = columns)
A B
1 2 6
2 4 4
3 6 2
но выдает ошибку, когда я передаю символическое имя:
> d %>% fn(cols = A)
Error: Problem with `mutate()` input `..1`.
x object 'A' not found
i Input `..1` is `across(all_of(A), ~. * 2)`.
Run `rlang::last_error()` to see where the error occurred. > d %>% fn(cols = B)
> d %>% fn(cols = c(A, B))
Error: Problem with `mutate()` input `..1`.
x object 'A' not found
i Input `..1` is `across(all_of(c(A, B)), ~. * 2)`.
Run `rlang::last_error()` to see where the error occurred.
Как это исправить, чтобы включить оба подхода и избежать предупреждения?