如果更容易,我需要在ddply或者聚合中使用group by。我不确定如何做到这一点,因为我需要使用cumsum作为我的聚合函数。这就是我的数据:
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
预期产出:
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
我尝试使用
ddply(dd,c("level1","level2","hour"),summarise,cumsum(product))
但是这并不总结我认为是因为小时栏被用于分组而被它拆分......我想..我不确定我是否完全理解聚合如何在这里工作。有什么方法可以使用aggregate或ddply获得所需的输出吗?
答案 0 :(得分:16)
以下是使用ave
和within
的基础R的解决方案:
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
当然,如果您想删除现有的产品列,可以将命令更改为以下内容以覆盖当前的“产品”列:
within(mydf, {
product <- ave(product, level1, level2, FUN = cumsum)
})
您当前的方法无法正常工作,因为您已将“小时”作为您的分组变量之一。换句话说,它看到“A +茶+ 0”的组合与“A +茶+ 1”不同,但是根据您想要的输出,您似乎只想要“A +茶”的组合是基。
aggregate
无法按预期工作,因为它会将所有内容压缩为data.frame
,其行数与“level1”和“level2”的唯一组合数相同,在这种情况下,4行。汇总列为list
。这些值是正确的,但它没那么有用。
这是aggregate
及其输出:
> 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
答案 1 :(得分:7)
您应该使用transform
代替summarise
:
# 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