Подтвердить что ты не робот

Вычислить кумулятивную сумму в каждом идентификаторе (группе)

С фреймом данных:

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

Как я могу сделать это эффективно? Спасибо!

4b9b3361

Ответ 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))