2016-05-12 14 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 

Ich habe oben ein Beispiel meines Dataset angefügt. Ich versuche, die Anzahl der einzigartigen Tage für jede Gruppe in R zu zählen. Für einige Beobachtungen ist es ziemlich einfach, dh A und B. Jedoch gibt es einige Gruppen mit unterschiedlichen Überlappungen von Tagen sowie Lücken in den Datumsbereichen, dh H.Zählen von eindeutigen Tagen mit Überlappung und Lücken in Datumsbereichen

Gibt es trotzdem ich kann die Anzahl der eindeutigen Tage (keine Überlappung und Berücksichtigung der Lücken) für jede Gruppe in R zusammenfassen? d.h. A und B würden jeweils 3 Tage zurückgeben, und H würde 11 Tage zurückgeben.

Group Count 
A  3 
B  3 
H  16 

Meine beste Vermutung würde die dplyr verwenden und Funktion zusammenfassen, aber ich habe meinen Kopf nicht in der Lage gewesen, um jede Lösung zu wickeln. Jede Hilfe wird geschätzt! Danke

+1

schön formulierte Frage. Könnten Sie näher erläutern, wie Fall drei zu 11 – OdeToMyFiddle

+0

Summe meiner Entschuldigung die richtige Anzahl hätte 16 sein sollen, wie unten erwähnt! –

Antwort

5

Hier ist eine dplyr Lösung:

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)) 

Die Idee ist, eine neue Spalte zu erstellen, die eine Reihe von Daten von Anfang bis Ende enthält, und dann Zählen Sie die Länge der einzelnen Beobachtungen in jeder Gruppe.

Dies gibt:

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

Das hat funktioniert! Das hat mich tagelang belästigt, bis ich beschlossen habe, hier zu berichten. Ihr seid unglaublich! –

+0

Sie könnten auch 'n_distinct' anstatt der' length' & 'unique' Kombination verwenden:' numDays = n_distinct (Datum) ' – Jaap

+0

Danke für den Vorschlag, @ProcrastinatusMaximus! Ich habe die Antwort aktualisiert, um n_distinct zu verwenden. – shreyasgm

4

Wenn Sie die einzigartigen Tage nach Gruppe zählen wollen, ich tun würde (vorausgesetzt, Ihre Start und End Spalten sind in Datumsformat):

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

die gibt:

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

Erläuterung: Für jede Zeile erstellen Sie Datumsfolgen mit den Daten Start und End. Danach zählen Sie die einzigartigen Tage mit der uniqueN Funktion. Das ist besser als meine alte Antwort (siehe unten), weil dadurch Lücken berücksichtigt werden.

Dies ergibt eine höhere Nummer für die H Gruppe im Vergleich zu Ihrer beschriebenen gewünschten Ausgabe. Wenn Sie sich jedoch Ihre Daten genau ansehen, werden Sie sehen, dass die richtige Nummer 16 ist.


Eine ähnliche Lösung mit Base 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))) 

, die ein ähnliches Ergebnis ergibt:

group dates 
1  A  3 
2  B  3 
3  H 16 

Wenn Sie die dates Spalte in df2 Datum-Format wollen, as.Date(unlist(l), origin = '1970-01-01') stattdessen verwenden von unlist(l).


Gebrauchte Daten:

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

Vielen Dank für die gründliche Erklärung! Ich schätze das wirklich! –

+0

@MichaelLuu Ich habe auch eine Basis R-Ansatz enthalten. – Jaap

Verwandte Themen