2011-12-19 3 views
3

J'ai une trame de données avec 3 variables: lieu, heure et valeur (P, T, X). Je veux créer une quatrième variable qui sera la somme cumulative de X. Normalement j'aime faire des calculs de groupement avec sqldf, mais ne peux pas sembler trouver un équivalent pour cumsum. C'est-à-dire:Somme cumulée par groupe dans sqldf?

sqldf("select P,T,X, cumsum(X) as X_CUM from df group by P,T") 

ne fonctionne pas. Est-ce encore possible avec sqldf? J'ai essayé doBy, mais ce n'est pas tout cumsum non plus.

Répondre

7

Mettre en place certaines données de test:

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

et maintenant nous avons trois solutions. D'abord, nous utilisons sqldf, comme demandé, en utilisant la base de données SQLite par défaut. Ensuite, nous le faisons à nouveau avec sqldf mais cette fois avec PostgreSQL en utilisant le driver RPostgreSQL ou RpgSQL. PostgreSQL supporte les fonctions de fenêtrage analytique qui simplifient le SQL. Vous devrez d'abord configurer une base de données PostgreSQL pour cela. Enfin, nous montrons une solution pure R qui utilise uniquement le noyau de 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"' 
) 

(Ceci est également fonctionne avec le pilote RpgSQL PostgreSQL Pour l'utiliser, vous devez avoir installé Java et une base de données PostgreSQL, puis à la place de l'utilisation ci-dessus: 1ibrary(RpgSQL); sqldf(...) où la même chaîne SQL est utilisée cept il devrait y avoir pas de guillemets autour DF.)

3) Plaine R

transform(DF, cumsum = ave(value, p, FUN = cumsum)) 
1

J'espère que je compris ce que vous voulez:

library(plyr) 
ddply(df, .(P,T), summarize, cumsum(X)) 

ce que cela vous aide?

1

Ou, une autre option est 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 
>