2016-12-07 5 views
4

Ich habe die folgenden Daten:Suche nach dem Datum der Differenz

ID GROUP  DATE 
A GR1 12/01/2013 
A GR1 09/04/2014 
A GR1 01/03/2015 
A GR2 04/04/2015 
A GR2 08/21/2015 
A GR1 01/05/2016 
A GR1 06/28/2016 
B GR2 11/01/2013 
B GR2 06/04/2014 
B GR2 04/15/2015 
B GR3 11/04/2015 
B GR2 03/21/2016 
B GR2 07/05/2016 
B GR1 06/28/2016 
C GR2 01/16/2014 
C GR2 06/04/2014 
C GR2 04/15/2015 
C GR3 11/04/2015 
C GR2 03/21/2016 
C GR2 06/05/2016 
C GR1 06/28/2016 

Ich möchte den Unterschied der Person in jeder Gruppe blieb erhalten. So ist die neue Tabelle wird wie folgt aussehen:

ID GROUP  DATE  Diff 
A GR1 12/01/2013 
A GR1 09/04/2014 
A GR1 01/03/2015 398 
A GR2 04/04/2015 
A GR2 08/21/2015 139 
A GR1 01/05/2016 
A GR1 06/28/2016 175 
B GR2 11/01/2013 
B GR2 06/04/2014 
B GR2 04/15/2015 530 
B GR3 11/04/2015 
B GR2 03/21/2016 
B GR2 07/05/2016 106 
B GR1 06/28/2016 
C GR2 01/16/2014 
C GR2 06/04/2014  
C GR2 04/15/2015 454 
C GR3 11/04/2015 
C GR2 03/21/2016 
C GR2 01/05/2016 76 
C GR1 06/28/2016 

der Wert in der Spalte "Diff" 398 durch die Differenz unter kommt '01/03/2015' - '12/1/2013' . Ähnlich alle anderen Unterschiede.

Jetzt ist meine Frage, wie man diesen Unterschied bekommt? Ich kann nicht Max (Datum) -min (Datum) bei jeder Gruppe nehmen, weil sich die Gruppe zu unterschiedlichen Zeitpunkten wiederholt. Ähnlich kann ich nicht den ersten Punkt und den letzten Punkt wie in SAS nehmen.

Ich werde sehr dankbar sein, wenn mir jemand mit der Lösung helfen wird. Ich würde die Lösung in SAS bevorzugen, da die Datengröße sehr groß ist. SO hält sich nicht im Speicher.

Grüße,

+0

@RichScriven: Vielen Dank für Ihren Kommentar. Aber kannst du mir bitte sagen, wie es geht? Ich bevorzuge sas, da die Datengröße so groß ist, dass sie nicht im Speicher gehalten wird. – Beta

Antwort

6
library(dplyr) 
library(data.table) 
df$xxx = rleidv(df[, c("ID","GROUP"),with = FALSE ]) 
df$DATE = as.Date(df$DATE, format = "%m/%d/%Y") 
df %>% group_by(xxx) %>% mutate(diff = max(DATE) - min(DATE)) %>% 
     ungroup(xxx) %>% mutate(xxx = NULL) 
#  ID GROUP  DATE  diff 
# <chr> <chr>  <date> <time> 
#1  A GR1 2013-12-01 398 days 
#2  A GR1 2014-09-04 398 days 
#3  A GR1 2015-01-03 398 days 
#4  A GR2 2015-04-04 139 days 
#5  A GR2 2015-08-21 139 days 
#6  A GR1 2016-01-05 175 days 
#7  A GR1 2016-06-28 175 days 
#8  B GR2 2013-11-01 530 days 
#9  B GR2 2014-06-04 530 days 
#10  B GR2 2015-04-15 530 days 

nur data.table mit:

library(data.table) 
df[, diff := max(DATE)-min(DATE),by = c("xxx")][,xxx:=NULL] 
+0

Vielen Dank für Ihre Antwort. Ihre Antwort hat meine Frage perfekt beantwortet. Aber ich würde gerne auf Richs Antwort warten, als er zuerst die Lösung gab, bevor er Ihre Antwort akzeptierte. Ich hoffe, es wird Ihnen nichts ausmachen. Nochmals vielen Dank Joel! – Beta

+0

@Beta ist Ihr Anruf –

+1

Wenn wir nur GROUP verwenden, um die Läufe zu finden ('df $ xxx = rleid (df $ GROUP)'), bekommen wir Ärger, wenn die nächste ID mit derselben Gruppe beginnt. In diesen bestimmten Daten ändert sich die Gruppe immer, wenn sich die ID ändert, also ist es nicht passiert ... –

2
data want(drop=_:); 
    merge have have(firstobs=2 rename=(id=_id group=_group date=_date)); 
    retain _temp; 
    _temp= min(_temp,date); 
    if id^=_id or group^=_group then do; 
     diff=intck('day',_temp,date); 
     if diff=0 then call missing(diff); 
     _temp=_date; 
    end; 
run; 
+0

Vielen Dank für Ihre Antwort! – Beta

5

es mit SAS ist Doing trivial. Verwenden Sie RETAIN, um das Startdatum vom ersten Datensatz für die Gruppe beizubehalten. Ihre Daten werden nicht sortiert angezeigt. Sortieren Sie sie also entweder zuerst, oder wenn Sie die aktuelle Bestellung beibehalten möchten (und die Datensätze in den Gruppen sind bereits nach Datum sortiert), können Sie die -Option für die BY-Anweisung verwenden.

data want ; 
    set have ; 
    by id group notsorted; 
    if first.group then start = date ; 
    else if last.group then diff = date - start ; 
    retain start; 
    drop start; 
run; 

Wenn Sie die aktuelle Ordnung halten müssen, aber die Daten sind nicht innerhalb der Gruppen sortiert, dann die min zu entdecken und max Daten innerhalb der Gruppe müssen Sie eine andere Variable und ein wenig mehr Logik hinzuzufügen.

data want ; 
    set have ; 
    by id group notsorted; 
    if first.group then start = date ; 
    if first.group then stop = date ; 
    start = min(start,date); 
    stop = max(stop,date); 
    if last.group and not first.group then diff = stop - start ; 
    retain start stop; 
    drop start stop; 
run; 
+0

Vielen Dank Tom! Ich habe tatsächlich so verfahren, wie du es vorgeschlagen hast, außer dass ich nicht die Option "nicht sortiert" verwendet habe. Ich war mir dessen nicht bewusst. Das ist ein tolles Lernen! Danke noch einmal! – Beta

Verwandte Themen