I tried to define a function like: fnx <- function(x, by.vars=Month) print(by(x, by.vars, summary)) But this doesn't work (does not find x$Month; unlike other functions, such as subset(), the INDICES argument to "by" does not look for variables in dataset x. Is fully documented, but I forget every time). So I tried using "with": fnxx <- function(x, by.vars=Month) print(with(x, by(x, by.vars, summary))) Still fails to find object x$Month. I DO have a working solution (below) - this post is just to ask: Can anyone explain what happened to the with()? FYI solutions are to call like this: fnx(airquality, airquality$Month) but this will not work generically - e.g. in my real application the dataset gets subsetted and by.vars needs to refer to the subsets. So redefine like this: fny <- function(x, by.vars=Month) { attach(x) print(by(x, by.vars, summary)) detach(x) } Simon Fear Senior Statistician Syne qua non Ltd Tel: +44 (0) 1379 644449 Fax: +44 (0) 1379 644445 email: Simon.Fear at synequanon.com web: http://www.synequanon.com Number of attachments included with this message: 0 This message (and any associated files) is confidential and\...{{dropped}}
On Wed, 27 Aug 2003, Simon Fear wrote:> I tried to define a function like: > > fnx <- function(x, by.vars=Month) > print(by(x, by.vars, summary)) > > But this doesn't work (does not find x$Month; unlike other functions, > such as > subset(), the INDICES argument to "by" does not look for variables in > dataset > x. Is fully documented, but I forget every time). So I tried using > "with": > > fnxx <- function(x, by.vars=Month) > print(with(x, by(x, by.vars, summary))) > > Still fails to find object x$Month.That's not the actual error message, is it?> I DO have a working solution (below) - this post is just to ask: Can > anyone > explain what happened to the with()?Nothing! by.vars is a variable passed to fnxx, so despite lazy evaluation, it is going to be evaluated in the environment calling fnxx(). If that fails to find it, it looks for the default value, and evaluates that in the environment of the body of fnxx. It didn't really get as far as with. (I often forget where default args are evaluated, but I believe that is correct in R as well as in S.) I think you intended Months to be a name and not a variable. With X <- data.frame(z=rnorm(20), Month=factor(rep(1:2, each=10))) fnx <- function(x, by.vars="Month") print(by(x, x[by.vars], summary)) will work, as will fnx <- function(x, by.vars=Month) print(by(x, x[deparse(substitute(by.vars))], summary)) -- 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
"Simon Fear" <Simon.Fear at synequanon.com> writes:> I tried to define a function like: > > fnx <- function(x, by.vars=Month) > print(by(x, by.vars, summary)) > > But this doesn't work (does not find x$Month; unlike other functions, > such as > subset(), the INDICES argument to "by" does not look for variables in > dataset > x. Is fully documented, but I forget every time). So I tried using > "with": > > fnxx <- function(x, by.vars=Month) > print(with(x, by(x, by.vars, summary))) > > Still fails to find object x$Month. > > I DO have a working solution (below) - this post is just to ask: Can > anyone > explain what happened to the with()? >Nothing, but by.vars is evaluated in the function frame where it is not defined. I think you're looking for something like function(x, by.vars) { if (missing(by.vars)) by.vars <- as.name("Month") print(eval.parent(substitute(with(x, by(x, by.vars, summary))))) } (Defining the default arg requires a bit of sneakiness...) -- 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
Thank you so much for that fix (to my understanding). I would be willing to add such an example to the help page for future releases - though I'm sure others would do it better - there are currently no examples where INDICES is a name. In fact in my real application it is more or less essential that INDICES is a name or at least deparse(substituted as a subscript; in a slight elaboration of my previous "fix" fnz <- function(dframe, by.vars=treat) for (pop in 1:2) { dframe.pop <- subset(dframe, ITT==pop) attach(dframe.pop) print(by(dframe.pop, by.vars, summary)) detach(dframe.pop) } the second call (when pop=2) to by() will crash because by.vars is not re-evaluated afresh - it retains its value from the first loop. So, my "fix" was wrong and I am happy to stand corrected.> -----Original Message----- > From: Prof Brian Ripley [mailto:ripley at stats.ox.ac.uk] > Sent: 27 August 2003 14:08 > To: Simon Fear > Cc: R-help at stat.math.ethz.ch > Subject: Re: [R] seeking help with with() > > > Security Warning: > If you are not sure an attachment is safe to open please contact > Andy on x234. There are 0 attachments with this message. > ________________________________________________________________ > > On Wed, 27 Aug 2003, Simon Fear wrote: > > > I tried to define a function like: > > > > fnx <- function(x, by.vars=Month) > > print(by(x, by.vars, summary)) > > > > But this doesn't work (does not find x$Month; unlike other > functions, > > such as > > subset(), the INDICES argument to "by" does not look for > variables in > > dataset > > x. Is fully documented, but I forget every time). So I tried using > > "with": > > > > fnxx <- function(x, by.vars=Month) > > print(with(x, by(x, by.vars, summary))) > > > > Still fails to find object x$Month. > > That's not the actual error message, is it? > > > I DO have a working solution (below) - this post is just to ask: Can > > anyone > > explain what happened to the with()? > > Nothing! > > by.vars is a variable passed to fnxx, so despite lazy > evaluation, it is > going to be evaluated in the environment calling fnxx(). If > that fails > to > find it, it looks for the default value, and evaluates that in the > environment of the body of fnxx. It didn't really get as far as with. > > (I often forget where default args are evaluated, but I > believe that is > correct in R as well as in S.) > > I think you intended Months to be a name and not a variable. With > > X <- data.frame(z=rnorm(20), Month=factor(rep(1:2, each=10))) > > fnx <- function(x, by.vars="Month") > print(by(x, x[by.vars], summary)) > > will work, as will > > fnx <- function(x, by.vars=Month) > print(by(x, x[deparse(substitute(by.vars))], summary)) > > > -- > 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 >Simon Fear Senior Statistician Syne qua non Ltd Tel: +44 (0) 1379 644449 Fax: +44 (0) 1379 644445 email: Simon.Fear at synequanon.com web: http://www.synequanon.com Number of attachments included with this message: 0 This message (and any associated files) is confidential and\...{{dropped}}