I can't get rpart accept case weights defined inside a function. It keeps using the copy defined in the "global" environment (if they exists) instead of the function-defined ones. Here is what I do: test.function <- function (formula, data) { weights <- rep(.1, 100) rpart(formula, data, weights) } test.function(x~y, data) And I get an error:> Error in model.frame(formula, rownames, variables, varnames, extras, extranames, : > invalid type (closure) for variable '(weights)'If I define weights in the global environment, it uses this instead of the function-defined one (which can be verified by .Last.value$frame$wt[1]: it should equal sum(weights) and actually equals the sum of global weights, not the function one). I tried to pass a named argument (weights=weights), using other names (w, foo, ...), or both, but still it doesn't work. I found nothing in rpart doc about that behaviour... It was tested on R 2.7.0 (Windows XP) and R 2.5.1 (Linux kernel 2.6.9). For the moment, the only workaround I found is to use/modify the global weights using <<- (not very satisfying). What did I wrong? And what should I do to get it work (i.e. using the copy of weights defined inside the function)? Thanks in advance for your help. Xavier Robin -- Xavier Robin Biomedical Proteomics Research Group (BPRG) Department of Structural Biology and Bioinformatics (DBSB) Geneva University Medical Center (CMU) 1, rue Michel Servet - CH-1211 Gen?ve 4 - Switzerland Tel: (+41 22) 379 53 21
Prof Brian Ripley
2008-Jun-03 10:21 UTC
[R] Rpart and case weights: working with functions
'weights' should be a column in your 'data': that is the standard way to specify weights to a model-fitting function. On Tue, 3 Jun 2008, Xavier Robin wrote:> I can't get rpart accept case weights defined inside a function. > It keeps using the copy defined in the "global" environment (if they exists) > instead of the function-defined ones. > > Here is what I do: > > test.function <- function (formula, data) { > weights <- rep(.1, 100) > rpart(formula, data, weights) > } > > test.function(x~y, data) > > And I get an error: >> Error in model.frame(formula, rownames, variables, varnames, extras, >> extranames, : invalid type (closure) for variable '(weights)' > > > If I define weights in the global environment, it uses this instead of the > function-defined one (which can be verified by .Last.value$frame$wt[1]: it > should equal sum(weights) and actually equals the sum of global weights, not > the function one). > > I tried to pass a named argument (weights=weights), using other names (w, > foo, ...), or both, but still it doesn't work. I found nothing in rpart doc > about that behaviour... > It was tested on R 2.7.0 (Windows XP) and R 2.5.1 (Linux kernel 2.6.9). > > For the moment, the only workaround I found is to use/modify the global > weights using <<- (not very satisfying). > > > What did I wrong? And what should I do to get it work (i.e. using the copy of > weights defined inside the function)? > > Thanks in advance for your help. > > Xavier Robin > > -- > Xavier Robin > > Biomedical Proteomics Research Group (BPRG) > Department of Structural Biology and Bioinformatics (DBSB) > Geneva University Medical Center (CMU) > 1, rue Michel Servet - CH-1211 Gen?ve 4 - Switzerland > Tel: (+41 22) 379 53 21 > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >-- 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 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
A bit of fiddling suggests that the problem is less to do with rpart (which will quite happily acept weights defined inside a function) and more to do with the formula argument to the test function. This is probably because defining the formula in the global environment (as you implicitly do by placing it in the function call) drags the original formula environment along with it; try> f<-function(form) str(form) > f(y~x)to see what I mean. As a work-round, try something lik test.function <- function (formula.str, data) { weights <- rep(.1, 8) rpart(as.formula(formula.str), data, weights) } which works if formula.str is a string instead of a formula object. Alternatively, test.function <- function (form, data) { weights <- rep(.1, 8) environment(form)<-environment() #re-sets the formula environment rpart(form, data, weights) } test.function(y~x,df) ### SEEMED to work - though it looks like the sort of kludge an expert would quail at; there's ### bound to be a right way to get the formula evaluated in the current environment.>>> Xavier Robin <Xavier.Robin at medecine.unige.ch> 03/06/2008 10:33:06 >>>I can't get rpart accept case weights defined inside a function. It keeps using the copy defined in the "global" environment (if they exists) instead of the function-defined ones. ******************************************************************* This email and any attachments are confidential. Any use...{{dropped:8}}
S Ellison a ?crit :> As a work-round, try something lik > > test.function <- function (formula.str, data) { > weights <- rep(.1, 8) > rpart(as.formula(formula.str), data, weights) > } > > which works if formula.str is a string instead of a formula object.Ok, I think I got the point. The only problem with transforming the string to a formula is that rpart raises another error:> Error in t.default(x) : argument is not a matrix> test.function <- function (form, data) { > weights <- rep(.1, 8) > environment(form)<-environment() #re-sets the formula environment > rpart(form, data, weights) > }This works perfectly well. It will be good enough for what I need. Thanks a lot ;-) Xavier