2016-08-23 36 views
1

私はR noobであり、そのIDのタイプ 'B'のイベントの間に発生した各IDのイベントタイプの数を合計するデータセットのサマリーを実行しようとしています。ここではサンプルが説明することである:生成日付に基づくdplyrのグループの条件付き要約

id <- c('1', '1', '1', '2', '2', '2', '3', '3', '3', '3') 
type <- c('A', 'A', 'B', 'A', 'B', 'C', 'A', 'B', 'C', 'B') 
datestamp <- as.Date(c('2016-06-20','2016-07-16','2016-08-14','2016-07-17' 
         ,'2016-07-18','2016-07-19','2016-07-16','2016-07-19' 
         , '2016-07-21','2016-08-20')) 
df <- data.frame(id, type, datestamp) 

:イベント「B」は発生し

> df 
    id type datestamp 
1 1 A 2016-06-20 
2 1 A 2016-07-16 
3 1 B 2016-08-14 
4 2 A 2016-07-17 
5 2 B 2016-07-18 
6 2 C 2016-07-19 
7 3 A 2016-07-16 
8 3 B 2016-07-19 
9 3 C 2016-07-21 
10 3 B 2016-08-20 

いつでも、私はそのBイベントの前に発生した各イベントタイプの数を知りたいです、そのIDの他のBイベントの後に実行されます。

研究に
id type B_instance count 
1 1 A   1  2 
2 2 A   1  1 
3 3 A   1  1 
4 3 C   2  1 

は、この質問は、最も近い来た: 私は何で終わるしたいことは、このようなテーブルがある

df2 <- df %>% 
    group_by(id, type) %>% 
    summarize(count = count(id[which(datestamp < datestamp[type =='B'])])) %>% 
    filter(type != 'B') 
:私はこの仕事をしようとしてきた summarizing a field based on the value of another field in dplyr

しかし、エラーが出て

答えて

0

あなたは0を使用することができます(それが働いた場合でも= 3 idを持つようにも、それは、同じIDで2「B」のイベントを考慮していません)を使用してcumsum(type == "B")を実行して新しいグループ変数B_instanceを作成し、最後のBの後ろにある型やB型自体を除外します。その後、countを使用して、グループでのオカレンスをid,B_instanceおよびtypeでカウントします。

df %>% 
     group_by(id) %>% 
     # create B_instance using cumsum on the type == "B" condition 
     mutate(B_instance = cumsum(type == "B") + 1) %>%  
     # filter out rows with type behind the last B and all B types     
     filter(B_instance < max(B_instance), type != "B") %>% 
     # count the occurrences of type grouped by id and B_instance 
     count(id, type, B_instance) 

# Source: local data frame [4 x 4] 
# Groups: id, type [?] 

#  id type B_instance  n 
# <fctr> <fctr>  <dbl> <int> 
# 1  1  A   1  2 
# 2  2  A   1  1 
# 3  3  A   1  1 
# 4  3  C   2  1 
+0

としてこれは完璧に動作します!好奇心から!ありがとう、なぜそうでない場合は、ゼロからスタートする、インスタンスがカウント一致させるには1? – feyr

+0

ずつ増加する必要があり、その結果は意志CUMSUMありません'1,1,1,2'の代わりに' 0,0,0,1'のようになります。 – Psidom

1

data.tableを使用したオプションです。 'data.frame'を 'data.table'に変換します(setDT(df)、 'id'でグループ化され、maxの位置が 'type'が 'B'で、行インデックス(.I)が見つかった(df[i1])をサブセット化し、 'type'が 'B'で、 'id'、 'type'、 'type'のrleidでグループ化された行を削除すると、 「数」。

library(data.table) 
i1 <- setDT(df)[, .I[seq(max(which(type=="B")))] , by = id]$V1 
df[i1][type!="B"][, .(count = .N), .(id, type, B_instance = rleid(type))] 
# id type B_instance count 
#1: 1 A  1  2 
#2: 2 A  1  1 
#3: 3 A  1  1 
#4: 3 C  2  1 
+1

これはとてもうまく動作します、ありがとうございます。@ Psidom's dplyrソリューションは私にとってもっと直感的です。しかし、私が気づいていないdata.tableを使用する利点はありますか?または単に個人的な好みですか? – feyr

+0

@feyrどちらも良いパッケージです。代入( ':=')を利用したい場合は、どのdata.tableが効率的であるか(これはまだ行われていません)。しかし、この場合、psidomの解決策は私のものと同じくらい、あるいはより優雅になります。 – akrun

関連する問題