Given a data set with a group factor, I want to translate the numeric variables to their centroid, by subtracting out the group means (adding back the grand means). The following gives what I want, but there must be an easier way using sweep or apply or some such. iris2 <- iris[,c(1,2,5)] means <- colMeans(iris2[,1:2]) pooled <- lm(cbind(Sepal.Length, Sepal.Width) ~ Species, data=iris2)$residuals pooled[,1] <- pooled[,1] + means[1] pooled[,2] <- pooled[,2] + means[2] pooled <- as.data.frame(pooled) pooled$Species <- iris2$Species -- Michael Friendly Email: friendly AT yorku DOT ca Professor, Psychology Dept. & Chair, Quantitative Methods York University Voice: 416 736-2100 x66249 Fax: 416 736-5814 4700 Keele Street Web: http://www.datavis.ca Toronto, ONT M3J 1P3 CANADA
On 01/01/2013 19:50, Michael Friendly wrote:> Given a data set with a group factor, I want to translate the numeric > variables to their > centroid, by subtracting out the group means (adding back the grand means). > > The following gives what I want, but there must be an easier way using > sweep or > apply or some such.Yes. It is part of the calculation of within-group covariances in LDA, so (from MASS:::lda.default) group.means <- tapply(x, list(rep(g, p), col(x)), mean) x - group.means[g, ] shows the idiom.> > iris2 <- iris[,c(1,2,5)] > means <- colMeans(iris2[,1:2]) > > pooled <- lm(cbind(Sepal.Length, Sepal.Width) ~ Species, > data=iris2)$residuals > pooled[,1] <- pooled[,1] + means[1] > pooled[,2] <- pooled[,2] + means[2] > pooled <- as.data.frame(pooled) > pooled$Species <- iris2$Species >-- 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
On 01/01/2013 20:43, Prof Brian Ripley wrote:> On 01/01/2013 19:50, Michael Friendly wrote: >> Given a data set with a group factor, I want to translate the numeric >> variables to their >> centroid, by subtracting out the group means (adding back the grand >> means). >> >> The following gives what I want, but there must be an easier way using >> sweep or >> apply or some such. > > Yes. It is part of the calculation of within-group covariances in LDA, > so (from MASS:::lda.default) > > group.means <- tapply(x, list(rep(g, p), col(x)), mean) > x - group.means[g, ] > > shows the idiom.There is also rowsum() (but that postdates that code).> >> >> iris2 <- iris[,c(1,2,5)] >> means <- colMeans(iris2[,1:2]) >> >> pooled <- lm(cbind(Sepal.Length, Sepal.Width) ~ Species, >> data=iris2)$residuals >> pooled[,1] <- pooled[,1] + means[1] >> pooled[,2] <- pooled[,2] + means[2] >> pooled <- as.data.frame(pooled) >> pooled$Species <- iris2$Species >> > >-- 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
On 1/1/2013 3:43 PM, Prof Brian Ripley wrote:> On 01/01/2013 19:50, Michael Friendly wrote: >> Given a data set with a group factor, I want to translate the numeric >> variables to their >> centroid, by subtracting out the group means (adding back the grand >> means). >>...> > Yes. It is part of the calculation of within-group covariances in LDA, > so (from MASS:::lda.default) > > group.means <- tapply(x, list(rep(g, p), col(x)), mean) > x - group.means[g, ] > > shows the idiom.thanks for this, Brian-- just the idiom I was looking for. However, I want the result to be centered at the grand means, so: pool <- function(x, groups){ x <- as.matrix(x) p <- ncol(x) n <- nrow(x) g <- as.factor(groups) group.means <- tapply(x, list(rep(g, p), col(x)), mean) grand.mean <- colMeans(x) x - group.means[g, ] + outer(rep(1,n), grand.mean) } pooled <- data.frame(pool(iris[,1:4], iris[,5])) pooled$Species <- iris$Species -- Michael Friendly Email: friendly AT yorku DOT ca Professor, Psychology Dept. & Chair, Quantitative Methods York University Voice: 416 736-2100 x66249 Fax: 416 736-5814 4700 Keele Street Web: http://www.datavis.ca Toronto, ONT M3J 1P3 CANADA