将未绑定变量传递给 R 函数

Passing in unbound variables into R functions

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

大家好,

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

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

这是R-specificnon-standard评价的案例。这是 R 中一个非常强大的概念,基本上意味着您传入函数 select 的内容不会直接计算。相反,它采用未评估的参数并稍后在数据帧的上下文中对其进行评估。

我建议您阅读有关此 http://adv-r.had.co.nz/Computing-on-the-language.html 的高级 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() 函数,它允许您计算某个命名空间内的某个 call/symbol。是的,在 R 数据帧中是命名空间。于是

eval(column_name, envir = data_frame) 在数据帧的上下文中计算 column_name

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

reprex package (v0.3.0)

于 2020-08-14 创建