代码之家  ›  专栏  ›  技术社区  ›  Josh

dplyr()中的非标准评估和QuasiQuote未按预期(天真地)工作

  •  4
  • Josh  · 技术社区  · 7 年前

    我试图搜索一个数据库,然后用源于原始搜索的名称标记输出。 "derived_name" 在下面的可复制示例中。我用的是 dplyr %>% 我对质量报价和/或非标准评估有困难。具体来说,使用 count_colname ,从中派生的字符对象 “派生的名称” ,在决赛中 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
    

    基于 this discussion 我以为上面的代码可以用。和 this post 引导我尝试 top_n_() 似乎不存在。

    我在学习 vignette("programming") 有点过头了。 This post 引导我尝试 !! 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 ou 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"
    
    2 回复  |  直到 7 年前
        1
  •  5
  •   Tung    7 年前

    根据 top_n 文件( ?top_n )不支持 character / string 因此,第一个示例不起作用。在第二个例子中, rlang::sym 将字符串转换为变量名,然后 !! 未引用,以便在内部进行评估 托普津 . 注: top_n 以及其他 dplyr verbs 自动引用他们的输入。

    使用 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") 对这些概念的介绍。

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

        2
  •  0
  •   Josh    7 年前

    所以,我意识到,我在这个问题(以及许多其他问题)中所努力解决的不是真正的质量评价和/或非标准评价,而是 converting character strings into object names . 这是我的新解决方案:

    letrs_top.df <- letrs_count.df %>%
        top_n(5, get(count_colname))