Met dataframe:
df <- data.frame(id = rep(1:3, each = 5)
, hour = rep(1:5, 3)
, value = sample(1:15))
Ik wil een cumulatieve somkolom toevoegen die overeenkomt met de 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
Hoe kan ik dit efficiënt doen? Bedankt!
Antwoord 1, autoriteit 100%
df$csum <- ave(df$value, df$id, FUN=cumsum)
ave
is de “go-to”-functie als u een per-groepsvector wilt die even lang is als een bestaande vector en deze kan alleen uit die subvectoren worden berekend. Als u verwerking per groep nodig heeft op basis van meerdere “parallelle” waarden, is de basisstrategie do.call(rbind, by(dfrm, grp, FUN))
.
Antwoord 2, autoriteit 45%
Om aan de alternatieven toe te voegen, is de syntaxis van data.table
leuk:
library(data.table)
DT <- data.table(df, key = "id")
DT[, csum := cumsum(value), by = key(DT)]
Of, compacter:
library(data.table)
setDT(df)[, csum := cumsum(value), id][]
Het bovenstaande zal:
- Converteer het
data.frame
naar eendata.table
door middel van referentie - Bereken de cumulatieve som van de waarde gegroepeerd op id en wijs deze toe door middel van referentie
- Print (de laatste
[]
daar) het resultaat van de hele operatie
“df” wordt nu een data.table
met een kolom “csum”.
Antwoord 3, autoriteit 31%
Dplyr gebruiken::
require(dplyr)
df %>% group_by(id) %>% mutate(csum = cumsum(value))
Antwoord 4, autoriteit 15%
Bibliotheek plyr
gebruiken.
library(plyr)
ddply(df,.(id),transform,csum=cumsum(value))