2015-05-12 3 views
0

У меня есть этот фрейм данных (скорректированный с кодом @ Vinterwoo), и я ищу функцию, чтобы получить среднее значение для каждой группы для каждого столбца. Таким образом, среднее значение для группы А в столбцах C1 и C2 и то же самое для группы B и т. Д. Я знаю, как получить среднее значение для каждой группы (например, используя aggregate), но мне нужно, чтобы среднее значение отображалось в каждой строке соответствующей группы (см. Желаемый результат).Среднее значение для каждой группы в столбце, результат в строке

C1 <- c(3,2,4,3,6,7,5) 
C2 <- c(3,7,3,4,5,2,1) 
DF <- data.frame(ID=c("A","C","A","C","E","F","E"),C1=C1,C2=C2) 

ID C1 C2 
A 3 3 
C 2 7 
A 4 3 
C 3 4 
E 6 5 
F 7 2 
E 5 1 

Желаемый результат:

ID C1 C2 avg.C1 avg.C2 
A 3 3 3.5 3.0 
C 2 7 2.5 5.5 
A 4 3 3.5 3.0 
C 3 4 2.5 5.5 
E 6 5 5.5 3.0 
F 7 2 7.0 2.0 
E 5 1 5.5 3.0 

ответ

4

Я хотел бы предложить «data.table "пакет для этого:

sdcols <- names(DF)[-1]  ## A vector of the new columns we want to add 
as.data.table(DF)[, paste(sdcols, "mean", sep = "_") := lapply(.SD, mean), 
        by = ID][] ## you can also be more specific and specify sdcols 
# ID C1 C2 C1_mean C2_mean 
# 1: A 3 3  3.5  3.0 
# 2: C 2 7  2.5  5.5 
# 3: A 4 3  3.5  3.0 
# 4: C 3 4  2.5  5.5 
# 5: E 6 5  5.5  3.0 
# 6: F 7 2  7.0  2.0 
# 7: E 5 1  5.5  3.0 

Как указано в комментировал коде, вы можете указать, какие столбцы действовать по использованию .SDcols аргумент:

sdcols <- names(DF)[-1] 
as.data.table(DF)[, paste(sdcols, "mean", sep = "_") := lapply(.SD, mean), 
        by = ID, .SDcols = sdcols][] 
2

Try:

library(dplyr) 
DF %>% group_by(ID) %>% mutate(avg.C1 = mean(C1), avg.C2 = mean(C2)) 

Что дает:

#Source: local data frame [7 x 5] 
#Groups: ID 
# 
# ID C1 C2 avg.C1 avg.C2 
#1 A 3 3 3.5 3.0 
#2 C 2 7 2.5 5.5 
#3 A 4 3 3.5 3.0 
#4 C 3 4 2.5 5.5 
#5 E 6 5 5.5 3.0 
#6 F 7 2 7.0 2.0 
#7 E 5 1 5.5 3.0 
0

Если вы собираетесь создать новый столбец с помощью base вы можете просто вычислить требуемые значения d назначьте их столбцам. Для того, чтобы посчитать, что вы берете среднее каждого C, который имеет идентификатор равный его собственному:

DF$avg.C1 <- sapply(1:nrow(DF), function(i) mean(DF$C1[DF$ID==DF$ID[i]])) 
DF$avg.C2 <- sapply(1:nrow(DF), function(i) mean(DF$C2[DF$ID==DF$ID[i]])) 
1

Вы можете использовать агрегат и объединить в следующие

DF2=aggregate(cbind(C1, C2) ~ ID , data= DF , FUN= mean) 
DF_Wanted= merge(DF, DF2, by=c("ID"), all=TRUE) 
0

Есть некоторые хорошие ответы уже размещены, но я удивлен, что никто не упомянул ave(), который в основном предназначен для точной цели; он даже запускает mean() без каких-либо подтасовки!

cbind(DF,avg.C1=ave(DF$C1,DF$ID),avg.C2=ave(DF$C2,DF$ID)); 
## ID C1 C2 avg.C1 avg.C2 
## 1 A 3 3 3.5 3.0 
## 2 C 2 7 2.5 5.5 
## 3 A 4 3 3.5 3.0 
## 4 C 3 4 2.5 5.5 
## 5 E 6 5 5.5 3.0 
## 6 F 7 2 7.0 2.0 
## 7 E 5 1 5.5 3.0 
Смежные вопросы