2016-03-23 19 views
7

Ich habe 2-Datenrahmen:Wie Zeilen aus einer Datentabelle zu entfernen, basierend auf einem Zustand in einen anderen Datentabelle

master = data.table(MasterTimes= as.POSIXct("2015-01-01", tz = "GMT") + seq(1,100,1)) 
mydata = data.frame(MyTimes = as.POSIXct(c("2015-01-01 00:00:18","2015-01-01 00:00:54","2015-01-01 00:00:48","2015-01-01 00:01:10","2015-01-01 00:01:05"),tz = "GMT")) 

Ich würde innerhalb von +/- 5 Sekunden Fenster in Master alle Zeilen halten möchten jede Zeit im mydata Datenrahmen. Ich möchte die Zeilen in master entfernen, die diese Bedingung nicht erfüllen.

Hier ist ein einfacheres Beispiel, wenn mydata nur 1 Reihen hat:

master = data.table(MasterTimes= as.POSIXct("2015-01-01", tz = "GMT") + seq(1,100,1)) 
mydata = data.frame(MyTimes = as.POSIXct(c("2015-01-01 00:00:18"),tz = "GMT")) 

können Sie sehen mydata enthält nur "2015-01-01 00:00:18". In diesem Fall möchte ich alle Zeilen aus dem Stammdatenrahmen entfernen, wo die Zeit nicht innerhalb der + ist - 5 Sekunden Fenster dh ich alle Zeilen aus master vor "2015-01-01 00:00:13" und nach "2015-01-01 00:00:23"

Das ist der einfache Fall entfernen möge aber ein schwieriger Fall ist, wenn mydata

mydata = data.frame(MyTimes = as.POSIXct(c("2015-01-01 00:00:18", "2015-01-01 00:00:22"),tz = "GMT")) 

in diesem Fall enthält, weil "2015-01-01 00:00:18" wieder würde ich normalerweise alle Zeilen in Master vor "2015-01-01 00:00:13" und nach "2015-01-01 00:00:23" entfernen.

Aber in diesem Fall kann ich das nicht tun, weil mydata auch "2015-01-01 00:00:22" so wollen I enthält in master nach "2015-01-01 00:00:18" alle Zeilen halten und vor "2015-01-01 00:00:27"

Da "2015-01-01 00:00:22" in meine Daten muss ich jetzt die halten in Master Reihen von "2015-01-01 00:00:23" zu "2015-01-01 00:00:27"

Grundsätzlich mag ich jede Zeile im Master halten, die in mydata innerhalb eines +/- 5 Sekunden-Fenster von jeder Reihe ist. Wenn es Zeilen im Master gibt, die nicht innerhalb eines 5 Sekunden Fensters sind, möchte ich es löschen.

aktualisieren

Können Sie beraten, wie dies zu implementieren, wenn master und mydata mehr als 1 Spalte haben wie:

master = data.table(MasterTimes= as.POSIXct("2015-01-01", tz = "GMT") + seq(1,100,1), otherol = seq(1,100,1)) 
mydata = data.frame(MyTimes = as.POSIXct(c("2015-01-01 00:00:18"),tz = "GMT"),othercol = c(1)) 

In Wirklichkeit beide Master und mydata haben 50+ Spalten.

+0

Ich denke, dass 'master [rowSums (abs (Außen (Master $ MasterTimes, mydata $ MyTimes, difftime, Einheiten = "sec")) <=5)> 0]' könnte ein Weg sein, aber es skaliert nicht gut und sicherlich bessere Lösungen existieren. – nicola

Antwort

1

Base-R Lösung:

check_valid_time <- function(row, mydata){ 
    any(row > mydata$MyTimes - 5 & row < mydata$MyTimes + 5) 
} 

master[sapply(master$MasterTimes, check_valid_time, mydata),] 
+0

Danke! Können Sie erklären, wo die Zeile und mydata Parameter an die Funktion check_valid_time übergeben werden, wenn Sie sapply() aufrufen? – user3022875

+0

@CatusWoman - Können Sie sehen das Update in der post. Wie würden Sie Ihre Lösung mit mehr als 1 Spalte in den Datenrahmen implementieren.In der Realität haben Master-und mydata beide 50 Spalten – user3022875

+0

@ user3022875 Dies sollte funktionieren, egal wie viele Spalten Sie haben (die Variable heißt Zeile, aber es ist eigentlich nur der Wert von 'MasterTimes' für diese Zeile). Sapply übergibt jeden Wert von' master $ MasterTimes' an 'check_valid_time' mit 'mydata' als zusätzlicher Parameter. –

0

Aufbauend auf nicola Kommentar:

master[unlist(lapply(master$MasterTimes, function(x) any(abs(difftime(x, mydata$MyTimes, units="secs"))<5))),] 
1

Eine Möglichkeit folgende sein würde. Sie erstellen zuerst foo, die +/- 5 Sekunden von MyData $ MyTimes für jede Zeile enthält. Dann, Sie Teilmenge master. Zuerst entfernen Sie mydata$MyTimes und wählen dann foo$whatever in MasterTimes. Nur für den Fall, sortierte ich die Daten nach MasterTimes am Ende.

foo <- setDT(mydata)[, list(whatever = seq(MyTimes - 5, MyTimes + 5, by = 1)), by = rownames(mydata)] 
master[!MasterTimes %in% mydata$MyTimes][MasterTimes %in% foo$whatever] -> x 

setorder(x, MasterTimes) 
0

Oder wie folgt aus:

master[which(sapply(unlist(master), function(x) 
    min(sapply(unlist(mydata), function(y) abs(x - y)))) <5),] 
+0

WARUM sind NAs in deiner Ausgabe? – user3022875

+0

@ user3022875 Ich bekomme keine 'NA' nach dem Ausführen des Codes. Sind alle Werte 'NA's? – DatamineR

+0

das Ergebnis ist korrekt, aber es enthält NAs an der Unterseite – user3022875

Verwandte Themen