Вычислить кумулятивную сумму в каждом идентификаторе (группе)
С фреймом данных:
df <- data.frame(id = rep(1:3, each = 5)
, hour = rep(1:5, 3)
, value = sample(1:15))
Я хочу добавить столбец суммарной суммы, который соответствует 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
Как я могу сделать это эффективно? Спасибо!
Ответы
Ответ 1
df$csum <- ave(df$value, df$id, FUN=cumsum)
ave
- это функция перехода, если вы хотите, чтобы вектор по группам был равным по длине существующему вектору, и его можно вычислить только из этих субвекторов. Если вам нужна обработка по группам, основанная на нескольких "параллельных" значениях, базовая стратегия - do.call(rbind, by(dfrm, grp, FUN))
.
Ответ 2
Чтобы добавить к альтернативам, синтаксис data.table
хорош:
library(data.table)
DT <- data.table(df, key = "id")
DT[, csum := cumsum(value), by = key(DT)]
Или, более компактно:
library(data.table)
setDT(df)[, csum := cumsum(value), id][]
Вышеуказанное:
- Преобразуйте
data.frame
в data.table
по ссылке
- Рассчитать совокупную сумму значения, сгруппированную по id и присвоить ее ссылкой
- Распечатайте (последний
[]
) результат всей операции
"df" теперь будет data.table
с столбцом "csum".
Ответ 3
Использование dplyr ::
require(dplyr)
df %>% group_by(id) %>% mutate(csum = cumsum(value))
Ответ 4
Использование библиотеки plyr
.
library(plyr)
ddply(df,.(id),transform,csum=cumsum(value))
Ответ 5
Просто обновление, у вас может быть пакет, который загрузил plyr
.
Явная ссылка на dplyr
также исправит это:
df %>% group_by(id) %>% dplyr::mutate(csum = cumsum(value))