找到组的最大值和总和,并插入R中的相关行

时间:2013-02-02 12:43:35

标签: r plyr

我有一个示例数据框sample.data,如下所示:

x   y   z
1   0   1
1   0   1
1   0   1
1   0   1
1   0   2
1   0   2
1   0   2
1   0   2
1   0   2
0   1   2

我需要找到每个z类别的x和y的最大值和总和(z类似于1,2,... 600)。我使用plyr的ddply:

library(plyr)
z.group<-ddply (sample.data,.(z),summarize,max_x=max(x), max_y=max(y), sum_x=sum(x), sum_y=sum(y))

z.group 
 z   max_x  max_y  sum_x    sum_y
  1    1    0   4   0
  2    1    1   5   1

现在,我需要在相关行下插入这些sum_x, sum_y, max_x, and max_y作为sample.data的列。例如,if max_x is 1 for z=1, then I insert max_x is 1 for all rows with z=1。预期的输出是

x   y   z   max_x  max_y    sum_x  sum_y
1   0   1   1   0   4   0
1   0   1   1   0   4   0
1   0   1   1   0   4   0
1   0   1   1   0   4   0
1   0   2   1   1   5   1
1   0   2   1   1   5   1
1   0   2   1   1   5   1
1   0   2   1   1   5   1
1   0   2   1   1   5   1
0   1   2   1   1   5   1

我想知道如何获得预期的输出?

2 个答案:

答案 0 :(得分:4)

您可以使用transform

直接一步完成
.group<-ddply (sample.data,.(z),transform,max_x=max(x), max_y=max(y), sum_x=sum(x), sum_y=sum(y))
> z.group
   x y z max_x max_y sum_x sum_y
1  1 0 1     1     0     4     0
2  1 0 1     1     0     4     0
3  1 0 1     1     0     4     0
4  1 0 1     1     0     4     0
5  1 0 2     1     1     5     1
6  1 0 2     1     1     5     1
7  1 0 2     1     1     5     1
8  1 0 2     1     1     5     1
9  1 0 2     1     1     5     1
10 0 1 2     1     1     5     1

答案 1 :(得分:3)

我认为您可以使用merge执行此操作:

merge(sample.data, z.group, by="z")

#    z x y max_x max_y sum_x sum_y
# 1  1 1 0     1     0     4     0
# 2  1 1 0     1     0     4     0
# 3  1 1 0     1     0     4     0
# 4  1 1 0     1     0     4     0
# 5  2 1 0     1     1     5     1
# 6  2 1 0     1     1     5     1
# 7  2 1 0     1     1     5     1
# 8  2 1 0     1     1     5     1
# 9  2 1 0     1     1     5     1
# 10 2 0 1     1     1     5     1

data.table替代方案:

require(data.table)
dt <- data.table(sample.data, key="z")
dt[, list(x=x, y=y, max_x=max(x), max_y=max(y), sum_x=sum(x), sum_y=sum(y)), by=z]

更好/更短的解决方案(正如@agstudy建议的那样,应该是可能的):

dt[, `:=`(max_x=max(x), max_y=max(y), sum_x=sum(x), sum_y=sum(y)), by=z]