2015-08-04 4 views
7

Hallo Ich habe zwei Tabellen (Tabelle1 und Tabelle2 unten) und möchte sie basierend auf dem nächsten Zeitstempel zu expected_output verbinden. Irgendeine Lösung mit dplyr wäre, wenn möglich, großartig, aber nicht, wenn es die Dinge noch komplizierter macht.Verknüpfen Sie zwei Datenrahmen in R basierend auf dem nächsten Zeitstempel

table1 = 
structure(list(date = structure(c(1437051300, 1434773700, 1431457200 
), class = c("POSIXct", "POSIXt"), tzone = ""), val1 = c(94L, 
33L, 53L)), .Names = c("date", "val1"), row.names = c(NA, -3L 
), class = "data.frame") 

table2 = 
structure(list(date = structure(c(1430248288, 1435690482, 1434050843 
), class = c("POSIXct", "POSIXt"), tzone = ""), val2 = c(67L, 
90L, 18L)), .Names = c("date", "val2"), row.names = c(NA, -3L 
), class = "data.frame") 

expected_output = 
structure(list(date = structure(c(1437051300, 1434773700, 1431457200 
), class = c("POSIXct", "POSIXt"), tzone = ""), val1 = c(94L, 
33L, 53L), val2 = c(90L, 18L, 67L)), .Names = c("date", "val1", 
"val2"), row.names = c(NA, -3L), class = "data.frame") 

Antwort

12

Roll Joins Merkmal data.table mit roll = "nearest":

require(data.table) # v1.9.6+ 
setDT(table1)[, val2 := setDT(table2)[table1, val2, on = "date", roll = "nearest"]] 

Hier val2 Spalte wird erstellt, indem ein auf der Säule date mit roll = "nearest" Option verbinden. Für jede Zeile von table1$date wird die am nächsten passende Zeile aus table2$date berechnet und val2 für die entsprechende Zeile wird extrahiert.

+0

Dies ist sehr hilfreich! Eine Idee, wie man von "am nächsten" zu "am neuesten" wechselt? I.e. die Zeit direktional halten und in der Zukunft nicht zu einer Reihe verschmelzen? – emudrak

+1

@emudrak 'roll = Inf' direktional unbegrenzt. "roll = 30" Richtungsgrenze für Staleness. Verwenden Sie das Zeichen, um die Richtung zu steuern. –

2

Dies haftet langsam, aber ...

d <- function(x,y) abs(x-y) # define the distance function 
idx <- sapply(table1$date, function(x) which.min(d(x,table2$date))) # find matches 

cbind(table1,table2[idx,-1,drop=FALSE]) 
#     date val1 val2 
# 2 2015-07-16 08:55:00 94 90 
# 3 2015-06-20 00:15:00 33 18 
# 1 2015-05-12 15:00:00 53 67 

Ein anderer Weg idx der Konstruktion ist max.col(-outer(table1$date, table2$date, d)).

Verwandte Themen