我有一个包含11列和100000行(例如)的大型数据集,其中我有值1,2,3,4。其中4是缺失值。有些行完全丢失了。即所有11列中的4个。例如
"4" "4" "4" "4" "4" "4" "4" "4" "4" "4" "4"
现在我需要的是只删除那些完全缺失的行。简单来说,我想保留缺少值小于11的行。我使用了na.omit,但它在我的情况下不起作用。
提前致谢。
答案 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.fail
或stats
。
答案 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
)值的矩阵。 rowSums
将TRUE
转换为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,]