Нестандартная оценка и квазиквотация в 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") для введения в эти понятия.

Смотрите также эти ответы: 1-й, 2-й, 3-й

Итак, я понял, что в этом вопросе (и во многих других проблемах) я боролся не с квази-цитатой и / или нестандартной оценкой, а с преобразованием символьных строк в имена объектов. Вот мое новое решение:

letrs_top.df <- letrs_count.df %>%
    top_n(5, get(count_colname))
Другие вопросы по тегам