From murdoch at stats.uwo.ca  Thu Jul  3 02:38:00 2008
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Wed, 02 Jul 2008 20:38:00 -0400
Subject: [Rd] Constructing logical expressions dynamically
In-Reply-To: <39abe3570807021627y211f35e8u33d096dda7e5d2d@mail.gmail.com>
References: <39abe3570807021627y211f35e8u33d096dda7e5d2d@mail.gmail.com>
Message-ID: <486C1F68.2010608@stats.uwo.ca>

On 02/07/2008 7:27 PM, Tom Murray wrote:
> Hello,
> 
> I am trying to construct a logical expression dynamically, for use in the
> subset() function. I am puzzled by problems with the code that follows
> below.
> 
> Probably there's an easier way to select rows of a data frame according to
> some dynamic criteria--and I'd love to hear about it--but I'd also like to
> understand what I'm doing incorrectly in constructing the expression in my
> code.
> 
> Thanks in advance,
> 
> tm
> 
> 
> 
> # These two expressions print the same, at least.
> e1 = expression(name == 'a')

e1 is an object of class "expression":

 > class(e1)
[1] "expression"

It prints looking like a function call because R doesn't know any other 
way to print an expression.

> e2 = substitute(expression(cname == 'a'), list(cname=as.symbol('name')))

e2 is not, it's an unevaluated function call:

 > class(e2)
[1] "call"

It really is a function call, as class() tells us.

If you evaluate it, you get something just like e1:

 > class(eval(e2))
[1] "expression"


> print (e1)
> print (e2)
> 
> # But they do not evaluate the same!
> 
> # This works.
> data = data.frame(name=c('a', 'b', 'c', 'a'), age=c(1,2,3,4))
> d1 = subset(data, eval(e1))
> print (d1)
> 
> # This gives the error:
> #     Error in subset.data.frame(data, eval(e2)) :
> #       'subset' must evaluate to logical
> d2 = subset(data, eval(e2))
> print (d2)

The problem here is that eval(e2) is an expression; you need to evaluate 
it to get the logical vector, i.e.

d2 <- subset(data, eval(eval(e2)))

Duncan Murdoch



[Rd] Constructing logical expressions dynamically
Duncan Murdoch