我想将列附加到具有累积函数结果的数据框。我可以使用unsplit
/ split
完成此操作,就像这样
> set.seed(3)
> d <- data.frame(type=sample(c('a','b'),10,replace=TRUE), val=rnorm(10))
> d
type val
1 a 0.03012394
2 b 0.08541773
3 a 1.11661021
4 a -1.21885742
5 b 1.26736872
6 b -0.74478160
7 a -1.13121857
8 a -0.71635849
9 b 0.25265237
10 b 0.15204571
所以我使用split
/ lapply
/ unsplit
来获得我想要的结果
> d$sum <- unsplit(lapply(split(d,d$type), function(x) { cumsum(x$val)}), d$type)
> d
type val sum
1 a 0.03012394 0.03012394
2 b 0.08541773 0.08541773
3 a 1.11661021 1.14673416
4 a -1.21885742 -0.07212326
5 b 1.26736872 1.35278645
6 b -0.74478160 0.60800486
7 a -1.13121857 -1.20334183
8 a -0.71635849 -1.91970032
9 b 0.25265237 0.86065723
10 b 0.15204571 1.01270293
这是理想的结果。但在这种情况下,我真的想使用plyr
的简化语法。所以我试过
> d$sum2 <- unsplit(dlply(d, .(type), summarise, cumsum(val)), d$type)
Error in `row.names<-.data.frame`(`*tmp*`, value = value) :
duplicate 'row.names' are not allowed
In addition: Warning message:
non-unique values when setting 'row.names': '1', '2', '3', '4', '5'
dlply
和lapply
/ split
的输出几乎相同,只是dlply
有一些额外的垃圾,我认为unsplit
会忽略,dlply
输出已重新索引row.names。我认为后者就是投诉。
另请注意,我知道我可以使用ddply
/ transform
> ddply(d, .(type), transform, sum2=cumsum(val))
type val sum sum2
1 a 0.03012394 0.03012394 0.03012394
2 a 1.11661021 1.14673416 1.14673416
3 a -1.21885742 -0.07212326 -0.07212326
4 a -1.13121857 -1.20334183 -1.20334183
5 a -0.71635849 -1.91970032 -1.91970032
6 b 0.08541773 0.08541773 0.08541773
7 b 1.26736872 1.35278645 1.35278645
8 b -0.74478160 0.60800486 0.60800486
9 b 0.25265237 0.86065723 0.86065723
10 b 0.15204571 1.01270293 1.01270293
这在我的情况下不起作用,因为正如您所看到的,这会产生重新排列行不正常的副作用。如果ddply
有一些不会重新排列行的参数,那么这对我的目的来说是完美的。
答案 0 :(得分:3)
也许您可以试试dplyr
?与ddply
相反,它保留原始顺序。
library(dplyr)
d %.%
group_by(type) %.%
mutate(sum = cumsum(val))
# Source: local data frame [10 x 3]
# Groups: type
#
# type val sum
# 1 a 0.03012394 0.03012394
# 2 b 0.08541773 0.08541773
# 3 a 1.11661021 1.14673416
# 4 a -1.21885742 -0.07212326
# 5 b 1.26736872 1.35278645
# 6 b -0.74478160 0.60800486
# 7 a -1.13121857 -1.20334183
# 8 a -0.71635849 -1.91970032
# 9 b 0.25265237 0.86065723
# 10 b 0.15204571 1.01270293
答案 1 :(得分:1)
为什么不使用ave
?
d$sum <- # absolutely terrible name for a variable
ave( d$val, d$type, FUN=cumsum)
lapply( split(d, d$type) , func)
- 方法对于一次只对一个向量进行操作的函数来说是过度的。