[Rd] eval functions... (PR#668)

Prof Brian D Ripley ripley@stats.ox.ac.uk
Sat, 23 Sep 2000 07:42:49 +0100 (BST)


On Fri, 22 Sep 2000 aprasad@fs.fed.us wrote:

> Full_Name: Anantha Prasad
> Version: 1.1.1
> OS: Linux
> Submission from: (NULL) (199.131.134.30)
> 
> 
> I am trying to convert some S-PLUS code to R (a tcl/tk application that uses
> R)...
> here is the error I got in R (but not in S-PLUS)...so I am wondering if it is a
> bug.
> 
> Eg., the foll. extract from a function runs fine in S-PLUS but gives the error:
> Error in x[[j]] : subscript out of bounds
> in R

A tracback helps ...

> 
> code snippet .....
> 
>  attach(xd)
> 	 resp <- "iv802"
> 	pickedlist <- "BD + CEC + CLAY + ERODFAC + INCEPTSL"
> 	lmexp <- paste(resp, " ~ ", pickedlist,sep="")
>         tmpzx <- eval(lm(lmexp,data=xd))
> 
> Essentially, I want to do:
>  lm(iv802 ~ BD + CEC + CLAY + ERODFAC + INCEPTSL, data=xd)
> thru a function that has the parameters passed thru TclTk and Perl......

I don't understand why that would work in S-PLUS!  You apply eval to
expressions or calls, but lm(mexp,data=xd) is not a call. Probably S-PLUS
has an implicit as.formula in its version.

The essence can be seen in

> lm(formula="y ~ x")
Error in x[[j]] : subscript out of bounds
> traceback()
[1] "eval(expr, envir, enclos)"                                        
[2] "eval(attr(formula, \"variables\"), data, sys.frame(sys.parent()))"
[3] "model.frame.default(formula = y ~ x, drop.unused.levels = TRUE)"  
[4] "model.frame(formula = y ~ x, drop.unused.levels = TRUE)"          
[5] "eval(expr, envir, enclos)"                                        
[6] "eval(mf, sys.frame(sys.parent()))"                                
[7] "lm(formula = y ~ x)"                                              

The point is that the formula argument should be a formula, not a 
character string, so this is not a bug per se.

There are lots of correct ways to do this.  Perhaps the simplest is

lm(as.formula(lmexp), data=xd)

but that will record the call as 

lm(formula = as.formula(lmexp), data = xd)

To avoid that, if you need to, use something like

do.call("lm", list(formula = as.formula(lmexp), data=xd))

(There are lots more ways too, including using parse or substitute.)

-- 
Brian D. Ripley,                  ripley@stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272860 (secr)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._