Les deux approches proposées jusqu'à présent échouent avec de grands ensembles de données car (entre autres problèmes de mémoire) ils créent is.na(df)
, qui sera un objet de la même taille que df
.
Voici deux approches plus efficaces en termes de mémoire et de temps
Une approche utilisant Filter
Filter(function(x)!all(is.na(x)), df)
et une approche utilisant data.table (pour le temps général et l'efficacité de la mémoire)
library(data.table)
DT <- as.data.table(df)
DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F]
exemples utilisant des données volumineuses (30 colonnes, 1e6 lignes)
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