Skip to content

eval functions... (PR#668)

4 messages · aprasad@fs.fed.us, Peter Dalgaard, Douglas Bates +1 more

#
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

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......

Thanks much.


-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
aprasad@fs.fed.us writes:
Um, I'm somewhat surprised that this gives sensible results in
Splus... It does, since Splus accepts a text string for a formula
which R does not. 

[The use of eval is also unnecessary, and the sep="" is peculiar in
view of the spaces around the ~...]

In R you need to jump through an extra hoop to create a formula object
from the string representation:

lmexp <- formula(paste(resp, "~", pickedlist))
tmpzx <- lm(lmexp,data=xd)

The Splus docs explicitly say that the first argument to lm should be
a formula object, and R's behaviour is consistent with that.
#
aprasad@fs.fed.us writes:
I think in both R and S-PLUS you would be better off using as.formula.
iv802 ~ BD + CEC + CLAY + ERODFAC + INCEPTSL

You may want to use Bill Venables' favorite function do.call as well.  Try

resp <- "iv802"
pickedlist <- "BD + CEC + CLAY + ERODFAC + INCEPTSL"
tmpzx <- do.call("lm", 
          list(formula = as.formula(paste(resp, "~", pickedlist)),
               data = xd))

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
On Fri, 22 Sep 2000 aprasad@fs.fed.us wrote:

            
A tracback helps ...
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
Error in x[[j]] : subscript out of bounds
[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.)