4

我正在尝试搜索数据库,然后"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. 我不明白为什么!!需要 in !! 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"
4

2 回答 2

6

根据top_n文档 ( ?top_n),它不支持character/string输入,因此第一个示例不起作用。在您的第二个示例中,rlang::sym将字符串转换为变量名,然后!!将其取消引用,以便可以在内部对其进行评估top_n。注意:top_n和其他dplyr动词会自动引用它们的输入。

按照@lionel 的建议使用rlang::qq_show,我们可以看到它不起作用,因为没有count_colnameletrs_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")这些概念的介绍,请参阅 。

另请参阅以下答案:1st , 2nd , 3rd

于 2018-08-08T04:00:59.720 回答
0

所以,我意识到我在这个问题(以及许多其他问题)中挣扎的并不是真正的准引用和/或非标准评估,而是将字符串转换为对象名称。这是我的新解决方案:

letrs_top.df <- letrs_count.df %>%
    top_n(5, get(count_colname))
于 2019-03-30T03:52:26.013 回答