dear R wizards---more ignorance on my part, exacerbated by too few examples in the function documentations.> d <- data.frame( id=rep(1:3,3), x=rnorm(9), y=rnorm(9))Question 1: how do I work with the output of "by"? for example,> b <- by( d, d$id, function(x) coef(lm( y ~ x, data=x ) )) > bd$id: 1 (Intercept) x 0.2303 0.3618 --------------------------------------------------------------------------------------------------- d$id: 2 (Intercept) x 0.05785 -0.40617 --------------------------------------------------------------------------------------------------- d$id: 3 (Intercept) x 0.269 -0.378 getting the categories is easy:> names(b)[1] "1" "2" "3" but how do I transform the non-name info in this by() data structure into a matrix with dimensions 3 by 2? (presumably, there is some vector operator that can do this kind of magic.) Question 2: Let's say I want to add only one of the two coefficients to d. The naive approach a <- ave( d, d$id, FUN=function(x) coef(lm( y ~ x, data=x ))[2] ) gives me the right coefficient in each row, but overwrites every entry. I guess I can keep only the first column of a, and add it to d, but this seems a rather ugly and inefficient way. How is this done better? Question 3: repeat question 2, but keep both the intercept and the slope. thanks in advance, as always, for any advice. /iaw ---- Ivo Welch (ivo.welch at gmail.com)
Hi Ivo, See inline. On Fri, Jul 8, 2011 at 3:42 PM, ivo welch <ivowelch at gmail.com> wrote:> dear R wizards---more ignorance on my part, exacerbated by too few > examples in the function documentations. > >> d <- data.frame( id=rep(1:3,3), x=rnorm(9), y=rnorm(9)) > > Question 1: how do I work with the output of "by"? ?for example, > >> b <- by( d, d$id, function(x) coef(lm( y ~ x, data=x ) )) >> b > > d$id: 1 > (Intercept) ? ? ? ? ? x > ? ? 0.2303 ? ? ?0.3618 > --------------------------------------------------------------------------------------------------- > d$id: 2 > (Intercept) ? ? ? ? ? x > ? ?0.05785 ? ?-0.40617 > --------------------------------------------------------------------------------------------------- > d$id: 3 > (Intercept) ? ? ? ? ? x > ? ? ?0.269 ? ? ?-0.378 > > getting the categories is easy: > >> ?names(b) > ?[1] "1" "2" "3" > > but how do I transform the non-name info in this by() data structure > into a matrix with dimensions 3 by 2? ?(presumably, there is some > vector operator that can do this kind of magic.)Here is one option: a <- do.call(cbind, b)> > > Question 2: ?Let's say I want to add only one of the two coefficients > to d. ?The naive approach > ?a <- ave( d, d$id, FUN=function(x) coef(lm( y ~ x, data=x ))[2] ) > gives me the right coefficient in each row, but overwrites every > entry. ?I guess I can keep only the first column of a, and add it to > d, but this seems a rather ugly and inefficient way. ?How is this done > better?Do you actually want the coefficients duplicated for every row where id is the same? d$coef <- a[, as.character(d$id)]> > Question 3: repeat question 2, but keep both the intercept and the slope.d <- cbind(d, t(a[, as.character(d$id)])) though you'll get a rowname warning HTH, Josh> > > thanks in advance, as always, for any advice. > > /iaw > ---- > Ivo Welch (ivo.welch at gmail.com) > > ______________________________________________ > 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. >-- Joshua Wiley Ph.D. Student, Health Psychology University of California, Los Angeles https://joshuawiley.com/
Q1. simplify2array(b) gives the transpose of what I think you want. Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: r-help-bounces at r-project.org > [mailto:r-help-bounces at r-project.org] On Behalf Of ivo welch > Sent: Friday, July 08, 2011 3:43 PM > To: r-help > Subject: [R] manipulating "by" lists and "ave()" functions > > dear R wizards---more ignorance on my part, exacerbated by too few > examples in the function documentations. > > > d <- data.frame( id=rep(1:3,3), x=rnorm(9), y=rnorm(9)) > > Question 1: how do I work with the output of "by"? for example, > > > b <- by( d, d$id, function(x) coef(lm( y ~ x, data=x ) )) > > b > > d$id: 1 > (Intercept) x > 0.2303 0.3618 > -------------------------------------------------------------- > ------------------------------------- > d$id: 2 > (Intercept) x > 0.05785 -0.40617 > -------------------------------------------------------------- > ------------------------------------- > d$id: 3 > (Intercept) x > 0.269 -0.378 > > getting the categories is easy: > > > names(b) > [1] "1" "2" "3" > > but how do I transform the non-name info in this by() data structure > into a matrix with dimensions 3 by 2? (presumably, there is some > vector operator that can do this kind of magic.) > > > Question 2: Let's say I want to add only one of the two coefficients > to d. The naive approach > a <- ave( d, d$id, FUN=function(x) coef(lm( y ~ x, data=x ))[2] ) > gives me the right coefficient in each row, but overwrites every > entry. I guess I can keep only the first column of a, and add it to > d, but this seems a rather ugly and inefficient way. How is this done > better? > > Question 3: repeat question 2, but keep both the intercept > and the slope. > > > thanks in advance, as always, for any advice. > > /iaw > ---- > Ivo Welch (ivo.welch at gmail.com) > > ______________________________________________ > 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. >