Dear All, This is driving me nuts; I think it should be very simple (and I am sure the answer is in front of me somewhere in ch. 3 of "S programming") but I just don''t get it. It seems that "weights" never gets passed on to the second funciton as it should: myf1<-function(formula,data,weights=NULL,max.num=0,exclude.tips=NULL){ myf2<-function(formula,data,weights){ mf <- match.call() mf[[1]] <- as.name("model.frame") print("we get up to here") mf<-eval(mf,sys.frame(sys.parent())) #this is the culprit doesn''t work w <- model.weights(mf) # do several things here; for simplicity just print(w) } # the next two lines exclude certain data points if(!is.null(exclude.tips)) data<-data[match(data$Tips,exclude.tips,nomatch=0)==0,] if(max.num) data<-data[data$sim.counter<max.num+1,] myf2(formula,data,weights=weights) } The following is an example:>data.ex2<-data.frame(sim.counter=c(rep(0,3),rep(1,3)),Tips=rep(c("a","b","c"),2),y=rnorm(6),x1=rnorm(6),x2=rnorm(6)) > myf1(y~x1,data.ex2,weights=x2)[1] "we get up to here" Error in eval(expr, envir, enclos) : Object "x2" not found Why doesn''t it find x2? Isn''t x2 right there? Note that if I define myf2 as a function in the global env. and I call it, it works fine. What I am doing wrong? Thanks, Ramon P.S. In case it matters, I am using R 1.0.1 (under Linux) -- Ramón Díaz-Uriarte Dept. Zoology and Statistics University of Wisconsin-Madison Madison, WI 53706-1381 email: rdiazuri at students.wisc.edu phone: 608-238-8041 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help 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-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
On Mon, 29 May 2000, Ramon Diaz-Uriarte wrote:> Dear All, > > This is driving me nuts; I think it should be very simple (and I am sure the > answer is in front of me somewhere in ch. 3 of "S programming") but I just don''t > get it. > > It seems that "weights" never gets passed on to the second funciton as it > should: > > > > myf1<-function(formula,data,weights=NULL,max.num=0,exclude.tips=NULL){ > myf2<-function(formula,data,weights){ > mf <- match.call() > mf[[1]] <- as.name("model.frame") > print("we get up to here") > mf<-eval(mf,sys.frame(sys.parent())) #this is the culprit doesn''t work > w <- model.weights(mf) > # do several things here; for simplicity just > print(w) > } > # the next two lines exclude certain data points > if(!is.null(exclude.tips)) data<-data[match(data$Tips,exclude.tips,nomatch=0)==0,] > if(max.num) data<-data[data$sim.counter<max.num+1,] > myf2(formula,data,weights=weights) > } > > > The following is an example: > > >data.ex2<-data.frame(sim.counter=c(rep(0,3),rep(1,3)),Tips=rep(c("a","b","c"),2),y=rnorm(6),x1=rnorm(6),x2=rnorm(6)) > > myf1(y~x1,data.ex2,weights=x2) > [1] "we get up to here" > Error in eval(expr, envir, enclos) : Object "x2" not found > > Why doesn''t it find x2? Isn''t x2 right there? Note that if I define myf2 as a > function in the global env. and I call it, it works fine.Put a browser in myf2 and take a closer look. Your call is Browse[1]> mf model.frame(formula = formula, data = data, weights = weights) Now, weights is x2, and x2 exists nowhere visible (it is a column of data). So you want the value of weights substituted but not evaluated, and that gets tricky, if not impossible. So let''s look for an easier way. The usual way to do this is to assemble the call in myf1, not myf2. As in myf1 <- function(formula,data,weights=NULL,max.num=0,exclude.tips=NULL) { mf <- match.call() mf$nax.num <- mf$exclude.tips <- NULL mf[[1]] <- as.name("model.frame") myf2<-function(mf) { mf <- eval(mf,sys.frame(sys.parent(2))) w <- model.weights(mf) # do several things here; for simplicity just print(w) } # the next two lines exclude certain data points if(!is.null(exclude.tips)) data <- data[match(data$Tips,exclude.tips,nomatch=0)==0,] if(max.num) data <- data[data$sim.counter<max.num+1,] myf2(mf) } Note that I go up two parents, as the data are in the caller of myf1. eval.parent(mf, 2) would be neater, or you could do this in myf1. Another idea is to use subset= rather than the data manipulations here. -- Brian D. Ripley, ripley at 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-help 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-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Thank you very much to Prof. Ripley for his prompt (and very helpful) response!!! I think I understand the situation now; and I was happily surprised by the simplicity and elegance of setting to null two offending components returned by match.call and by going up two parents to get the data. Ramon On Tue, 30 May 2000, Prof Brian D Ripley wrote:> On Mon, 29 May 2000, Ramon Diaz-Uriarte wrote: > > > Dear All, > > > > This is driving me nuts; I think it should be very simple (and I am sure the > > answer is in front of me somewhere in ch. 3 of "S programming") but I just don''t > > get it. > > > > It seems that "weights" never gets passed on to the second funciton as it > > should: > > > > > > > > myf1<-function(formula,data,weights=NULL,max.num=0,exclude.tips=NULL){ > > myf2<-function(formula,data,weights){ > > mf <- match.call() > > mf[[1]] <- as.name("model.frame") > > print("we get up to here") > > mf<-eval(mf,sys.frame(sys.parent())) #this is the culprit doesn''t work > > w <- model.weights(mf) > > # do several things here; for simplicity just > > print(w) > > } > > # the next two lines exclude certain data points > > if(!is.null(exclude.tips)) data<-data[match(data$Tips,exclude.tips,nomatch=0)==0,] > > if(max.num) data<-data[data$sim.counter<max.num+1,] > > myf2(formula,data,weights=weights) > > } > > > > > > The following is an example: > > > > >data.ex2<-data.frame(sim.counter=c(rep(0,3),rep(1,3)),Tips=rep(c("a","b","c"),2),y=rnorm(6),x1=rnorm(6),x2=rnorm(6)) > > > myf1(y~x1,data.ex2,weights=x2) > > [1] "we get up to here" > > Error in eval(expr, envir, enclos) : Object "x2" not found > > > > Why doesn''t it find x2? Isn''t x2 right there? Note that if I define myf2 as a > > function in the global env. and I call it, it works fine. > > Put a browser in myf2 and take a closer look. Your call is > > Browse[1]> mf > model.frame(formula = formula, data = data, weights = weights) > > Now, weights is x2, and x2 exists nowhere visible (it is a column of data). > So you want the value of weights substituted but not evaluated, and that > gets tricky, if not impossible. So let''s look for an easier way. > > The usual way to do this is to assemble the call in myf1, not myf2. As in > > myf1 <- function(formula,data,weights=NULL,max.num=0,exclude.tips=NULL) > { > mf <- match.call() > mf$nax.num <- mf$exclude.tips <- NULL > mf[[1]] <- as.name("model.frame") > > myf2<-function(mf) { > mf <- eval(mf,sys.frame(sys.parent(2))) > w <- model.weights(mf) > # do several things here; for simplicity just > print(w) > } > # the next two lines exclude certain data points > if(!is.null(exclude.tips)) > data <- data[match(data$Tips,exclude.tips,nomatch=0)==0,] > if(max.num) data <- data[data$sim.counter<max.num+1,] > myf2(mf) > } > > Note that I go up two parents, as the data are in the caller of myf1. > eval.parent(mf, 2) would be neater, or you could do this in myf1. > > Another idea is to use subset= rather than the data manipulations here. > > -- > Brian D. Ripley, ripley at 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-help 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-help-request at stat.math.ethz.ch > _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help 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-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._