2016-04-06 4 views
2

Lets nehme ich einen Datenrahmen haben:Erstellen Sie eine Folge von einzigartigen Beobachtungen Gruppe mit dplyr und erstellen Sie einen Unterschied in Monaten Spalte

User Date 
    aaaa 2015-11-26 
    aaaa 2015-12-26 
    aaaa 2016-01-26 
    bbbb 2014-10-15 
    bbbb 2014-11-15 
    bbbb 2015-05-16 

Und ich möchte eine neue Spalte Variable (n), dass generieren:

  1. einen die eindeutigen Benutzer in Folge Count
  2. Wenn eine Lücke im Monat zu Monat gibt es, zählen, wie viele Monate die Lücke ist.

Wunsch ouput:

User Date  Count Gap 
    aaaa 2015-11-26 1  0 
    aaaa 2015-12-26 2  0 
    aaaa 2016-01-26 3  0 
    bbbb 2014-10-15 1  0 
    bbbb 2014-11-15 2  0 
    bbbb 2015-05-16 3  6 
+1

Was passiert, wenn die Reihenfolge des Benutzers war 'c ("aaa", "aaa", "bbbb", "aaa", "bbbb", "bbbb") '? Sollte das Ergebnis gleich sein? Oder startet das eine neue Sequenz für User 'aaaa'? –

+0

Nein, es war die Reihenfolge "a, a, b, a, b, b" - die Zählung sollte als "1,2,1,3,2,3" zurückgehen - der eigentliche Datenrahmen hat Tausende von eindeutigen Benutzern und Zehntausende von Beobachtungen. Ich nehme an, dass sie alle gemischt sind - obwohl ich leicht durch einzigartigen Benutzer gruppieren könnte, wenn es sein muss. –

+0

Das sieht wie eine Option aus: http://StackOverflow.com/Q/22287062 Für die "Count" -Ding in dplyr, tun Sie einfach group_by und row_number. – Frank

Antwort

0

zoo::as.yearmon() Verwendung jedoch ich round hatte, weil sonst 2015-11-26 zu 2015-12-26 betrachtet länger als einem Monat. Vielleicht kann jemand kommentieren/bearbeiten/erklären, wie man diese bestimmte Berechnung "intuitiver" macht.

library(dplyr) 
library(zoo) 

df %>% 
    group_by(User) %>% 
    mutate(Count = 1:n(), 
     Gap_In_Months = round(12 * as.numeric(as.yearmon(Date) - as.yearmon(lag(Date))), 1), 
     Gap = ifelse(Gap_In_Months <= 1 | is.na(Gap_In_Months), 0, Gap_In_Months)) 

#  User  Date Count Gap_In_Months Gap 
# (fctr)  (fctr) (int)   (dbl) (dbl) 
# 1 aaaa 2015-11-26  1   NA  0 
# 2 aaaa 2015-12-26  2    1  0 
# 3 aaaa 2016-01-26  3    1  0 
# 4 bbbb 2014-10-15  1   NA  0 
# 5 bbbb 2014-11-15  2    1  0 
# 6 bbbb 2015-05-16  3    6  6 

Vielleicht möchten Sie genauer zu sein "Was ist ein Monat"? 30 Tage? 31 Tage? 28 Tage?

Wenn das der Fall ist, können wir lubrdiate nutzen:

library(lubridate) 

df %>% 
    group_by(User) %>% 
    mutate(Count = 1:n(), 
     Diff_Time = ymd(Date) - ymd(lag(Date)), 
     Gap = ifelse(Diff_Time <= ddays(31) | is.na(Diff_Time), 0, as.numeric(Diff_Time, units = "days"))) 

#  User  Date Count Diff_Time Gap 
# (fctr)  (fctr) (int) (dfft) (dbl) 
# 1 aaaa 2015-11-26  1 NA days  0 
# 2 aaaa 2015-12-26  2 30 days  0 
# 3 aaaa 2016-01-26  3 31 days  0 
# 4 bbbb 2014-10-15  1 NA days  0 
# 5 bbbb 2014-11-15  2 31 days  0 
# 6 bbbb 2015-05-16  3 182 days 182 
+0

Süß! - werde ich Geben Sie das einen Lauf. Wirklich, um einen Monat bedeute ich buchstäblich die Zunahme in der Ganzzahl des Monats. Der Tageswert ist für das, woran ich arbeite, überflüssig. –

+0

Das ist gut, aber gehen Sie mit Vorsicht vor - betrachten Sie '2015-11-30 'to' 2015-12-01' - so wie dies geschrieben steht, würde dies als eine Lücke von einem Monat betrachtet werden, die möglicherweise nicht das ist, was Sie beabsichtigen. Ein Grund mehr, die Zwischenrechnung beizubehalten (zB 'Gap_In_Months 'an die Daten angehängt – JasonAizkalns

Verwandte Themen