Hi All,
I've been successfully using the with function for analyses and the
transform function for multiple transformations. Then I thought, why not
use "with" for both? I ran into problems & couldn't figure
them out from
help files or books. So I created a simplified version of what I'm
doing:
rm( list=ls() )
x1<-c(1,3,3)
x2<-c(3,2,1)
x3<-c(2,5,2)
x4<-c(5,6,9)
myDF<-data.frame(x1,x2,x3,x4)
rm(x1,x2,x3,x4)
ls()
myDF
This creates two new variables just fine"
transform(myDF,
sum1=x1+x2,
sum2=x3+x4
)
This next code does not see sum1, so it appears that "transform"
cannot
see the variables that it creates. Would I need to transform new
variables in a second pass?
transform(myDF,
sum1=x1+x2,
sum2=x3+x4,
total=sum1+sum2
)
Next I'm trying the same thing using "with". It doesn't not
work but
also does not generate error messages, giving me the impression that I'm
doing something truly idiotic:
with(myDF, {
sum1<-x1+x2
sum2<-x3+x4
total <- sum1+sum2
} )
myDF
ls()
Then I thought, perhaps one of the advantages of "transform" is that
it
works on the left side of the equation without using a longer name like
myDF$sum1. "with" probably doesn't do that, so I use the longer
form
below. It also does not work and generates no error messages.
# Try it again, writing vars to myDF explicitly.
# It generates no errors, and no results.
with(myDF, {
myDF$sum1<-x1+x2
myDF$sum2<-x3+x4
myDF$total <- myDF$sum1+myDF$sum2
} )
myDF
ls()
I would appreciate some advice about the relative roles of these two
functions & why my attempts with "with" have failed.
Thanks!
Bob
========================================================Bob Muenchen (pronounced
Min'-chen), Manager
Statistical Consulting Center
U of TN Office of Information Technology
200 Stokely Management Center, Knoxville, TN 37996-0520
Voice: (865) 974-5230
FAX: (865) 974-4810
Email: muenchen at utk.edu
Web: http://oit.utk.edu/scc,
News: http://listserv.utk.edu/archives/statnews.html
Muenchen, Robert A (Bob) wrote:> Hi All, > > I've been successfully using the with function for analyses and the > transform function for multiple transformations. Then I thought, why not > use "with" for both? I ran into problems & couldn't figure them out from > help files or books. So I created a simplified version of what I'm > doing: > > rm( list=ls() ) > x1<-c(1,3,3) > x2<-c(3,2,1) > x3<-c(2,5,2) > x4<-c(5,6,9) > myDF<-data.frame(x1,x2,x3,x4) > rm(x1,x2,x3,x4) > ls() > myDF > > This creates two new variables just fine" > > transform(myDF, > sum1=x1+x2, > sum2=x3+x4 > ) > > This next code does not see sum1, so it appears that "transform" cannot > see the variables that it creates. Would I need to transform new > variables in a second pass? > > transform(myDF, > sum1=x1+x2, > sum2=x3+x4, > total=sum1+sum2 > ) > > Next I'm trying the same thing using "with". It doesn't not work but > also does not generate error messages, giving me the impression that I'm > doing something truly idiotic: > > with(myDF, { > sum1<-x1+x2 > sum2<-x3+x4 > total <- sum1+sum2 > } ) > myDF > ls() > > Then I thought, perhaps one of the advantages of "transform" is that it > works on the left side of the equation without using a longer name like > myDF$sum1. "with" probably doesn't do that, so I use the longer form > below. It also does not work and generates no error messages. > > # Try it again, writing vars to myDF explicitly. > # It generates no errors, and no results. > with(myDF, { > myDF$sum1<-x1+x2 > myDF$sum2<-x3+x4 > myDF$total <- myDF$sum1+myDF$sum2 > } ) > myDF > ls() > > I would appreciate some advice about the relative roles of these two > functions & why my attempts with "with" have failed. >Yes, transform() calculates all its new values, then assigns to the given names. This is expedient, but it has the drawback that new variables are not usable inside the expressions. A possible alternative implementation would be equivalent to a series of nested calls to transform, which of course you could also do manually: transform( transform(myDF, sum1=x1+x2, sum2=x3+x4 ), total=sum1+sum2 ) The problem with with() on data frames and lists is that, like the "eval" family of functions, _converts_ the object to an environment, and then evaluates the expression in the converted environment. The environment is temporary, so assignments to it get lost. The current development sources has a new (experimental) function within() which is like with(), but stores any modified variables back. (This is very recent and may or may not make it to 2.6.0). -- O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
Try this version of transform. In the first test we show
it works on your example but we have used the head of the built in
anscombe data set. The second and third show that
it necessarily is incompatible with transform because transform
always looks up variables in DF first whereas my.transform looks
up the computed ones first.
my.transform <- function(DF, ...) {
f <- function(){}
formals(f) <- eval(substitute(as.pairlist(c(alist(...), DF))))
body(f) <- substitute(modifyList(DF, data.frame(...)))
f()
}
# test
a <- head(anscombe)
# 1
my.transform(a, sum1 = x1+x2+x3+x4, sum2 = y1+y2+y3+y4, total = sum1+sum2)
# 2
my.transform(a, y2 = y1, y3 = y2)
# 3
transform(a, y2 = y1, y3 = y2) # different
On 9/1/07, Muenchen, Robert A (Bob) <muenchen at utk.edu>
wrote:> Hi All,
>
> I've been successfully using the with function for analyses and the
> transform function for multiple transformations. Then I thought, why not
> use "with" for both? I ran into problems & couldn't
figure them out from
> help files or books. So I created a simplified version of what I'm
> doing:
>
> rm( list=ls() )
> x1<-c(1,3,3)
> x2<-c(3,2,1)
> x3<-c(2,5,2)
> x4<-c(5,6,9)
> myDF<-data.frame(x1,x2,x3,x4)
> rm(x1,x2,x3,x4)
> ls()
> myDF
>
> This creates two new variables just fine"
>
> transform(myDF,
> sum1=x1+x2,
> sum2=x3+x4
> )
>
> This next code does not see sum1, so it appears that "transform"
cannot
> see the variables that it creates. Would I need to transform new
> variables in a second pass?
>
> transform(myDF,
> sum1=x1+x2,
> sum2=x3+x4,
> total=sum1+sum2
> )
>
> Next I'm trying the same thing using "with". It doesn't
not work but
> also does not generate error messages, giving me the impression that
I'm
> doing something truly idiotic:
>
> with(myDF, {
> sum1<-x1+x2
> sum2<-x3+x4
> total <- sum1+sum2
> } )
> myDF
> ls()
>
> Then I thought, perhaps one of the advantages of "transform" is
that it
> works on the left side of the equation without using a longer name like
> myDF$sum1. "with" probably doesn't do that, so I use the
longer form
> below. It also does not work and generates no error messages.
>
> # Try it again, writing vars to myDF explicitly.
> # It generates no errors, and no results.
> with(myDF, {
> myDF$sum1<-x1+x2
> myDF$sum2<-x3+x4
> myDF$total <- myDF$sum1+myDF$sum2
> } )
> myDF
> ls()
>
> I would appreciate some advice about the relative roles of these two
> functions & why my attempts with "with" have failed.
>
> Thanks!
> Bob
>
> ========================================================> Bob Muenchen
(pronounced Min'-chen), Manager
> Statistical Consulting Center
> U of TN Office of Information Technology
> 200 Stokely Management Center, Knoxville, TN 37996-0520
> Voice: (865) 974-5230
> FAX: (865) 974-4810
> Email: muenchen at utk.edu
> Web: http://oit.utk.edu/scc,
> News: http://listserv.utk.edu/archives/statnews.html
>
> ______________________________________________
> R-help at stat.math.ethz.ch 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.
>