2016-05-27 20 views
7

Ho una situazione come questa. Multiple data.table "rbinded".Come identificare solo le righe "non duplicate"

library(data.table) 
x <- data.table(id=c(1,2,3,4),dsp=c(5,6,7,8),status=c(FALSE,TRUE,FALSE,TRUE)) 
y <- data.table(id=c(1,2,3,4),dsp=c(6,6,7,8),status=c(FALSE,FALSE,FALSE,TRUE)) 
z <- data.table(id=c(1,2,3,4),dsp=c(5,6,9,8),status=c(FALSE,TRUE,FALSE,FALSE)) 
w <- data.table(id=c(1,2,3,4),dsp=c(5,6,7,NA),status=c(FALSE,TRUE,FALSE,TRUE)) 
setkey(x,id) 
setkey(y,id) 
setkey(z,id) 
setkey(w,id) 
Bigdt<-rbind(x,y,z,w) 

vorrei ottenere solo le righe non ripetute come:

id dsp status 
1 6 FALSE 
2 6 FALSE 
3 9 FALSE 
4 8 FALSE 
4 NA TRUE 

Così ho provato

Resultdt<-Bigdt[!duplicated(Bigdt)] 

ma il risultato:

id dsp status 
1 5 FALSE 
2 6 TRUE 
3 7 FALSE 
4 8 TRUE 

non corrisponde le mie aspettative. Ho provato in diversi metodi (dato che rbind non è obbligatorio), per esempio unire, unire, ecc. Il pacchetto data.table sembra potenzialmente quello che contiene la soluzione ... apparentemente. Qualche idea?

+0

Il codice funziona bene per me (con copia da incollare da qui), Frank, scusa ma il tuo codice non fornisce il risultato previsto ... –

+0

correct! Scusate, modifico, ma per quanto riguarda le altre linee? –

+0

Questo è quello che ottengo: stato id dsp N 1 6 FALSE 1 2 6 FALSE 1 3 9 FALSE 1 4 8 FALSE 1 4 NA TRUE 1 –

risposta

9

Si può fare

Bigdt[, .N, by=names(Bigdt)][N == 1L][, N := NULL][] 

    id dsp status 
1: 1 6 FALSE 
2: 2 6 FALSE 
3: 3 9 FALSE 
4: 4 8 FALSE 
5: 4 NA TRUE 

Per vedere come funziona, eseguire solo una parte della catena DT[][][][]:

  • Bigdt[, .N, by=names(Bigdt)]
  • Bigdt[, .N, by=names(Bigdt)][N == 1L]
  • Bigdt[, .N, by=names(Bigdt)][N == 1L][, N := NULL]
+1

Grazie Frank! :) –

+1

Se colpisci i limiti di memoria con la soluzione di Frank, puoi usare facoltativamente 'dt [, N: = rowidv (dt)]' per aggiungere la sequenza di righe duplicate sul set di dati sul posto, quindi sottoinsieme su 'N == 1L'. – jangorecki

+0

@jangorecki La tabella dati deve essere ordinata per quello? Lo aggiungerò alla risposta. Sentiti libero di modificare in altri dettagli o alternative. – Frank

2

Si può anche provare

Bigdt[!(duplicated(Bigdt)|duplicated(Bigdt, fromLast=TRUE))] 
# id dsp status 
#1: 1 6 FALSE 
#2: 2 6 FALSE 
#3: 3 9 FALSE 
#4: 4 8 FALSE 
#5: 4 NA TRUE 

O se stiamo usando .SD

Bigdt[Bigdt[,!(duplicated(.SD)|duplicated(.SD, fromLast=TRUE))]] 

o un'altra opzione sarebbe il raggruppamento per i nomi delle colonne, trovare l'indice di riga con .I e sottoinsieme del set di dati

Bigdt[Bigdt[, .I[.N==1], by = names(Bigdt)]$V1] 
Problemi correlati