从所有值为NA的数据框中删除列

我遇到了一个数据框的问题,我自己也无法真正解决这个问题:
dataframe具有任意属性作为列每行代表一个数据集

问题是:
如何摆脱所有行的值为NA的列

尝试这个:

df <- df[,colSums(is.na(df))<nrow(df)] 

到目前为止,提供的两种方法在大数据集中失败,因为它们创build的是(其他内存问题)是is.na(df) ,它将是一个与df大小相同的对象。

以下是两种更具记忆力和时间效率的方法

一种使用Filter的方法

 Filter(function(x)!all(is.na(x)), df) 

和一个使用data.table(一般时间和内存效率)的方法

 library(data.table) DT <- as.data.table(df) DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F] 

使用大数据的例子(30列,1e6行)

 big_data <- replicate(10, data.frame(rep(NA, 1e6), sample(c(1:8,NA),1e6,T), sample(250,1e6,T)),simplify=F) bd <- do.call(data.frame,big_data) names(bd) <- paste0('X',seq_len(30)) DT <- as.data.table(bd) system.time({df1 <- bd[,colSums(is.na(bd) < nrow(bd))]}) # error -- can't allocate vector of size ... system.time({df2 <- bd[, !apply(is.na(bd), 2, all)]}) # error -- can't allocate vector of size ... system.time({df3 <- Filter(function(x)!all(is.na(x)), bd)}) ## user system elapsed ## 0.26 0.03 0.29 system.time({DT1 <- DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F]}) ## user system elapsed ## 0.14 0.03 0.18 

另一种方法是使用apply()函数。

如果你有data.frame

 df <- data.frame (var1 = c(1:7,NA), var2 = c(1,2,1,3,4,NA,NA,9), var3 = c(NA) ) 

那么你可以使用apply()来查看哪些列满足你的条件,所以你可以简单地做与Musa的答案相同的子集,只需要一个apply方法。

 > !apply (is.na(df), 2, all) var1 var2 var3 TRUE TRUE FALSE > df[, !apply(is.na(df), 2, all)] var1 var2 1 1 1 2 2 2 3 3 1 4 4 3 5 5 4 6 6 NA 7 7 NA 8 NA 9 

我希望这也可以帮助。 它可以做成一个单一的命令,但是我发现通过将它分成两个命令使我更容易阅读。 我用下面的说明做了一个function,并且快速地工作。

naColsRemoval = function (DataTable) { na.cols = DataTable [ , .( which ( apply ( is.na ( .SD ) , 2 , all ) ) )] DataTable [ , unlist (na.cols) := NULL , with = F] }

.SD将允许将validation限制在表的一部分,如果你愿意的话,但它会把整个表作为

 df[sapply(df, function(x) all(is.na(x)))] <- NULL