Среднее значение по уровням фактора в R, добавить как новый столбец

У меня есть то, что, как я боюсь, может быть простой проблемой, для которой у меня почти есть решение (действительно, у меня есть решение, но оно неуклюже).

У меня есть кадр данных следующим образом:

name    replicate   value
A   1   0.9
A   2   1
B   1   0.8
B   2   0.81
C   1   0.7
C   2   0.9

Что я хотел бы сделать, так это вычислить среднее значение «значения» по «имени» и добавить результаты в новый столбец следующим образом:

name    replicate   value   meanbyname
A   1   0.9 0.95
A   2   1   0.95
B   1   0.8 0.805
B   2   0.81    0.805
C   1   0.7 0.8
C   2   0.9 0.8

Я могу рассчитать средние значения любым из следующих способов:

a<-aggregate(value~name, data=test, FUN=function(x) c(mean=mean(x),count=length(x)))
b<-aggregate(test$value~test$name, FUN=mean)
c<-tapply(test$value, test$name, mean)

но я не могу легко добавить их во фрейм данных, так как они имеют неправильную длину.

Тогда я мог бы сделать это:

 test$meanbyname<-rep(c, each=2)

Это кажется близким, выдает ошибку, поскольку объект «a» кажется шириной всего в два столбца:

  test$meanbyname<-rep(a$value.mean, each=a$value.count)

Мне нужен способ автоматизации процесса, чтобы он работал, если есть, например, три реплики name=A и только одна реплика name=B. Может ли быть однострочное решение, которое является более универсальным?

Заранее всем спасибо за помощь.


person looble    schedule 20.02.2015    source источник


Ответы (1)


Вы можете использовать ave из base R

 test$meanbyname <- with(test, ave(value, name))

Или, используя mutate из dplyr или := из data.table, можно получить результаты

i.e.

 library(dplyr)
 group_by(test, name) %>% 
               mutate(meanbyname=mean(value))

Or

 library(data.table)
 setDT(test)[, meanbyname:= mean(value), by=name]
person akrun    schedule 20.02.2015