2016-12-07 3 views
2

Ich versuche, zwei Datensätze bis zum nächsten vorhergehenden Datum, nach Gruppe übereinstimmen. Also innerhalb einer Gruppe möchte ich die Variablen eines zweiten Datensatzes (d2) zu dem der ersten (d1) hinzufügen, wenn das Datum des ersten Datums das nächste Datum am oder vor dem Datum des zweiten Datums ist. Wenn zwei Zeilen im zweiten Datensatz mit einer Zeile im ersten verglichen werden, möchte ich den größeren der Werte hinzufügen. (Es wird immer mindestens ein Datum in d1 kleiner als dem Zeitpunkt in d2, durch Gruppe)Merge zwei Datenrahmen bis zum nächsten vorherigen Datum beim Aggregieren

Hier ist ein Beispiel, das hoffentlich macht deutlicher

d1 = data.frame(id=c(1,1,1,2,2), 
       ref=as.Date(c("2013-12-07", "2014-12-07", "2015-12-07", "2013-11-07", "2014-11-07"))) 
d1 
# id  ref 
# 1 1 2013-12-07 
# 2 1 2014-12-07 
# 3 1 2015-12-07 
# 4 2 2013-11-07 
# 5 2 2014-11-07 

d2 = data.frame(id=c(1,1,2),     
       date=as.Date(c("2014-05-07","2014-12-05", "2015-11-05")), 
       x1 = factor(c(1,2,2), ordered = TRUE), 
       x2 = factor(c(2, NA ,2), ordered=TRUE)) 
d2 
# id date x1 x2 
# 1 1 2014-05-07 1 2 
# 2 1 2014-12-05 2 <NA> 
# 3 2 2015-11-05 2 2 

Mit dem erwarteten Ergebnis

output = data.frame(id=c(1,1,1,2,2), 
        ref=as.Date(c("2013-12-07", "2014-12-07", "2015-12-07", "2013-11-07", "2014-11-07")), 
        x1 = c(2, NA, NA, NA, 2), 
        x2 = c(2, NA, NA, NA, 2)) 
output 
# id  ref x1 x2 
# 1 1 2013-12-07 2 2 
# 2 1 2014-12-07 NA NA 
# 3 1 2015-12-07 NA NA 
# 4 2 2013-11-07 NA NA 
# 5 2 2014-11-07 2 2 

So zum Beispiel die ersten beiden Beobachtungen von d2, id = 1, mit Daten "2014-05-07","2014-12-05", sind auf das frühere Datum "2013-12-07" in d1 abgestimmt. Da in d1 zwei Zeilen zu einer Zeile passen, wird die höchste Ebene ausgewählt.

Ich könnte dies in der Basis R durch Schleifen der folgenden Berechnungen durch jeder Gruppe tun, aber ich hatte auf etwas effizienteres gehofft. Ich würde gerne einen data.table Ansatz sehen (aber ich bin auf R v3.1 und data.table v1.9.4 beschränkt). Dank

echte Daten-Set:
d1: Reihen 1M/100K Gruppen
d2: Reihen 11K/4K-Gruppen

# for one group 
x = d1[d1$id==1, ] 
y = d2[d2$id==1, ] 
id = apply(outer(x$ref, y$date, "-"), 2, which.min) 
temp = cbind(y, ref=x$ref[id]) 
# aggregate variables by ref 
temp = merge(aggregate(x1 ~ ref, data=temp, max), 
aggregate(x2 ~ ref, data=temp, max) 
) 
merge(x, temp, all=T) 

ps: ich How to match by nearest date from two data frames? und Join data.table on exact date or if not the case on the nearest less than date ohne Erfolg ausgesehen hatte.

Antwort

1

Sie können diese dplyr mit tun:

d2$ind <- 0 
library(dplyr) 
out <- d1 %>% full_join(d2,by=c("id","ref"="date")) %>% 
       arrange(id,ref) %>% 
       mutate(ind=cumsum(ifelse(is.na(ind),1,ind))) %>% 
       group_by(ind) %>% 
       summarise(ref=min(ref),x1=max(x1,na.rm=TRUE),x2=max(x2,na.rm=TRUE)) 
### A tibble: 5 x 4 
## ind  ref  x1  x2 
## <dbl>  <date> <fctr> <fctr> 
##1  1 2013-12-07  2  2 
##2  2 2014-12-07  NA  NA 
##3  3 2015-12-07  NA  NA 
##4  4 2013-11-07  NA  NA 
##5  5 2014-11-07  2  2 

Wir zunächst eine Spalte von Indikatoren d2 hinzuzufügen und auf Null gesetzt. Dann führen wir eine vollständige äußere Verbindung zwischen d1 und d2 durch. Diese Zeilen in d1 haben ind von NA. Wir sortieren nach id und ref (d. H. Das Datum) und ersetzen die NA Einträge von ind durch 1 und führen eine cumsum durch. Daraus ergibt sich:

id  ref x1 x2 ind 
1 1 2013-12-07 <NA> <NA> 1 
2 1 2014-05-07 1 2 1 
3 1 2014-12-05 2 <NA> 1 
4 1 2014-12-07 <NA> <NA> 2 
5 1 2015-12-07 <NA> <NA> 3 
6 2 2013-11-07 <NA> <NA> 4 
7 2 2014-11-07 <NA> <NA> 5 
8 2 2015-11-05 2 2 5 

Daraus können wir leicht sehen können, dass wir können Gruppe von ind und summarise entsprechend Ihr Ergebnis zu erhalten.

+0

danke für Ihre Antwort – user2957945

Verwandte Themen