Eliminar columnas del dataframe donde TODOS los valores son NA

Tengo problemas con un dataframe y no pude resolver ese problema yo mismo:
El dataframe tiene propiedades arbitrarias como columnas y cada fila representa un conjunto de datos .

La pregunta es:
¿Cómo deshacerse de las columnas donde TODAS las filas tienen el valor NA ?

Prueba esto:

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

Los dos enfoques ofrecidos hasta ahora fallan con grandes conjuntos de datos, ya que (entre otros problemas de memoria) crean is.na(df) , que será un objeto del mismo tamaño que df .

Aquí hay dos enfoques que son más eficientes en la memoria y el tiempo

Un enfoque que utiliza el Filter

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

y un enfoque usando data.table (para el tiempo general y la eficiencia de la memoria)

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

ejemplos que usan datos grandes (30 columnas, 1e6 filas)

 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 

Otra forma sería usar la función apply() .

Si tienes el data.frame

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

luego puedes usar apply() para ver qué columnas cumplen tu condición y así puedes simplemente hacer el mismo subconjunto que en la respuesta de Musa, solo con un enfoque de 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 

dplyr ahora tiene un verbo select_if que puede ser útil aquí:

 library(dplyr) temp <- data.frame(x = 1:5, y = c(1,2,NA,4, 5), z = rep(NA, 5)) not_all_na <- function(x) any(!is.na(x)) not_any_na <- function(x) all(!is.na(x)) > temp xyz 1 1 1 NA 2 2 2 NA 3 3 NA NA 4 4 4 NA 5 5 5 NA > temp %>% select_if(not_all_na) xy 1 1 1 2 2 2 3 3 NA 4 4 4 5 5 5 > temp %>% select_if(not_any_na) x 1 1 2 2 3 3 4 4 5 5 
 df[sapply(df, function(x) all(is.na(x)))] <- NULL 

Espero que esto también pueda ayudar. Podría convertirse en un solo comando, pero me resultó más fácil leer dividiéndolo en dos comandos. Hice una función con las siguientes instrucciones y trabajé rápido como un rayo.

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

.SD permitirá limitar la verificación a una parte de la tabla, si lo desea, pero tomará toda la tabla como