sqldf中按组累计的总和?

时间:2011-12-19 09:45:47

标签: r sqldf

我有一个包含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都是。

3 个答案:

答案 0 :(得分:8)

设置一些测试数据:

DF <- data.frame(t = 1:4, p = rep(1:3, each = 4), value = 1:12)

现在我们有三个解决方案。首先,我们使用默认的SQLite数据库按要求使用sqldf。接下来我们再次使用sqldf,但这次使用PostgreSQL使用RPostgreSQLRpgSQL驱动程序。 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
>