【问题标题】:Error getting column name using R tidyeval [duplicate]使用 R tidyeval 获取列名时出错 [重复]
【发布时间】:2019-11-15 10:13:22
【问题描述】:

我正在编写一个通用查找函数来针对小标题执行。当我运行下面的代码时,我得到“错误:找不到对象'x'”

我的真实函数返回不同的错误消息,但我认为对此提供一些指导会有所帮助。

请看下面的代码

library(dplyr)
library(tibble)

fruits <- tibble(
  x = 1:5, 
  y = c("apple", "peach", "pear", "strawberry", "orange")
)

gLookup <- function(datasource, indexColumn, targetValue, lookupColumn){
  datasource %>% 
    filter(indexColumn == targetValue) %>% 
    select(lookupColumn) %>% 
    unlist() %>% 
    unname
}

gLookup(fruits, x, 3, y)

我希望返回“pear”,但我得到的是: 错误:找不到对象“x”

【问题讨论】:

  • 找不到更合适的副本。除非事情发生了变化,否则dplyr 使用NSE,因此您需要!!enquosym 等。
  • 或新的{{,如filter({{indexColumn}} == {{targetValue}}) %&gt;%lookupColumn 也应该这样做。

标签: r dplyr tidyverse rlang tidyeval


【解决方案1】:

Writing functions with dplyr is a little complicated 因为它的非标准评估。它后面有a solid framework,但需要学习一些工作。对于手头的问题,您需要替换并引用您传入的列名(使用rlang::enquo),然后在要使用它们时取消引用(使用!!)。

library(dplyr)

fruits <- tibble::tibble(
    x = 1:5, 
    y = c("apple", "peach", "pear", "strawberry", "orange")
)

gLookup <- function(datasource, indexColumn, targetValue, lookupColumn){
    indexColumn <- enquo(indexColumn)    # substitute and quote
    lookupColumn <- enquo(lookupColumn)

    datasource %>% 
        filter(!!indexColumn == targetValue) %>%    # unquote with !!
        select(!!lookupColumn) %>% 
        unlist() %>% 
        unname
}

gLookup(fruits, x, 3, y)
#> [1] "pear"

如果您有新版本的 rlang,您可以使用 {{...}} 进行替换、引用和取消引用:

gLookup <- function(datasource, indexColumn, targetValue, lookupColumn){
    datasource %>% 
        filter({{indexColumn}} == targetValue) %>%    # both substitute and quote with `{{...}}`
        select({{lookupColumn}}) %>% 
        unlist() %>% 
        unname
}

gLookup(fruits, x, 3, y)
#> [1] "pear"

【讨论】:

  • 太棒了!我永远不会自己解决这个问题。这也解决了“真实”功能中的问题。谢谢。
  • 我的问题通过使用 {{}} 运算符就解决了: datasource %>% filter({{indexColumn}} == targetValue) %>% select({{lookupColumn}}) %> % unlist() %>% unname
  • 关于“substitute,quote”部分的东西,我直接将它翻译成substitute(quote()),这是行不通的。
  • substitute 有点像enquo(有时是{{...}}); quote 就像 quo!! 并没有真正的基本等价物;也许.(...)bquote。不过,当 rlang(其 quosures 比原始表达式更健壮)已经内置到 dplyr 中时,我不确定使用基本 NSE 的意义。
猜你喜欢
  • 2020-11-06
  • 2018-12-22
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多