/ /ルックバックウィンドウを使用してdata.tableで簡単な概要を取得する方法-r、data.table

ルックバックウィンドウを使用してdata.tableに簡単な要約を表示する方法 - r、data.table

この質問は、 data.tableでカウントの簡単な要約を取得する方法.

同様に、これはColと呼ばれる列に応じて各IDを要約する機能エンジニアリングの一部です 特定の時間枠で振り返ることにより。同じ前処理がテストセットに適用されます。データセットが大きいため、data.tableベースのソリューションがより好ましい場合があります。

1.ルックバックウィンドウで変数と値をサマライズする

トレーニング入力:

ID   Time        Col   Count
A    2017-06-05   M      1
A    2017-06-02   M      1
A    2017-06-03   M      1
B    2017-06-02   K      1
B    2017-06-01   M      4

振り返って2日間適用すると、次のようになります。

ID   Time          Time-2D   Col   Count
A    2017-06-05   2017-06-03   M      1   #Time-2D by moving time two days back
A    2017-06-02   2017-05-31   M      1
A    2017-06-03   2017-06-01   M      1
B    2017-06-02   2017-05-31   K      1
B    2017-06-01   2017-05-30   M      4

期待される出力(カウント):

ID   Time          Time-2D   Col_M    Col_K
A    2017-06-05   2017-06-03   1      0     #from 2017-06-03 to 2017-06-05, for user A, there are 0 (sum(count)) of K and 1 (sum(count)) of M.
A    2017-06-02   2017-05-31   1      0
A    2017-06-03   2017-06-01   2      0     # 2 is because from 06-01 to 06-03, there is two rows in the first table (A    2017-06-02   M      1; A    2017-06-03   M      1) that the count summarization on M is 2.
B    2017-06-02   2017-05-31   0      1
B    2017-06-01   2017-05-30   4      0

2.比率を計算する

上記の表に基づいて、 期待される出力(比率):

ID   Time          Time-2D   Col_M    Col_K
A    2017-06-05   2017-06-03   1      0     # 1/sum(1+0)
A    2017-06-02   2017-05-31   1      0
A    2017-06-03   2017-06-01   1      0     #2/sum(2+0)
B    2017-06-02   2017-05-31   0      1
B    2017-06-01   2017-05-30   1      0     # 4/sum(4+0)

上記はトレーニングデータの処理用です。テストデータセットの場合、Col_M、Col_Kを介してマッピングする必要がある場合、つまり、Sのような他の値がColに現れる場合、それは無視されます。

回答:

回答№1は1

私はあなたの要求を理解していると思います。たとえば、2番目の観測値に関係なく、観測値の順序を気にするようです Time 最初の観測の前 Time。これはあまり意味がありませんが、これを達成するための非常に効率的なdata.tableソリューションがあります。これは基本的に 非等 参加する ID, Col、 両方 Timeそして 行インデックス(基本的には出現順)。その後、それだけ dcast (前の質問のように)longからwideに変換します。結果は日付順に並べられていますが、 rowindx 変数なので、次を使用して並べ替えることができます setorder。また、これは非常に基本的なものであるため、比率計算を維持します(ヒント- ドン "t ループを使用し、完全にベクトル化された1つのライナーです)

library(data.table) #v1.10.4+

## Read the data
DT <- fread("ID   Time        Col   Count
A    2017-06-05   M      1
A    2017-06-02   M      1
A    2017-06-03   M      1
B    2017-06-02   K      1
B    2017-06-01   M      4")

## Prepare the variables we need for the join
DT[, Time := as.IDate(Time)]
DT[, Time_2D := Time - 2L]
DT[, rowindx := .I]

## Non-equi join, sum `Count` by each join
DT2 <- DT[DT,
sum(Count),
on = .(ID, Col, rowindx <= rowindx, Time <= Time, Time >= Time_2D),
by = .EACHI]

## Fix column names (a known issue)
setnames(DT2, make.unique(names(DT2)))

## Long to wide (You can reorder back using `rowindx` and `setorder` function)
dcast(DT2, ID + Time + Time.1 + rowindx ~ Col, value.var = "V1", fill = 0)
#    ID       Time     Time.1 rowindx K M
# 1:  A 2017-06-02 2017-05-31       2 0 1
# 2:  A 2017-06-03 2017-06-01       3 0 2
# 3:  A 2017-06-05 2017-06-03       1 0 1
# 4:  B 2017-06-01 2017-05-30       5 0 4
# 5:  B 2017-06-02 2017-05-31       4 1 0

回答№2の場合は1

あなたが試すことができます

dt <- fread("ID   Time          Time-2D   Col   Count
A    2017-06-05   2017-06-03   M      1
A    2017-06-02   2017-05-31   M      1
A    2017-06-03   2017-06-01   M      1
B    2017-06-02   2017-05-31   K      1
B    2017-06-01   2017-05-30   M      4")
dt1 <- dcast(dt, ID+Time+`Time-2D`~Col, value.var = c("Count"))
dt1[, K := ifelse(is.na(K), 0, K)]
dt1[, M := ifelse(is.na(M), 0, M)]

ID       Time    Time-2D K M
1:  A 2017-06-02 2017-05-31 0 1
2:  A 2017-06-03 2017-06-01 0 1
3:  A 2017-06-05 2017-06-03 0 1
4:  B 2017-06-01 2017-05-30 0 4
5:  B 2017-06-02 2017-05-31 1 0

dt1[, Col_K := K/(K+M)]
dt1[, Col_M := M/(K+M)]

ID       Time    Time-2D K M Col_K Col_M
1:  A 2017-06-02 2017-05-31 0 1     0     1
2:  A 2017-06-03 2017-06-01 0 1     0     1
3:  A 2017-06-05 2017-06-03 0 1     0     1
4:  B 2017-06-01 2017-05-30 0 4     0     1
5:  B 2017-06-02 2017-05-31 1 0     1     0

たぶん、最後の2行を組み合わせることができます。何かのようなもの

dt1[, `:=`()]