我正在try 传递一个应该针对数据帧进行求值的表达式,本质上是对subset()进行镜像.问题是,我需要能够在其他功能中使用它.

这实质上意味着保留表达式,直到合适的时间(即,调用类似子集的函数)才对其求值.

我最终能够成功的方法是通过传递env和默认值sys.frame(sys.nframe()),该值应该计算为函数的帧.缺点是,这需要是每个外部函数的参数,以保留嵌套属性:

f1 = function(x, expr, env=sys.frame(sys.nframe())){
    expr = substitute(expr, env)
    eval(expr, x)
    }

f2 = function(x, expr, env=sys.frame(sys.nframe())){
    f1(x, expr, env)
    }

f3 = function(x, expr, env=sys.frame(sys.nframe())){
    f2(x, expr, env)
    }

f4 = function(x, expr){
    f2(x, expr) # no env passing
    }

m = head(mtcars, 2) # less typing

f1(m, mpg > 20) # TRUE TRUE -- expected
f2(m, mpg > 20) # TRUE TRUE -- yaay
f3(m, mpg > 20) # TRUE TRUE -- yaay
f4(m, mpg > 20) # expr      -- naay :(

我可以重写f1以使其自动展开调用堆栈并找到正确的env来替换传递的表达式吗?

推荐答案

你可以用do.call()来建立这些电话.例如

f1 = function(x, expr){
  expr = substitute(expr)
  eval(expr, x)
}

f2 = function(x, expr){
  do.call("f1", list(x, substitute(expr)))
}

f3 = function(x, expr){
  do.call("f2", list(x, substitute(expr)))
}
f1(m, mpg > 20) 
# [1] TRUE TRUE
f2(m, mpg > 20) 
# [1] TRUE TRUE
f3(m, mpg > 20) 
# [1] TRUE TRUE

但总的来说,我强烈建议不要这样做.通常,你会有一个面向用户的函数来处理非标准的判断,然后你只需要传递一个引用的语言字符串,或者,在rlang/tidyverse世界中,传递一个你可以在以后判断的问题.在try 以编程方式使用函数时,依赖嵌套的非标准求值调用通常只会导致更多令人头痛的问题.

R相关问答推荐

在R中列表的结尾添加数字载体

如何将在HW上运行的R中的消息(错误、警告等)作为批处理任务输出

如何删除R中除某些特定名称外的所有字符串?

为什么在ggplot2中添加geom_text这么慢?

如何通过Docker部署我的shiny 应用程序(多个文件)

如何在一次运行中使用count进行多列计数

将饼图插入条形图

如何对2个列表元素的所有组合进行操作?

用约翰逊分布进行均值比较

是否有新方法来更改Facet_WRAP(Ggplot2)中条文本的文本 colored颜色 ?

正则表达式在第二个管道和第二个T之后拆分R中的列

如何平滑或忽略R中变量的微小变化?

防止在更新SHINY中的Reactive Value的部分内容时触发依赖事件

减少雨云面之间的间距并绘制所有统计数据点

Ggplot2如何找到存储在对象中的残差和拟合值?

需要一个函数来在第一行创建一个新变量,然后用新变量替换一个不同的变量(对于多行)

我已经运行了几个月的代码的`Palette()`中出现了新的gglot错误

策略表单连接两个非常大的箭头数据集,而不会 destruct 内存使用

如何在一种 colored颜色 中设置数值变量的 colored颜色 和高于阈值的 colored颜色 点?

将Geojson保存为R中的shapefile