Skip to content

Substituted arguments surviving multiple function calls

3 messages · Michael Hoffman, Brian Ripley, Sundar Dorai-Raj

#
I am using R 2.1.1 and have written a function that will retrieve a 
named column from a data frame:

d = data.frame(a1=c(4, 2), a2=c(6, 7))
f1 = function(x)
{
   do.call("$", list(d, substitute(x)))
}

So this works:

 > f1(a1)
[1] 4 2

However, I want to make another function, f2, which also accepts a 
column name as an argument and then calls the first function with it:

f2 = function(x)
{
   f1(substitute(x))
}

However, this does not work:

 > f2(a1)
Error in list(a1 = c(4, 2), a2 = c(6, 7))$substitute(x) :
         invalid subscript type

It works if I take the substitute() out of f1(), but then I can only 
call f1() through f2() or something that does the substitution for it.
Is there a better way to do this?

Thanks for any help you can offer.
#
I think you would do better to use [[]], which allows this sort of thing 
as character strings.

f1 <- function(x) d[[deparse(substitute(x))]]

Now f1 is looking for the *name* it is called with, so you need

f2 <- function(x) eval(substitute(f1(x), list(x=substitute(x))))

Leaving the eval off

f2n <- function(x) substitute(f1(x), list(x=substitute(x)))
f1(a1)

shows you how it works.

This really isn't a good idea, though, just to avoid a couple of quotes.
On Tue, 23 Aug 2005, Michael Hoffman wrote:

            

  
    
#
Michael Hoffman wrote:
Hi, Michael,

How about the following:

d <- data.frame(a1 = c(4, 2), a2 = c(6, 7))

f1 <- function(x, d) {
   eval(substitute(x), d)
}

f2 <- function(x, d) {
   eval(substitute(f1(x, d)), list(x = substitute(x), d = d))
}

f1(a1, d)
f2(a1, d)

Note that I redefined "f1" to do away with the "do.call". Also, it's 
always safest to pass "d" as an argument rather than rely on it being in 
  .GlobalEnv.

There may be others who suggest a different approach.

HTH,

--sundar