如何删除R中只包含缺失值的行?

时间:2011-08-25 04:36:24

标签: r

我有一个包含11列和100000行(例如)的大型数据集,其中我有值1,2,3,4。其中4是缺失值。有些行完全丢失了。即所有11列中的4个。例如

"4"  "4"  "4"  "4"  "4"  "4"  "4"  "4"  "4"  "4"   "4"

现在我需要的是只删除那些完全缺失的行。简单来说,我想保留缺少值小于11的行。我使用了na.omit,但它在我的情况下不起作用。

提前致谢。

6 个答案:

答案 0 :(得分:11)

也许你最好的选择是利用R的习语来处理遗漏或NA值。在对NA值进行编码后,您可以使用complete.cases轻松实现目标。

创建一些缺少值的样本数据(即值为4):

set.seed(123)
m <- matrix(sample(1:4, 30, prob=c(0.3, 0.3, 0.3, 0.1), replace=TRUE), ncol=6)
m[4, ] <- rep(4, 6)

将所有等于4的值替换为NA

m[m==4] <- NA
m
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1   NA    2    2    2
[2,]    2    3    3    1    2    3
[3,]    3    2    2    1    2    3
[4,]   NA   NA   NA   NA   NA   NA
[5,]   NA    3    1   NA    2    1

现在,您可以使用各种处理NA值的函数。例如,complete.cases只会返回,您猜对了,完整的情况:

m[complete.cases(m), ]

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    2    3    3    1    2    3
[2,]    3    2    2    1    2    3

有关详细信息,请参阅?complete.cases包中的?na.failstats

答案 1 :(得分:3)

我在其他地方找到了这个解决方案,并在此使用Andrie的代码粘贴它来生成初始数据集。

首先生成数据集:

set.seed(123)
m <- matrix(sample(1:4, 30, prob=c(0.3, 0.3, 0.3, 0.1), replace=TRUE), ncol=6)
m[4, ] <- rep(4, 6)
m[m==4] <- NA
m

这是初始数据集:

1    1    NA   2    2    2
2    3    3    1    2    3
3    2    2    1    2    3
NA   NA   NA   NA   NA   NA
NA   3    1    NA   2    1

现在删除仅包含缺失观察值的行:

m[rowSums(is.na(m))<ncol(m),] 

结果如下:

1    1    NA   2    2    2
2    3    3    1    2    3
3    2    2    1    2    3
NA   3    1    NA   2    1

答案 2 :(得分:2)

真正快速的方法是使用一点点数学。假设您的数据帧名为datf

rsum <- rowSums(datf)
datf <- datf[rowSums != 44,] #11 * 4

(适用于矩阵)

答案 3 :(得分:2)

这是我能想到的最快的解决方案。我将使用类似于@Andrie的示例数据。

set.seed(21)
m <- matrix(sample(1:6, 110, replace=TRUE), ncol=11)
missVal <- 4
m[4, ] <- rep(missVal, 11)
m <- m[ rowSums((m==missVal)) != NCOL(m), ]

最后一行有效,因为m==missVal会返回逻辑(TRUE / FALSE)值的矩阵。 rowSumsTRUE转换为1并将FALSE转换为0,因此在这种情况下,只要4返回11,我们就知道所有列都为rowSums

答案 4 :(得分:2)

使用data.table提高内存效率。创建is.na(x)的解决方案是创建与原始数据集一样大的数据集,因此效率很低。

library(data.table)
DT <- as.data.table(m)
missing_value <- 4
missing <- as.data.table(setNames(as.list(rep(4, length(DT)), names(DT))
setkeyv(DT, names(DT))
setkey(missing, names(DT))

DT[-DT[(missing),which=T]]

这个和@ JoshuaUlrich的解决方案对于大数据都很快

set.seed(21)
m <- matrix(sample(1:6, 1100000, replace=TRUE), ncol=11)
missVal <- 4
missing_rows <- sample(100000, 53)
m[missing_rows, ] <- rep(missVal, 11)

DT <- as.data.table(m)
setkeyv(DT, names(DT))
missing <- setNames(as.list(rep(missVal, 11)), names(DT))

system.time({DT1 <- DT[-DT[missing,which=T]]})
## user  system elapsed 
## 0.02    0.00    0.01 
system.time({m1 <- m[ rowSums((m==missVal)) != NCOL(m), ]})
## user  system elapsed 
## 0.02    0.02    0.03 

答案 5 :(得分:1)

这样的事情可以解决问题(并且应该适用于矩阵和data.frames):

ac<-matrix(c("4","4","4","4","4","4","4","3","3","4","4", rep("4", 11)), nrow=2, ncol=11, byrow=TRUE)

rowsToRemove<-which(apply(ac, 1, function(currow){
    all(currow=="4")
}))

现在你可以简单地做

newac<-ac[-rowsToRemove,]