[英]Using data.table to group events based on criteria using r
我想使用R根據某些條件對數據進行分組。基本上,我有一個事件列表,我想根據某種活動模式在相鄰行中進行划分。
No. ID DATE_EVENT TIME_EVENT EVENT CODE
102995 018159871 07/08/2014 09:01:57 9008 1111
20398 018159871 07/08/2014 09:01:58 1000 1402
105541 018159871 07/08/2014 09:01:58 9210 1111
63492 018253609 07/08/2014 09:54:26 9008 905
37552 018253609 07/08/2014 09:54:45 9008 1111
9627 018253609 07/08/2014 09:54:48 9210 1111
112700 018253609 07/08/2014 09:54:48 1000 1402
50555 018253609 07/08/2014 09:55:56 1000 1401
63634 018253609 07/08/2014 09:55:56 9210 1111
34551 018330948 07/08/2014 09:21:51 9008 905
47252 018330948 07/08/2014 09:22:15 9008 1111
3975 018330948 07/08/2014 09:22:17 1000 1402
24196 018330948 07/08/2014 09:22:17 9210 1111
111150 018342571 07/08/2014 09:40:08 9008 905
17119 018342571 07/08/2014 09:40:19 9008 1111
18658 018342571 07/08/2014 09:40:21 9210 1111
25654 018342571 07/08/2014 09:40:21 1000 1402
我想對數據進行分組,以便將9008&905排成一行,然后在下一行9008&1111表示開始新的分組。 (如您在上面看到的,當這些代碼出現時,它是在新ID的開頭,但是並非總是如此,這就是為什么這樣做的必要)
在下面提供的幫助下,我目前正在使用以下
dt[, NEXT_EVENT:=c(tail(EVENT, -1), NA)]
dt[, NEXT_CODE:=c(tail(CODE, -1), NA)]
dt[(EVENT=="9008" & CODE=="905") &
(NEXT_EVENT=="9008" & NEXT_CODE=="1111"),
list(count = .N)]
這給了我兩個新列,每個新列中分別包含以下EVENT and
CODE`。
在查看了我的需求之后,我真正需要的是能夠基於EVENTS
的集合(或集合的組合)將行分組在一起。 例如,我希望能夠將所有具有9008
9009
或9010
的行組合在一起,或者說所有具有EVENT
1000
,或任何組合。
我將使用data.table
解決方案。 假設以上數據存在於名為df
的data.frame
:
dt <- data.table(df)
# dt[<filter>, <do something>, by=<group>]
dt[, NEXT_EVENT:=c(tail(EVENT, -1), NA)]
dt[, NEXT_CODE:=c(tail(CODE, -1), NA)]
dt[(EVENT=="9008" & CODE=="905") &
(NEXT_EVENT=="9008" & NEXT_CODE=="1111"),
list(count = .N)] # replace this with whatever you want to do with the data
您可以直接在主語句中進行NEXT_EVENT
和NEXT_CODE
索引,我將其分開以使其更具可讀性。
另外,如果您關心許多不同的組合,則可以按照以下方式進行操作:
dt[,
list(count = .N),
by=c("EVENT", "CODE", "NEXT_EVENT", "NEXT_CODE")]
可能有多種方法可以使用plyr
或dplyr
進行類似的操作,但我使用的包並不多。
我能夠順利運行所有內容。 我得到了一個結果
dt[(EVENT=="9008" & CODE=="905") &
(NEXT_EVENT=="9008" & NEXT_CODE=="1111"),
list(count = .N)]
count
1: 3
加載時我刪除了逗號,但是將EVENT和CODE轉換為字符列。 我希望你能得到
count
1: 0
因為您(我認為)將“ 9,008”與“ 9008”(均為字符串)進行比較。
作為健全性檢查,這是我使用的測試數據data.table
外觀(在執行最后一個打印結果的調用之前)
> dt
No ID DATE_EVENT TIME_EVENT EVENT CODE NEXT_EVENT NEXT_CODE
1: 102995 18159871 07/08/2014 09:01:57 9008 1111 1000 1402
2: 20398 18159871 07/08/2014 09:01:58 1000 1402 9210 1111
3: 105541 18159871 07/08/2014 09:01:58 9210 1111 9008 905
4: 63492 18253609 07/08/2014 09:54:26 9008 905 9008 1111
5: 37552 18253609 07/08/2014 09:54:45 9008 1111 9210 1111
6: 9627 18253609 07/08/2014 09:54:48 9210 1111 1000 1402
7: 112700 18253609 07/08/2014 09:54:48 1000 1402 1000 1401
8: 50555 18253609 07/08/2014 09:55:56 1000 1401 9210 1111
9: 63634 18253609 07/08/2014 09:55:56 9210 1111 9008 905
10: 34551 18330948 07/08/2014 09:21:51 9008 905 9008 1111
11: 47252 18330948 07/08/2014 09:22:15 9008 1111 1000 1402
12: 3975 18330948 07/08/2014 09:22:17 1000 1402 9210 1111
13: 24196 18330948 07/08/2014 09:22:17 9210 1111 9008 905
14: 111150 18342571 07/08/2014 09:40:08 9008 905 9008 1111
15: 17119 18342571 07/08/2014 09:40:19 9008 1111 9210 1111
16: 18658 18342571 07/08/2014 09:40:21 9210 1111 1000 1402
17: 25654 18342571 07/08/2014 09:40:21 1000 1402 NA NA
我不確定data.table
是為您的新需求而設計的。 您可以使用下面的代碼使其正常工作,但它並不十分優雅。
dt[,SEQUENCE:=1:.N]
dt[EVENT==9008 & CODE==905 &
NEXT_EVENT==9008 & NEXT_CODE==1111,
GRP_ID:=1:.N]
if (is.na(dt[1, GRP_ID]))
dt[1, GRP_ID:=0]
grps <- dt[!is.na(GRP_ID), unique(GRP_ID)]
for (grp in grps) {
dt[SEQUENCE>max(SEQUENCE[!is.na(GRP_ID) & GRP_ID==grp]) &
SEQUENCE<min(SEQUENCE[!is.na(GRP_ID) & GRP_ID==grp+1]),
GRP_ID:=grp]
}
當第4組(不存在)被調用時, min
將發出警告,但不會破壞任何內容。 就像我說的那樣,這是一個非常丑陋的解決方案。 也許其他人有更好的主意。
不確定預期的結果:使用dplyr
library(dplyr)
df %>%
mutate_each(funs(lead), NEXT_EVENT=EVENT, NEXT_CODE=CODE) %>%
group_by(EVENT, CODE, NEXT_EVENT, NEXT_CODE) %>%
tally()
# EVENT CODE NEXT_EVENT NEXT_CODE n
#1 1,000 1401 9,210 1111 1
#2 1,000 1402 1,000 1401 1
#3 1,000 1402 9,210 1111 2
#4 1,000 1402 NA NA 1
#5 9,008 905 9,008 1111 3
#6 9,008 1111 1,000 1402 2
#7 9,008 1111 9,210 1111 2
#8 9,210 1111 1,000 1402 2
#9 9,210 1111 9,008 905 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.