web-dev-qa-db-ja.com

各ID(グループ)内の累積合計を計算します

データフレームあり:

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

これを効率的に行うにはどうすればよいですか?ありがとう!

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

aveは、既存のベクトルと同じ長さのグループごとのベクトルが必要であり、それらのサブベクトルのみから計算できる場合の「移動」関数です。複数の「並列」値に基づくグループごとの処理が必要な場合、基本的な戦略はdo.call(rbind, by(dfrm, grp, FUN))です。

37
42-

代替案に追加するには、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.framedata.tableに変換する
  • IDでグループ化された値の累積合計を計算し、参照によって割り当てます
  • 操作全体の結果を出力する(最後の[]がある)

「df」は「csum」列を持つdata.tableになります。

20

Dplyr ::の使用

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

ライブラリplyrを使用します。

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