Нестандартная оценка и квазиквотация в dplyr() работают не так, как ожидалось (наивно)
Я пытаюсь найти в базе данных, а затем пометить выходной файл с именем, полученным из исходного поиска, "derived_name"
в воспроизводимом примере ниже. Я использую dplyr
труба %>%
и у меня возникли проблемы с квази-цитатой и / или нестандартной оценкой. В частности, используя count_colname
объект персонажа, полученный из "derived_name"
в финале top_n()
функция не может установить подкадр данных
search_name <- "derived_name"
set.seed(1)
letrs <- letters[rnorm(52, 13.5, 5)]
letrs_count.df <- letrs %>%
table() %>%
as.data.frame()
count_colname <- paste0(search_name, "_letr_count")
colnames(letrs_count.df) <- c("letr", count_colname)
letrs_top.df <- letrs_count.df %>%
top_n(5, count_colname)
identical(letrs_top.df, letrs_count.df)
# [1] TRUE
Основываясь на этом обсуждении, я подумал, что приведенный выше код будет работать. И этот пост заставил меня попробовать top_n_()
, который, кажется, не существует.
я обучаюсь vignette("programming")
что немного над моей головой. Этот пост заставил меня попробовать !! sym()
синтаксис, который работает, но я понятия не имею, почему! Помогите понять, почему работает приведенный ниже код. Благодарю.
colnames(letrs_count.df) <- c("letr", count_colname)
letrs_top.df <- letrs_count.df %>%
top_n(5, (!! sym(count_colname)))
letrs_top.df
# letr derived_name_letr_count
# 1 l 5
# 2 m 6
# 3 o 7
# 4 p 5
# 5 q 6
Дополнительные запутанные примеры, основанные на вопросах и комментариях @lionel и @Tung ниже. Что меня смущает, так это то, что в справочных фильмах говорится, что sym()
"взять строки в качестве входных данных и превратить их в символы" и !!
"приводит к кавычкам свой аргумент". Однако в приведенных ниже примерах sym(count_colname)
кажется, чтобы не цитировать derived_name_letr_count
, Я не понимаю, почему !!
нужен в !! sym(count_colname)
, поскольку sym(count_colname)
а также qq_show(!! sym(count_colname))
дать такое же значение.
count_colname
# [1] "derived_name_letr_count"
sym(count_colname)
# derived_name_letr_count
qq_show(count_colname)
# count_colname
qq_show(sym(count_colname))
# sym(count_colname)
qq_show(!! sym(count_colname))
# derived_name_letr_count
qq_show(!! count_colname)
# "derived_name_letr_count"
1 ответ
В соответствии с top_n
документация (?top_n
) не поддерживает character
/ string
ввод, таким образом, 1-й пример не работает. Во втором примере rlang::sym
преобразовал строку в имя переменной !!
без кавычек, чтобы его можно было оценить внутри top_n
, Замечания: top_n
и другие dplyr
глаголы автоматически указывают свои входные данные.
С помощью rlang::qq_show
как предполагает @lionel, мы видим, что это не работает, потому что нет count_colname
колонка в letrs_count.df
library(tidyverse)
set.seed(1)
letrs <- letters[rnorm(52, 13.5, 5)]
letrs_count.df <- letrs %>%
table() %>%
as.data.frame()
search_name <- "derived_name"
count_colname <- paste0(search_name, "_letr_count")
colnames(letrs_count.df) <- c("letr", count_colname)
letrs_count.df
#> letr derived_name_letr_count
#> 1 b 1
#> 2 c 1
#> 3 f 2
...
rlang::qq_show(top_n(letrs_count.df, 5, count_colname))
#> top_n(letrs_count.df, 5, count_colname)
sym
& !!
создать правильное имя столбца, существующее в letrs_count.df
rlang::qq_show(top_n(letrs_count.df, 5, !! sym(count_colname)))
#> top_n(letrs_count.df, 5, derived_name_letr_count)
letrs_count.df %>%
top_n(5, !! sym(count_colname))
#> letr derived_name_letr_count
#> 1 l 5
#> 2 m 6
#> 3 o 7
#> 4 p 5
#> 5 q 6
top_n(x, n, wt)
Аргументы:
x
:tbl()
фильтроватьn
: количество строк для возврата. Еслиx
сгруппированы, это количество строк в группе. Будет включать в себя более чемn
строки, если есть связи. Еслиn
положительный, выбирает верхn
строк. Если отрицательный, выбирает нижнююn
строк.wt
: (Необязательный). Переменная, используемая для заказа. Если не указано, по умолчанию используется последняя переменная вtbl
, Этот аргумент автоматически цитируется и позже оценивается в контексте фрейма данных. Поддерживает отмена цитирования. Увидетьvignette("programming")
для введения в эти понятия.
Итак, я понял, что в этом вопросе (и во многих других проблемах) я боролся не с квази-цитатой и / или нестандартной оценкой, а с преобразованием символьных строк в имена объектов. Вот мое новое решение:
letrs_top.df <- letrs_count.df %>%
top_n(5, get(count_colname))