standard evaluation arguments to the subset function

I want to use subset within another function but to pass on the non-standard evaluation arguments from the top-level function. The following is non-working code, but outlines the idea:

foo_1 <- function(x, mysubset) 
{
  # some deparse, substitute etc. magic here ??
  subset(x, subset)
}
foo_1(ansombe, x1 > 5)

I want this to get the same results as for subset(ansombe, x1 > 5) . Also, I want the same to work when the argument is passed on to a deeper level, ie

foo_2 <- function(x, mysubset) 
{  
  # some deparse, substitute etc. magic here ??
  foo_1(x, mysubset)
}
foo_2(ansombe, x1 > 5)

Here also I want the same result as above.

What I have tried so far

I tried a substitute - deparse , eval - parse combination, like

foo_1 <- function(x, mysubset)
{
  tx <- deparse(substitute(mysubset))
  subset(x, eval(parse(text=tx)))
}
foo_1(anscombe, x1 >5)

This is fine, but how do I go on for foo_2 now?

Also, I remember the dictum by Thomas Lumley:

If the answer is parse() you should usually rethink the question. -- Thomas Lumley (R-help, February 2005)

So, I was wondering if there is a better approach than an eval - parse combination.? Any ideas?

PS. This question is similar but does not include the deeper nesting: Pass subset argument through a function to subset

PPS: Maybe it is fruitful applying the . function from plyr , but I don't know how...


As long as you delay the evaulation as long as possible, something like this should work

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)

but if you plan on mucking about with mysubset you would need to be more careful.It would help to know exactly why you are doing this.


There might be dragons. (But those hide in subset too.)

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

I don't think you can avoid eval , but you can avoid parse . Just reconstruct the call to subset inside your function:

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    
链接地址: http://www.djcxy.com/p/73900.html

上一篇: 从减少人口中抽取样本

下一篇: 对子集函数的标准评估参数