[R] Reconstruction of a "valid" expression within a function

Tony Plate tplate at acm.org
Thu Apr 28 23:39:45 CEST 2005


You are passing just a string to subset().  At the very least you need 
to parse it (but still this does not work easily with subset() -- see 
below).  But are you sure you need to do this?  subset() for dataframes 
already accepts subset expressions involving the columns of the 
dataframe, e.g.:

 > df <- data.frame(x=1:10,y=rep(1:5,2))
 > subset(df, y==2)
   x y
2 2 2
7 7 2
 >

However, it's tricky to get subset() to work with an expression for its 
subset argument.  This is because of the way it evaluates its subset 
expression (look at the code for subset.data.frame()).

 > subset(df, parse(text="df$y==2"))
Error in subset.data.frame(df, parse(text = "df$y==2")) :
         'subset' must evaluate to logical
 > subset(df, parse(text="y==2"))
Error in subset.data.frame(df, parse(text = "y==2")) :
         'subset' must evaluate to logical
 >

It's a little tricky in general passing R language expressions around, 
because many functions that work with expressions work with the 
unevaluated form of the actual argument, rather than with an R language 
expression as the value of a variable.  E.g.:

 > with(df, y==2)
  [1] FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
 > cond <- parse(text="y==2")
 > cond
expression(y == 2)
 > with(df, cond)
expression(y == 2)

One way to make these types of functions work with R language 
expressions as the value of a variable is to use do.call():

 > do.call("with", list(df, cond))
  [1] FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
 >

So, returning to subset(), you can give it an expression that is stored 
in the value of a variable like this:

 > do.call("subset", list(df, cond))
   x y
2 2 2
7 7 2
 >

However, if you're a beginner at R, I suspect that you'll get much 
further if you avoid such meta-language constructs and just find a way 
to make subset() work for you without trying to paste together R 
language expressions.

Hope this helps,

-- Tony Plate

Pascal Boisson wrote:
> Hello all,
> 
> I have some trouble in reconstructing a valid expression within a
> function,
> here is my question.
> 
> I am building a function :
> 
> SUB<-function(DF,subset=TRUE) {
> #where DF is a data frame, with Var1, Var2, Fact1, Fact2, Fact3
> #and subset would be an expression, eg. Fact3 == 1 
> 
> #in a first time I want to build a subset from DF
> #I managed to, with an expression like eg. DF$Fact3,
> # but I would like to skip the DF$ for convenience
> # so I tried something like this :
> 
> tabsub<-deparse(substitute(subset))
> dDF<-deparse(substitute(DF))
> 
> if (tabsub[1]!="TRUE") {
> subset<-paste(dDF,"$",tabsub,sep="")}
> 
> #At this point, I have a string that seems to be the expression that I
> want
> sDF<-subset(DF, subset)
> }
> 
> #But I have an error message :
> 
>>Error in r & !is.na(r) : operations are possible only for numeric or
> 
> logical types
> 
> 
> I can not understand why is that, even after I've tried to convert
> properly the string into an expression.
> I've been all the day trying to sort that problem ...
> Maybe this attempt is ackward and I have not understood what is really
> behind an expression. 
> But if anyone could give me a tip concerning this problem or point me to
> relevant references, I would really appreciate.
> 
> Thanks
> Pascal Boisson
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> 
> DISCLAIMER:\ 
> \ This email is from the Scottish Crop Researc...{{dropped}}
> 
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>




More information about the R-help mailing list