首页 > 解决方案 > 将未绑定的变量传递给 R 函数

问题描述

> counties %>% select(state, county, population, poverty)
> # also written as
> select(counties , state, county, population, poverty)
> state
Error: object 'state' not found

大家好,

我有一个关于在这里传递给 select 函数的确切内容的问题statecounty,populationpoverty实际上不是绑定到封闭环境的变量,而是第一个元素的列名。这使得传递给函数的参数实际上是有状态的。

通常,在其他语言中,这些键将作为字符串传入,所以我只是想知道我们应该如何在这里推理和考虑这些未绑定的变量!也许另外,R解释器/解析器如何在幕后处理这个问题。

标签: rdplyrargumentsinterpreter

解决方案


这是一个特定于 R 的非标准评估的案例。这是 R 中一个非常强大的概念,基本上意味着您在函数select中传递的内容不会被直接评估。相反,它采用未评估的参数并稍后在数据框的上下文中对其进行评估。

我建议您阅读http://adv-r.had.co.nz/Computing-on-the-language.html上的 Advanced R 章节。

为了进一步扩展这一点,请看这个展示基本概念的示例:


expample_dataframe <- data.frame(
  foo = c(1:5),
  bar = c(10:14)
)

foo <- c("any" , "variable", "in", "global", "namespace")

print(foo) 
#> [1] "any"       "variable"  "in"        "global"    "namespace"

select_column <- function(data_frame, column_name){
  column_name <- substitute(column_name)
  eval(column_name, envir = data_frame)
}

select_column(expample_dataframe, foo)
#> [1] 1 2 3 4 5

foo
#> [1] "any"       "variable"  "in"        "global"    "namespace"

解释

substitute()不计算函数的输入,即它将其引用为symbol. 然后我们可以使用eval()允许您评估某个命名空间内的某个调用/符号的函数。是的,在 R 中,数据框是命名空间。因此

eval(column_name, envir = data_frame)column_name在数据框的上下文中进行评估。

这就是 R 中许多函数的幕后发生的事情。

reprex 包(v0.3.0)于 2020 年 8 月 14 日创建


推荐阅读