将非标准评估参数传递给子集函数
Posted
技术标签:
【中文标题】将非标准评估参数传递给子集函数【英文标题】:Passing on non-standard evaluation arguments to the subset function 【发布时间】:2015-02-17 10:45:59 【问题描述】:我想在另一个函数中使用subset
,但要传递来自***函数的非标准评估参数。以下是非工作代码,但概述了这个想法:
foo_1 <- function(x, mysubset)
# some deparse, substitute etc. magic here ??
subset(x, subset)
foo_1(ansombe, x1 > 5)
我希望得到与subset(ansombe, x1 > 5)
相同的结果。另外,当参数传递到更深层次时,我希望同样的工作,即
foo_2 <- function(x, mysubset)
# some deparse, substitute etc. magic here ??
foo_1(x, mysubset)
foo_2(ansombe, x1 > 5)
这里我也想要和上面一样的结果。
到目前为止我已经尝试过什么
我尝试了substitute
-deparse
、eval
-parse
组合,比如
foo_1 <- function(x, mysubset)
tx <- deparse(substitute(mysubset))
subset(x, eval(parse(text=tx)))
foo_1(anscombe, x1 >5)
这很好,但我现在如何继续foo_2
?
另外,我记得 Thomas Lumley 的格言:
如果答案是 parse(),你通常应该重新考虑这个问题。 -- Thomas Lumley(R-help,2005 年 2 月)
所以,我想知道是否有比eval
-parse
组合更好的方法。?
有什么想法吗?
PS。这个问题类似但不包括更深的嵌套:Pass subset argument through a function to subset
PPS:也许应用plyr
中的.
函数很有成效,但我不知道如何......
【问题讨论】:
当一个简单的foo[foo[,1]<5,]
或类似的结构可以使用时,我不太喜欢使用subset
。如果您可以发布一些小的、可重复的示例数据,我们可以展示一个简单的方法来做到这一点。编辑:就像 BrodieG 所做的 :-)
【参考方案1】:
我不认为你可以避开eval
,但你可以避开parse
。只需在您的函数中重构对 subset
的调用:
foo_1 <- function(x, mysubset)
eval(call("subset", x, substitute(mysubset)), parent.frame())
foo_1(mtcars, cyl == 6 & mpg > 20)
# mpg cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
# Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
# Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
【讨论】:
【参考方案2】:可能有龙。 (但那些也隐藏在subset
中。)
foo_1 <- function(x, mysubset)
sub <- eval(substitute(mysubset), envir=x, enclos=parent.frame())
x[sub,]
foo_1(iris, Sepal.Length == 5 & Species == "setosa")
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#5 5 3.6 1.4 0.2 setosa
#8 5 3.4 1.5 0.2 setosa
#26 5 3.0 1.6 0.2 setosa
#27 5 3.4 1.6 0.4 setosa
#36 5 3.2 1.2 0.2 setosa
#41 5 3.5 1.3 0.3 setosa
#44 5 3.5 1.6 0.6 setosa
#50 5 3.3 1.4 0.2 setosa
【讨论】:
@BrodieG 嘿,别惹我们坦格利安人。【参考方案3】:只要你尽可能延迟评估,这样的事情应该可以工作
foo_1 <- function(x, mysubset)
do.call("subset", list(quote(x), substitute(mysubset)))
foo_2 <- function(x, mysubset)
do.call("foo_1", list(quote(x), substitute(mysubset)))
data(anscombe)
foo_1(anscombe, x1 > 5)
foo_2(anscombe, x1 > 5)
但如果您打算与mysubset
混在一起,则需要更加小心。确切地知道您为什么这样做会有所帮助。
【讨论】:
以上是关于将非标准评估参数传递给子集函数的主要内容,如果未能解决你的问题,请参考以下文章