web-dev-qa-db-fra.com

Calculer la somme cumulée au sein de chaque ID (groupe)

Avec trame de données:

df <- data.frame(id = rep(1:3, each = 5)
                 , hour = rep(1:5, 3)
                 , value = sample(1:15))

Je veux ajouter une colonne de somme cumulée qui correspond à id:

df
   id hour value csum
1   1    1     7    7
2   1    2     9   16
3   1    3    15   31
4   1    4    11   42
5   1    5    14   56
6   2    1    10   10
7   2    2     2   12
8   2    3     5   17
9   2    4     6   23
10  2    5     4   27
11  3    1     1    1
12  3    2    13   14
13  3    3     8   22
14  3    4     3   25
15  3    5    12   37

Comment puis-je le faire efficacement? Merci!

35
Rock
df$csum <- ave(df$value, df$id, FUN=cumsum)

ave est la fonction "go-to" si vous voulez un vecteur par groupe de longueur égale à un vecteur existant et il peut être calculé uniquement à partir de ces sous-vecteurs. Si vous avez besoin d'un traitement par groupe basé sur plusieurs valeurs "parallèles", la stratégie de base est do.call(rbind, by(dfrm, grp, FUN)).

37
42-

Pour ajouter aux alternatives, la syntaxe de data.table Est Nice:

library(data.table)
DT <- data.table(df, key = "id")
DT[, csum := cumsum(value), by = key(DT)]

Ou, de manière plus compacte:

library(data.table)
setDT(df)[, csum := cumsum(value), id][]

Ce qui précède:

  • Convertissez le data.frame En un data.table Par référence
  • Calculez la somme cumulée de la valeur regroupée par id et affectez-la par référence
  • Imprimez (le dernier [] Là-bas) le résultat de toute l'opération

"df" sera désormais un data.table avec une colonne "csum".

20

Utilisation de dplyr ::

require(dplyr)
df %>% group_by(id) %>% mutate(csum = cumsum(value))
11
Tjebo

Utilisation de la bibliothèque plyr.

library(plyr)
ddply(df,.(id),transform,csum=cumsum(value))
8
Didzis Elferts