簡體   English   中英

使用data.table根據標准使用r對事件進行分組

[英]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 90099010的行組合在一起,或者說所有具有EVENT 1000 ,或任何組合。

我將使用data.table解決方案。 假設以上數據存在於名為dfdata.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_EVENTNEXT_CODE索引,我將其分開以使其更具可讀性。

另外,如果您關心許多不同的組合,則可以按照以下方式進行操作:

dt[, 
   list(count = .N),
   by=c("EVENT", "CODE", "NEXT_EVENT", "NEXT_CODE")] 

可能有多種方法可以使用plyrdplyr進行類似的操作,但我使用的包並不多。


問題更新后

我能夠順利運行所有內容。 我得到了一個結果

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

問題更新后#2

我不確定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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM