2015-03-05 27 views
5

Vorrei rimuovere tutte le righe di un data.table che contengono Inf in una qualsiasi delle sue colonne. Finora, ho usato questo approccio:Rimuovere le righe con NA da data.table in R

DT <- data.table(col1 = c(1,2,3), col2 = c(4,Inf,5)) 
DT[,drop := apply(.SD, 1, function(x) any(is.infinite(x))), by = 1:nrow(DT)] 
DT <- DT[(!drop)][,drop:=NULL] 

che viene da this Stackoverflow question. Tuttavia, questo approccio non è ben scalabile per grandi quantità di dati. C'è un modo migliore per rimuovere le righe con Inf?

+2

può essere 'DT [DT [, Riduzione ('&', lapply (.SD, is.finite))]]' – akrun

+0

interessante (?), L'esempio dato dal PO non funziona con versione 1.9.5, quando la soluzione @akrun funziona. –

+3

Perché non utilizzare 'rowSums':' DT [is.finite (rowSums (DT))] ' – shadow

risposta

16

È possibile utilizzare rowSums per verificare se nessun elemento di una riga non è finito.

DT[is.finite(rowSums(DT))] 

oppure è possibile utilizzare il fatto che Inf * 0 è NA e utilizzare complete.cases

DT[complete.cases(DT*0)] 

Alcuni di benchmarking mostra che il rowSums è più veloce per la serie di dati più piccoli e complete.cases è la soluzione più rapida per il set di dati di grandi dimensioni.

require(microbenchmark) 
microbenchmark(
    DT[is.finite(rowSums(DT))] 
    , 
    DT[complete.cases(DT*0)] 
    , 
    DT[DT[, Reduce('&', lapply(.SD, is.finite))]] 
) 
## 
## nrow(DT) = 3000 
## Unit: microseconds           
##           expr  min  lq  mean median  uq  max neval cld 
##      DT[is.finite(rowSums(DT))] 786.797 839.235 864.0215 852.8465 884.756 1021.988 100 a 
##      DT[complete.cases(DT * 0)] 1265.658 1326.575 1363.3985 1350.0055 1386.377 1898.040 100 c 
## DT[DT[, Reduce("&", lapply(.SD, is.finite))]] 1220.137 1275.030 1319.6226 1308.0555 1348.443 1624.023 100 b 
## 
## nrow(DT) = 300000 
## Unit: milliseconds 
##           expr  min  lq  mean median  uq  max neval cld 
##      DT[is.finite(rowSums(DT))] 21.617935 22.687452 26.698070 25.75765 26.07942 87.56290 100 c 
##      DT[complete.cases(DT * 0)] 7.209252 7.567393 9.908503 10.17569 10.37473 71.31375 100 a 
## DT[DT[, Reduce("&", lapply(.SD, is.finite))]] 11.786773 12.647652 14.128624 14.78512 15.05089 15.39542 100 b 
Problemi correlati