2016-05-12 19 views
4
Group  Start   End    Days 
A   5/12/2015  5/14/2015  3 
A   5/12/2015  5/14/2015  3 
B   1/1/2015   1/3/2015  3 
B   1/1/2015   1/3/2015  3 
H   1/8/2015   1/9/2015  2 
H   1/8/2015   1/9/2015  2 
H   1/13/2015  1/15/2015  3 
H   1/7/2015   1/17/2015  3 
H   1/12/2015  1/22/2015  7 

私は上記のデータセットのサンプルを添付しました。私はRの各グループのユニークな日の数を数えようとしています。いくつかの観測ではAとBのかなり単純なものです。しかし、日付範囲のギャップだけでなく日数の重複もあるグループがあります。例:日付範囲に重複とギャップがあるユニークな日をカウントする

Rの各グループの一意の日数(重複がなく、ギャップを考慮しない)を要約できますか?すなわち、AとBはそれぞれ3日を返し、Hは11日を返します。

Group Count 
A  3 
B  3 
H  16 

私の最高の推測では、しかし、私はすべてのソリューションのまわりで私の頭をラップすることができていない、dplyrを使用して機能をまとめることになります。 ご協力いただければ幸いです! (あなたのStartEnd列が日付形式であると仮定した場合)は、グループによってユニーク日間カウントしたい場合、私はどうしたらあなたに

+1

うまく表現の質問を。ケース3の合計が11になるように詳しく説明できますか – OdeToMyFiddle

+0

私のお詫びには、以下に述べるように正しい数が16だったはずです! –

答えて

5

dplyrソリューションです:

library(dplyr) 

df %>% 
    group_by(Group,rn = row_number()) %>% 
    do(data.frame(.,Date = seq(as.Date(.$Start,format = '%m/%d/%Y'), 
           as.Date(.$End,format = '%m/%d/%Y'), 
           '1 day'))) %>% 
    group_by(Group) %>% 
    summarise(numDays = n_distinct(Date)) 

アイデアは開始から終了までの日付の配列を含む新しい列を作成することで、その後、各グループの固有の観測の長さを数えます。

これは与える:

Group numDays 
    (fctr) (int) 
1  A  3 
2  B  3 
3  H  16 
+0

それはうまくいった!これは私がここで説明することにしたまで数日間私を悩ませていました。皆さんは素晴らしいです! –

+0

'length'と' unique'コンボの代わりに 'n_distinct'を使うこともできます:' numDays = n_distinct(Date) ' – Jaap

+0

@ProcrastinatusMaximus!私はn_distinctを使う答えを更新しました。 – shreyasgm

4

ありがとう:

library(data.table) 
setDT(mydf)[, .(dates = seq.Date(Start,End,'day')) , by = .(Group,1:nrow(mydf)) 
      ][, .(count = uniqueN(dates)), by = Group][] 

与える:

Group count 
1:  A  3 
2:  B  3 
3:  H 16 

説明:各行に対して、StartおよびEndの日付を持つ日付列を作成します。その後、uniqueN機能で一意の日数をカウントします。これは、これが考慮に入れられているので、私の古い答え(下記参照)よりも優れています。

これは、説明した望ましい出力と比較して、Hグループの数値が高くなります。ただし、データをよく見れば、正しい番号は16であることがわかります。


ベースRと同様のソリューション:類似した結果得られ

l <- mapply(seq.Date, mydf$Start, mydf$End, 1) 
df2 <- data.frame(group = rep(mydf$Group,sapply(l,length)), 
        dates = unlist(l)) 
aggregate(dates ~ group, df2, function(x) length(unique(x))) 

:あなたは日付形式でdf2dates列をしたい場合

group dates 
1  A  3 
2  B  3 
3  H 16 

を、代わりにas.Date(unlist(l), origin = '1970-01-01')を使用unlist(l)です。


使用するデータ:ここ

mydf <- structure(list(Group = c("A", "A", "B", "B", "H", "H", "H", "H", "H"), 
         Start = structure(c(16567, 16567, 16436, 16436, 16443, 16443, 16448, 16442, 16447), class = "Date"), 
         End = structure(c(16569, 16569, 16438, 16438, 16444, 16444, 16450, 16452, 16457), class = "Date"), 
         Days = c(3L, 3L, 3L, 3L, 2L, 2L, 3L, 3L, 7L)), 
        .Names = c("Group", "Start", "End", "Days"), row.names = c(NA, -9L), class = "data.frame") 
+0

徹底的な説明をいただきありがとうございます!ほんとうにありがとう! –

+0

@MichaelLuu私は基本的なRのアプローチも含めました。 – Jaap

関連する問題