175 votes

Supprimer les colonnes de la structure de données où TOUTES les valeurs sont NA

J'ai des problèmes avec une trame de données et je ne pouvais pas résoudre ce problème moi-même:
La structure de données a des propriétés arbitraires en tant que colonnes et chaque ligne représente un ensemble de données .

La question est:
Comment se débarrasser des colonnes où, pour TOUTES les lignes, la valeur est NA ?

Quelqu'un pourrait-il s'il vous plaît aider?

181voto

teucer Points 1877

Essaye ça:

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

116voto

mnel Points 48160

Les deux approches proposées jusqu'à présent échouer avec de grands ensembles de données, comme (entre autres des problèmes de mémoire) qu'ils créent is.na(df), qui seront un objet de la même taille que df.

Voici deux approches qui sont plus de mémoire et de temps efficace

Une approche à l'aide de Filter

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

et une approche utilisant des données.tableau (pour le temps et l'efficacité de mémoire)

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

des exemples d'utilisation de données de grande taille (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 

15voto

mropa Points 2813

Une autre solution consiste à utiliser la fonction apply() .

Si vous avez le data.frame

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

alors vous pouvez utiliser apply() pour voir quelles colonnes remplissent votre condition et vous pouvez simplement faire le même sous-ensemble que dans la réponse de Musa, uniquement avec une approche 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
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X