Ответ 1
Обратите внимание, что следующий код имеет rlang::sym()
внутри анонимной функции и работает по назначению:
map2(c("x1","x2"), c("x2","x1"), function(a, b){
data %>%
mutate(y1 = !!rlang::sym(a)) %>%
mutate(y2 = !!rlang::sym(b)) %>%
select(y1, y2, val)})
Оригинальная проблема связана с неуверенным оператором !!
и его приоритет относительно создания анонимной функции внутри функций нестандартной оценки (NSE), таких как mutate
. Рассмотрим вложенный фрейм данных
XX <- data_frame( dfs = list(
data_frame( x = letters[1:3], y = 1:3 ),
data_frame( x = letters[4:6], y = 4:6 )) )
Если я попытаюсь выбрать первый столбец внутри каждого из внутренних фреймов данных, используя
XX %>% mutate( dfs1 = map( dfs, function(df) {
i <- 1
df %>% select(!!i)} ))
Я получаю object 'i' not found
ошибку, потому что !!
unquoting происходит относительно внешнего mutate
, прежде чем создается среда для анонимной функции (содержащей select
). Если я переведу анонимную функцию вне mutate
map( XX$dfs, function(df) {
i <- 1
df %>% select(!!i)} )
он работает без проблем, потому что map
соответствует стандартным правилам оценки, а анонимная функциональная среда теперь создается до незаметного.
Страница помощи !!
говорится, что
Привет! оператор не подтверждает свой аргумент. Он немедленно оценивается в окружающем контексте.
Это означает, что когда вы пишете сложное выражение NSE, например select
внутри mutate
, unquoting будет происходить в среде выражения в целом. Как отмечается в комментариях @lionel в комментариях, unquoting в NSE имеет приоритет над другими вещами, такими как создание анонимных функциональных сред.