首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ddply的cumsum

使用ddply的cumsum
EN

Stack Overflow用户
提问于 2013-02-21 18:11:33
回答 3查看 5.1K关注 0票数 12

我需要在ddply或aggregate级别中使用group by,如果这样更容易的话。我真的不确定该怎么做,因为我需要使用cumsum作为我的聚合函数。下面是我的数据:

代码语言:javascript
复制
level1      level2  hour     product 
A           tea     0          7
A           tea     1          2
A           tea     2          9
A           coffee  17         7
A           coffee  18         2
A           coffee  20         4
B           coffee  0          2
B           coffee  1          3
B           coffee  2          4
B           tea     21         3
B           tea     22         1

预期输出:

代码语言:javascript
复制
A     tea     0   7
A     tea     1   9
A     tea     2   18
A     coffee  17  7
A     coffee  18  9
A     coffee  20  13
B     coffee  0   2
B     coffee  1   5
B     coffee  2   9
B     tea     21  3
B     tea     22  4

我试着用

代码语言:javascript
复制
ddply(dd,c("level1","level2","hour"),summarise,cumsum(product))

但这并不是总和,我认为这是因为小时列用于group by,并被它拆分..我认为..我不确定我是否完全理解aggregate是如何工作的。有没有什么方法可以使用aggregate或ddply获得所需的输出?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-21 18:21:31

这是一个使用avewithin的base R解决方案

代码语言:javascript
复制
within(mydf, {
  cumsumProduct <- ave(product, level1, level2, FUN = cumsum)
})
#    level1 level2 hour product cumsumProduct
# 1       A    tea    0       7             7
# 2       A    tea    1       2             9
# 3       A    tea    2       9            18
# 4       A coffee   17       7             7
# 5       A coffee   18       2             9
# 6       A coffee   20       4            13
# 7       B coffee    0       2             2
# 8       B coffee    1       3             5
# 9       B coffee    2       4             9
# 10      B    tea   21       3             3
# 11      B    tea   22       1             4

当然,如果您想删除现有的product列,您可以将命令更改为以下内容,以覆盖当前的"product“列:

代码语言:javascript
复制
within(mydf, {
  product <- ave(product, level1, level2, FUN = cumsum)
})

您当前的方法不起作用,部分原因是您已将“小时”作为分组变量之一。换句话说,它将"A + tea + 0“的组合视为不同于"A + tea + 1”的组合,但从您期望的输出来看,您似乎简单地希望"A + tea“的组合成为组。

aggregate不会像您预期的那样工作,因为它会将所有内容压缩到一个data.frame中,其行数与"level1“和"level2”的唯一组合的行数相同,在本例中为4行。聚合列将是一个list。这些值是正确的,但用处不大。

下面是aggregate及其输出:

代码语言:javascript
复制
> aggregate(product ~ level1 + level2, mydf, cumsum)
  level1 level2  product
1      A coffee 7, 9, 13
2      B coffee  2, 5, 9
3      A    tea 7, 9, 18
4      B    tea     3, 4
票数 16
EN

Stack Overflow用户

发布于 2013-02-21 18:19:42

您应该使用transform而不是summarise

代码语言:javascript
复制
# you should probably order your `level2` first
dd$level2 <- factor(dd$level2, levels=c("tea", "coffee"))
# and transform using level1 and level2 alone, not hour
# if you use hour, the groups will be for each row
ddply(dd, .(level1, level2), transform, product=cumsum(product))

#    level1 level2 hour product
# 1       A    tea    0       7
# 2       A    tea    1       9
# 3       A    tea    2      18
# 4       A coffee   17       7
# 5       A coffee   18       9
# 6       A coffee   20      13
# 7       B    tea   21       3
# 8       B    tea   22       4
# 9       B coffee    0       2
# 10      B coffee    1       5
# 11      B coffee    2       9
票数 7
EN

Stack Overflow用户

发布于 2022-02-24 17:01:24

现在提到这一点的人们可能希望避免使用plyr::ddply。这是一个dplyr解决方案。

代码语言:javascript
复制
library(dplyr)
output <- dd %>%
  group_by(level1, level2) %>%
  mutate(product_sum = cumsum(product)) %>%
  ungroup()
output

请注意,product_sum是新列的命名位置。您可以改用product。然后,原始产品列将被覆盖,因为原始问题可能更喜欢这样做,而不是在输出中同时包含两个列。

数据:

代码语言:javascript
复制
level1 <- c(rep("A",6), rep("B",5))
level2 <- c(rep("tea",3), rep("coffee",6), rep("tea",2))
hour <- c(0,1,2,17,18,20,0,1,2,21,22)
product <- c(7,2,9,7,2,4,2,3,4,3,1)

dd <- data.frame(level1, level2, hour, product)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14999556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档