使用组均值和/或匹配不同长度的数据帧进行计算

时间:2014-07-29 16:25:10

标签: r plyr

我正在尝试在此数据框(df)中添加列B,其中值基于A的组平均值(每个不同ID的平均值)。例如,对于每个T,B将是10 *平均值(A)。

ID  T   A
1   1   1.1
1   10  1.3
1   100 1.5
2   1   2.6
2   10  1.9
2   100 2.2

一个想法可能是为每个组计算A的平均值(ID == 1和ID == 2),将其存储在新对象中,然后使用ID来匹配对象......

使用plyr,我们可以得到A的组方式:

A.mean <- ddply(df, "ID", summarise, mean(A))

但我仍在寻找匹配df和A.mean,我不知道如何处理他们不同的长度...

我很高兴;-)获得

ID  T   A   A.mean
1   1   1.1 1.3
1   10  1.3 1.3
1   100 1.5 1.3
2   1   2.6 2.233333333
2   10  1.9 2.233333333
2   100 2.2 2.233333333

然后做df $ B&lt; - df $ A.mean * 10

2 个答案:

答案 0 :(得分:2)

使用ave

  within(df, {A.mean=ave(A, ID, FUN=mean); B.mean=10*A.mean})[,c(1:3,5,4)]
 #  ID   T   A   A.mean   B.mean
 #1  1   1 1.1 1.300000 13.00000
 #2  1  10 1.3 1.300000 13.00000
 #3  1 100 1.5 1.300000 13.00000
 #4  2   1 2.6 2.233333 22.33333
 #5  2  10 1.9 2.233333 22.33333
 #6  2 100 2.2 2.233333 22.33333

或者

 library(data.table)
 setDT(df)[,A.mean:=mean(A), by="ID"][,B.mean:=10*A.mean]
 df

data.table的另一种方式:

setDT(df)[, c("A.mean", "B.mean") := { m = mean(A); list(m, m*10) }, by=ID]

答案 1 :(得分:1)

使用transform代替summarise

ddply(df, .(ID), transform, A.mean = mean(A), B = mean(A) * 10)
#  ID   T   A   A.mean        B
#1  1   1 1.1 1.300000 13.00000
#2  1  10 1.3 1.300000 13.00000
#3  1 100 1.5 1.300000 13.00000
#4  2   1 2.6 2.233333 22.33333
#5  2  10 1.9 2.233333 22.33333
#6  2 100 2.2 2.233333 22.33333

或者您可以在ddply来电之后添加B列。

请注意,summarise将数据分解为每组1行(在这种情况下为ID),而transform保留现有结构,在这种情况下,只需添加相同的新列长度。

以下是等效的dplyr代码(如果您使用的是大型数据集,代码会更快):

library(dplyr)

df <- df %>%
  group_by(ID) %>%
  dplyr::mutate(A.mean = mean(A),
                B = A.mean*10)