2016-03-23 12 views
7

Ho 2 frame di dati:Come rimuovere le righe da una tabella di dati in base a una condizione in un'altra tabella dati

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")) 

Vorrei mantenere tutte le righe in master entro +/- 5 seconda finestra di qualsiasi ora nel frame di dati mydata. Vorrei rimuovere le righe in master che non soddisfano tale condizione.

Ecco un esempio più semplice se mydata ha solo 1 file:

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")) 

Potete vedere mydata contiene solo "2015-01-01 00:00:18". In questo caso voglio rimuovere tutte le righe dal telaio master data in cui il tempo non è all'interno del + - 5 secondi finestra di IE Voglio rimuovere tutte le righe da master prima "2015-01-01 00:00:13" e dopo "2015-01-01 00:00:23"

questo è il caso semplice ma un caso più difficile è se mydata contiene

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

in questo caso perché "2015-01-01 00:00:18" è nuovamente io normalmente rimuovere tutte le righe nella matrice prima e dopo "2015-01-01 00:00:13""2015-01-01 00:00:23".

Ma in questo caso non posso farlo perché mydata contiene anche "2015-01-01 00:00:22" così voglio mantenere tutte le righe master dopo "2015-01-01 00:00:18" e prima "2015-01-01 00:00:27"

Perché "2015-01-01 00:00:22" è nella mia dati che ora hanno bisogno di mantenere la righe nella matrice da "2015-01-01 00:00:23" a "2015-01-01 00:00:27"

Fondamentalmente voglio mantenere qualsiasi riga master che si trova a +/- 5 seconda finestra di ogni riga mydata. Se ci sono delle righe nel master che sono non all'interno di una finestra di 5 secondi, desidero eliminarlo.

Aggiornamento

può consigliare come implementare questo se master e mydata hanno più di 1 colonna come:

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 realtà sia master e mydata hanno 50+ colonne.

+0

Credo che 'maestri [rowSums (abs (esterni (master $ MasterTimes, mydata $ MyTimes, difftime, unità = "SEC")) <=5)> 0]' potrebbe essere un modo, ma non si adatta bene e sicuramente esistono soluzioni migliori – nicola

risposta

1

Soluzione base R:

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

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

Grazie, puoi spiegare dove i parametri row e mydata vengono passati alla funzione check_valid_time quando chiami sapply()? – user3022875

+0

@CatusWoman - Riesci a vedere l'aggiornamento nel post Come si impianta la soluzione con più di 1 colonna nei frame di dati. In realtà master e mydata hanno entrambi 50+ colonne – user3022875

+0

@ user3022875 Questo dovrebbe funzionare indipendentemente da quante colonne hai (la variabile è chiamata riga ma in realtà è solo il valore di 'MasterTimes' per quella riga) Sapply sta passando ogni valore di' master $ MasterTimes' a 'check_valid_time', con 'mydata' come parametro aggiuntivo. –

0

Basandosi sul commento di Nicola:

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

Una possibilità potrebbe essere la seguente. Per prima cosa crea foo che contiene +/- 5 secondi di mydata $ MyTimes per ogni riga. Quindi, il sottoinsieme master. Innanzitutto, rimuovi mydata$MyTimes e quindi seleziona foo$whatever in MasterTimes. Nel caso, ho ordinato i dati per MasterTimes alla fine.

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

O come questa:

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

WHy ci sono NA nell'output? – user3022875

+0

@ user3022875 Non ottengo alcun 'NA's dopo aver eseguito il codice. Sono tutti i valori 'NA's? – DatamineR

+0

il risultato è corretto ma include NA nella parte inferiore – user3022875

Problemi correlati