2014-12-15 8 views
15

Wie die unten (einfach mit sqldf) zu tun data.table und bekommen genau das gleiche Ergebnis mit:Wie führt man Join-Over-Datumsbereiche mit data.table aus?

library(data.table) 

whatWasMeasured <- data.table(start=as.POSIXct(seq(1, 1000, 100), 
    origin="1970-01-01 00:00:00"), 
    end=as.POSIXct(seq(10, 1000, 100), origin="1970-01-01 00:00:00"), 
    x=1:10, 
    y=letters[1:10]) 

measurments <- data.table(time=as.POSIXct(seq(1, 2000, 1), 
    origin="1970-01-01 00:00:00"), 
    temp=runif(2000, 10, 100)) 

## Alternative short names for data.tables 
dt1 <- whatWasMeasured 
dt2 <- measurments 

## Straightforward with sqldf  
library(sqldf) 

sqldf("select * from measurments m, whatWasMeasured wwm 
where m.time between wwm.start and wwm.end") 
+1

Löst dies Ihr Problem? http://stackoverflow.com/questions/5123197/matching-time-a-time-in-the-interval-between-a-start-and-end-time –

+0

@DavidRobinson Thanks. Ich habe diese Frage und Antwort tatsächlich gesehen, aber leider ist mein Datenvolumen riesig und würde wirklich eine schnelle data.table Lösung bevorzugen ... – Samo

+0

Ich weiß, dass das ein bisschen unerforscht ist, aber bin ich der einzige, der Dec-31-1969 erhält Termine? Sollte es nicht Jan-1-1970 sein? –

Antwort

17

Sie die foverlaps() Funktion nutzen zu können, die effizient verbindet über Intervalle implementiert. In Ihrem Fall benötigen wir nur eine Dummy-Spalte für measurments.

Anmerkung 1: - v1.9.5 als Bug mit foverlaps() dort fixiert wurde Sie sollten die Entwicklungsversion von data.table installieren. Sie finden die Installationsanleitung here.

Anmerkung 2: Ich rufe whatWasMeasured = dt1 und measurments = dt2 hier für die Bequemlichkeit.

require(data.table) ## 1.9.5+ 
dt2[, dummy := time] 

setkey(dt1, start, end) 
ans = foverlaps(dt2, dt1, by.x=c("time", "dummy"), nomatch=0L)[, dummy := NULL] 

Siehe ?foverlaps für weitere Informationen und this post für einen Leistungsvergleich.

+0

gibt es irgendeine Möglichkeit, die wir mit einer Art% zwischen Prozent Aussage wegkommen könnten? Hatte eine harte Zeit bekommen dt2 [Zeit% zwischen% dt1 [, Liste (Start, Ende)]] zu arbeiten, wie ich gehofft hatte. –

+0

@SerbanTanasa, schauen Sie sich [die Post] (http://Stackoverflow.com/a/25655497/559784) Ich habe in meiner Antwort verknüpft. Es vergleicht die Leistung einer Lösung auch mit "between". – Arun

+0

Danke für Ihre Antwort. Groß. Es klappt. Sehr schnell. Das einzige kleine Problem ist, dass es keine fehlenden Werte für Anfang oder Ende oder Zeit mag. vielleicht wäre ein na.rm-handling gut zu haben. Wenn ich diese Übung mit realen Daten durchführe, bekomme ich im Endergebnis zwei zusätzliche unerwünschte Spalten mit den Namen "start" und "end", die ich weder in den Eingabedaten noch die Namen der Schlüssel oder irgendetwas habe ... – Samo

Verwandte Themen