2015-03-05 27 views
5

Tôi muốn xóa tất cả các hàng của data.table có chứa Inf trong bất kỳ cột nào của nó. Cho đến nay, tôi đã sử dụng phương pháp này:Xóa các hàng có NA khỏi data.table trong 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] 

có nguồn gốc từ this Stackoverflow question. Tuy nhiên, cách tiếp cận này không thể mở rộng tốt với lượng lớn dữ liệu. Có cách nào tốt hơn để xóa các hàng có Inf không?

+2

Có thể 'DT [DT [, Giảm ('&', lapply (.SD, is.finite))]] ' – akrun

+0

Điều thú vị (?), Ví dụ được đưa ra bởi OP không làm việc với phiên bản 1.9.5, khi giải pháp @akrun hoạt động. –

+3

Tại sao không sử dụng 'rowSums':' DT [is.finite (rowSums (DT))] ' – shadow

Trả lời

16

Bạn có thể sử dụng rowSums để kiểm tra xem có yếu tố nào của hàng không hữu hạn hay không.

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

HOẶC bạn có thể sử dụng thực tế là Inf * 0NA và sử dụng complete.cases

DT[complete.cases(DT*0)] 

Một số điểm chuẩn cho thấy rowSums là nhanh nhất cho các tập dữ liệu nhỏ hơn và complete.cases sự là giải pháp nhanh nhất cho các tập dữ liệu lớn hơn.

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 
Các vấn đề liên quan