I can build a tree at the command line using
tr <- tree(V4 ~ ., dat)
but I don't know how to build one inside a function - the following does
not work
foo <- function(dummy) {
tr <- tree(V4 ~ ., dummy)
}
tr2 <- foo(dat)
and produces the error
Error in model.frame.default(formula = V4 ~ ., data = dummy) :
Object "dummy" not found
I know the solution has something to do with terms, formulas, frames,
environments, etc., but I can't figure it out (despite having read sec
3.4-3.5 of 'S progamming').
The reason I want to call 'tree' inside a function is that I am defining
a tree-based Conditional Probability Distribution (CPD) class that
should be able to be fit given an arbitrary number of parents. Currently
I implement this as shown below. This of course fails for the reason
above, but I also wondered if there was a way to avoid enumerating every
possible number of parents (I'm not sure how to make the formula "last
column ~ all other columns" in a general way).
fit.CPD.tree <- function(CPD, dat) {
print(paste("fitting tree CPD", CPD$id))
fam.vals <- dat[, c(CPD$parents, CPD$id), drop=FALSE]
print(fam.vals)
np <- length(CPD$parents)
if (np == 1)
CPD$tr <- tree(V2 ~ ., data = fam.vals)
else if (np == 2)
CPD$tr <- tree(V3 ~ ., fam.vals)
else if (np == 3)
CPD$tr <- tree(V4 ~ ., fam.vals)
else
stop(paste("too many parents for tree CPD", CPD$id))
end
list(CPD = CPD, dev = deviance(CPD$tr), score = dev)
}
Thanks for your help!
Kevin
P.S. You can reproduce the above problem using the following script
Nvars <- 4;
Nsamples <- 10;
N <- Nvars*Nsamples;
dat <- matrix(sample(1:2, N, c(0.5,0.5), replace=TRUE), Nsamples, Nvars)
#dat <- sample.bnet(bnet, 10)
dat <- as.data.frame(dat)
for (i in 1:Nvars) {
dat[,i]<- factor(dat[,i], 1:2)
}
tr <- tree(V4 ~ ., dat)
#deviance(tr)
foo <- function(dummy) {
tr <- tree(V4 ~ ., dummy)
}
tr2 <- foo(dat)
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
frames and formulas
2 messages · Kevin Murphy, Peter Dalgaard
Kevin Murphy <murphyk at cs.berkeley.edu> writes:
I can build a tree at the command line using
tr <- tree(V4 ~ ., dat)
but I don't know how to build one inside a function - the following does
not work
foo <- function(dummy) {
tr <- tree(V4 ~ ., dummy)
}
tr2 <- foo(dat)
and produces the error
Error in model.frame.default(formula = V4 ~ ., data = dummy) :
Object "dummy" not found
I know the solution has something to do with terms, formulas, frames,
environments, etc., but I can't figure it out (despite having read sec
3.4-3.5 of 'S progamming').
Jonathan Li reported the same thing just three days ago on R-help. It happens because tree uses the S-PLUS form of passing the frame number of the parent (i.e. eval(model, sys.parent())) rather than the parent environment, which conspires with an age-old bug in R that makes this work only on the command line. The quick fix is to modify the tree function to use eval(model, parent.frame()) instead. This is better R style anyway, but we'll get around to fixing eval() eventually.
O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- 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 _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._