我需要在ddply或aggregate级别中使用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))但这并不是总和,我认为这是因为小时列用于group by,并被它拆分..我认为..我不确定我是否完全理解aggregate是如何工作的。有没有什么方法可以使用aggregate或ddply获得所需的输出?
发布于 2013-02-21 18:21:31
这是一个使用ave和within的base 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当然,如果您想删除现有的product列,您可以将命令更改为以下内容,以覆盖当前的"product“列:
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及其输出:
> 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发布于 2013-02-21 18:19:42
您应该使用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发布于 2022-02-24 17:01:24
现在提到这一点的人们可能希望避免使用plyr::ddply。这是一个dplyr解决方案。
library(dplyr)
output <- dd %>%
group_by(level1, level2) %>%
mutate(product_sum = cumsum(product)) %>%
ungroup()
output请注意,product_sum是新列的命名位置。您可以改用product。然后,原始产品列将被覆盖,因为原始问题可能更喜欢这样做,而不是在输出中同时包含两个列。
数据:
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)https://stackoverflow.com/questions/14999556
复制相似问题