2016-09-30 8 views
1

ID、日付、およびイベントを含むデータセットがあります。イベントはバイナリの結果変数です。 IDあたり最大1つのイベントしか存在できません。このイベントの後に0が続きます。イベント後に表示されるすべてのゼロをグループ別に削除したい。私は以下のdplyrを使った解決法を持っていますが、より良い方法があるかどうかを知りたいと思っています。過去のある時点でイベントが発生したことを示す良い方法は何ですか?イベントが発生した後にグループ化されたデータから行を削除する

library(dplyr) 
d <-as.Date("01-05-15", "%d-%m-%y") 
#Starting dataset 
df <- data.frame(ID= c(rep(234,4),rep(235,6), rep(237,5)), 
     date = as.Date(c((d-4):(d-1),(d-1):(d+4),(d+1):(d+5)),origin="1960-10-01"), 
     event = c(0,1,0,0,0,0,0,0,0,0,0,0,0,1,0)) 

#desired result 
df[c(1:2,5:14),] 

#How can Improve this? 
df %>% group_by(ID) %>% 
    mutate(cumulative = lag(cumsum(event), default = 0)) %>% 
    filter(cumulative <1) %>% 
    select(-cumulative) %>% ungroup 

答えて

3

dplyrで試すことができます。 'ID'でグループ化した後、 'event'の要素が0(all(event == 0))または(|)行の順序が 'event'の最初の最大要素のインデックス以下(row_number() <= which.max(event))であるかどうかをチェックしてくださいその論理インデックスはfilterになります。

library(dplyr) 
df %>% 
    group_by(ID) %>% 
    filter(row_number() <= which.max(event)|all(event==0)) 
#  ID  date event 
# <dbl>  <date> <dbl> 
#1 234 2015-04-27  0 
#2 234 2015-04-28  1 
#3 235 2015-04-30  0 
#4 235 2015-05-01  0 
#5 235 2015-05-02  0 
#6 235 2015-05-03  0 
#7 235 2015-05-04  0 
#8 235 2015-05-05  0 
#9 237 2015-05-02  0 
#10 237 2015-05-03  0 
#11 237 2015-05-04  0 
#12 237 2015-05-05  1 

またはビットよりコンパクトなオプションが1に等しく、それはfilter呼び出しで2未満であるか否かをチェックしているeventダブル累積和であろう。

df %>% 
    group_by(ID) %>% 
    filter(cumsum(cumsum(event == 1))<2) 

またはdata.tableを使用して、 'ID' ifall 'イベント' の要素が0でグループ化され、(setDT(df)) 'data.table' に 'data.frame' を変換し、データのサブセット.table(.SD)またはelse 'event'の最初の要素から最初の最大要素までを含む行を持つData.tableをサブセット化します。

library(data.table) 
setDT(df)[, if(all(event==0)) .SD else .SD[seq(which.max(event))], by = ID] 
+1

私はall(event == 0)部分を理解しようとしていました。 –

関連する問題