我有一个包含3个变量的数据框:地点,时间和值(P,T,X)。我想创建一个第四个变量,它将是X的累积和。通常我喜欢用sqldf
进行分组计算,但似乎找不到cumsum
的等价物。那就是:
sqldf("select P,T,X, cumsum(X) as X_CUM from df group by P,T")
不起作用。 sqldf
是否可以实现这一点?我尝试了doBy
,但并非所有cumsum
都是。
答案 0 :(得分:8)
设置一些测试数据:
DF <- data.frame(t = 1:4, p = rep(1:3, each = 4), value = 1:12)
现在我们有三个解决方案。首先,我们使用默认的SQLite数据库按要求使用sqldf。接下来我们再次使用sqldf,但这次使用PostgreSQL使用RPostgreSQL或RpgSQL驱动程序。 PostgreSQL支持简化SQL的分析窗口函数。您将需要首先设置PostgreSQL数据库来执行该操作。最后,我们展示了一个纯R解决方案,它只使用R的核心。
1)sqldf / RSQLite
library(sqldf)
sqldf("select a.*, sum(b.value) as cumsum
from DF a join DF b
using (p)
where a.t >= b.t
group by p, a.t"
)
2)sqldf / RPostgreSQL
library(RPostgreSQL)
library(sqldf)
sqldf('select *,
sum(value) over (partition by p order by t) as cumsum
from "DF"'
)
(这也适用于RpgSQL PostgreSQL驱动程序。要使用它,您必须安装Java并设置PostgreSQL数据库,然后代替上述使用:1ibrary(RpgSQL); sqldf(...)
其中使用相同的SQL字符串,除此之外应该在DF
附近没有引号。)
3)平原R
transform(DF, cumsum = ave(value, p, FUN = cumsum))
答案 1 :(得分:1)
我希望我理解你想要的东西:
library(plyr)
ddply(df, .(P,T), summarize, cumsum(X))
这对你有帮助吗?
答案 2 :(得分:1)
或者,另一个选项是data.table。
> library(data.table)
> DT = data.table(place = 1:4, time = rep(1:3, each = 4), value = 1:3)
> setkey(DT,place,time) # order by place and time
> DT
place time value
[1,] 1 1 1
[2,] 1 2 2
[3,] 1 3 3
[4,] 2 1 2
[5,] 2 2 3
[6,] 2 3 1
[7,] 3 1 3
[8,] 3 2 1
[9,] 3 3 2
[10,] 4 1 1
[11,] 4 2 2
[12,] 4 3 3
> DT[,list(time,value,cumsum(value)),by=place]
place time value V3
[1,] 1 1 1 1
[2,] 1 2 2 3
[3,] 1 3 3 6
[4,] 2 1 2 2
[5,] 2 2 3 5
[6,] 2 3 1 6
[7,] 3 1 3 3
[8,] 3 2 1 4
[9,] 3 3 2 6
[10,] 4 1 1 1
[11,] 4 2 2 3
[12,] 4 3 3 6
>