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