вычислить средства группы по фактору - PullRequest
9 голосов
/ 04 октября 2010

Есть ли способ, которым это можно улучшить или сделать проще?

means.by<-function(data,INDEX){
  b<-by(data,INDEX,function(d)apply(d,2,mean))
  return(structure(
    t(matrix(unlist(b),nrow=length(b[[1]]))),
      dimnames=list(names(b),col.names=names(b[[1]]))
  ))
}

Идея та же, что и в выражении SAS MEANS BY.Функция 'means.by' принимает data.frame и индексную переменную и вычисляет среднее значение по столбцам data.frame для каждого набора строк, соответствующих уникальным значениям INDEX, и возвращает новый фрейм данных со строкойназывает уникальные значения INDEX.

Я уверен, что должен быть лучший способ сделать это в R, но я ничего не мог придумать.

Ответы [ 4 ]

13 голосов
/ 04 октября 2010

Выполняет ли агрегатная функция то, что вам нужно?

Если нет, посмотрите на пакет plyr, он дает несколько вариантов для разборки вещей, выполнения вычислений на куски, а затем снова собирает их вместе.

Вы также можете сделать это с помощью пакета reshape.

5 голосов
/ 04 октября 2010

Вы хотите tapply или ave, в зависимости от того, как вы хотите, чтобы ваш вывод:

> Data <- data.frame(grp=sample(letters[1:3],20,TRUE),x=rnorm(20))
> ave(Data$x, Data$grp)
 [1] -0.3258590 -0.5009832 -0.5009832 -0.2136670 -0.3258590 -0.5009832
 [7] -0.3258590 -0.2136670 -0.3258590 -0.2136670 -0.3258590 -0.3258590
[13] -0.3258590 -0.5009832 -0.2136670 -0.5009832 -0.3258590 -0.2136670
[19] -0.5009832 -0.2136670
> tapply(Data$x, Data$grp, mean)
         a          b          c 
-0.5009832 -0.2136670 -0.3258590 

# Example with more than one column:
> Data <- data.frame(grp=sample(letters[1:3],20,TRUE),x=rnorm(20),y=runif(20))
> do.call(rbind,lapply(split(Data[,-1], Data[,1]), mean))
             x         y
a -0.675195494 0.4772696
b  0.270891403 0.5091359
c  0.002756666 0.4053922
4 голосов
/ 05 октября 2010

с плиром

library(plyr)
df <- ddply(x, .(id),function(x) data.frame(
mean=mean(x$var)
))
print(df)

Обновление:

data<-data.frame(I=as.factor(rep(letters[1:10],each=3)),x=rnorm(30),y=rbinom(30,5,.5))
ddply(data,.(I), function(x) data.frame(x=mean(x$x), y=mean(x$y)))

Видите, plyr умный :)

Обновление 2:

В ответ на ваш комментарий, я считаю, что каст и плавки из пакета измененной формы намного проще для вашей цели.

cast(melt(data),I ~ variable, mean)
0 голосов
/ 05 февраля 2016

Используйте только обобщенную функцию в R.

>d=data.frame(type=as.factor(rep(c("A","B","C"),each=3)),
x=rnorm(9),y=rgamma(9,2,1))
> d
type           x         y
1    A -1.18077326 3.1428680
2    A -0.91930418 4.4606603
3    A  0.88345422 1.0979301
4    B  0.06964133 1.1429911
5    B -1.15380345 2.7609049
6    B  1.13637202 0.6668986
7    C -1.12052765 1.7352306
8    C -1.34803630 2.3099202
9    C -2.23135374 0.7244689
>
> cbind(lm(x~-1+type,data=d)$coef,lm(y~-1+type,data=d)$coef)
         [,1]     [,2]
typeA -0.4055411 2.900486
typeB  0.0174033 1.523598
typeC -1.5666392 1.589873
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...