Tengo un data.frame que contiene algunas columnas con todos los valores NA, ¿cómo puedo eliminarlas del data.frame?
¿Puedo usar la función?
na.omit(...)
especificando algunos argumentos adicionales?
Tengo un data.frame que contiene algunas columnas con todos los valores NA, ¿cómo puedo eliminarlas del data.frame?
¿Puedo usar la función?
na.omit(...)
especificando algunos argumentos adicionales?
head(data)
? ¿Quiere eliminar las columnas o filas correspondientes?
Respuestas:
Una forma de hacerlo:
df[, colSums(is.na(df)) != nrow(df)]
Si el recuento de NA en una columna es igual al número de filas, debe ser totalmente NA.
O de manera similar
df[colSums(!is.na(df)) > 0]
df[, colSums(is.na(df)) < nrow(df) * 0.5]
ejemplo, mantener solo columnas con al menos un 50% de espacios en blanco.
df[, colSums(is.na(df)) != nrow(df) - 1]
ya que la diagonal es siempre1
df %>% select_if(colSums(!is.na(.)) > 0)
Aquí hay una solución dplyr:
df %>% select_if(~sum(!is.na(.)) > 0)
janitor::remove_empty_cols()
está en desuso - usedf <- janitor::remove_empty(df, which = "cols")
Parece que desea eliminar SOLO columnas con TODAS las NA
s, dejando columnas con algunas filas que tienen NA
s. Haría esto (pero estoy seguro de que hay una solución vectorizada eficiente:
#set seed for reproducibility
set.seed <- 103
df <- data.frame( id = 1:10 , nas = rep( NA , 10 ) , vals = sample( c( 1:3 , NA ) , 10 , repl = TRUE ) )
df
# id nas vals
# 1 1 NA NA
# 2 2 NA 2
# 3 3 NA 1
# 4 4 NA 2
# 5 5 NA 2
# 6 6 NA 3
# 7 7 NA 2
# 8 8 NA 3
# 9 9 NA 3
# 10 10 NA 2
#Use this command to remove columns that are entirely NA values, it will elave columns where only some vlaues are NA
df[ , ! apply( df , 2 , function(x) all(is.na(x)) ) ]
# id vals
# 1 1 NA
# 2 2 2
# 3 3 1
# 4 4 2
# 5 5 2
# 6 6 3
# 7 7 2
# 8 8 3
# 9 9 3
# 10 10 2
Si se encuentra en la situación en la que desea eliminar columnas que tienen algún NA
valor, simplemente puede cambiar el all
comando anterior a any
.
NA
.
apply(is.na(df), 1, all)
embargo, lo haría solo porque es un poco más ordenado y is.na()
se usa en todas en df
lugar de en una fila a la vez (demuestre ser un poco más rápido).
Una secuencia de comandos intuitiva: dplyr::select_if(~!all(is.na(.)))
. Literalmente mantiene solo las columnas que faltan no todos los elementos. (para eliminar las columnas que faltan todos los elementos).
> df <- data.frame( id = 1:10 , nas = rep( NA , 10 ) , vals = sample( c( 1:3 , NA ) , 10 , repl = TRUE ) )
> df %>% glimpse()
Observations: 10
Variables: 3
$ id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
$ nas <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA
$ vals <int> NA, 1, 1, NA, 1, 1, 1, 2, 3, NA
> df %>% select_if(~!all(is.na(.)))
id vals
1 1 NA
2 2 1
3 3 1
4 4 NA
5 5 1
6 6 1
7 7 1
8 8 2
9 9 3
10 10 NA
Como el rendimiento era realmente importante para mí, comparé todas las funciones anteriores.
NOTA: Datos de la publicación de @Simon O'Hanlon. Solo con el tamaño 15000 en lugar de 10.
library(tidyverse)
library(microbenchmark)
set.seed(123)
df <- data.frame(id = 1:15000,
nas = rep(NA, 15000),
vals = sample(c(1:3, NA), 15000,
repl = TRUE))
df
MadSconeF1 <- function(x) x[, colSums(is.na(x)) != nrow(x)]
MadSconeF2 <- function(x) x[colSums(!is.na(x)) > 0]
BradCannell <- function(x) x %>% select_if(~sum(!is.na(.)) > 0)
SimonOHanlon <- function(x) x[ , !apply(x, 2 ,function(y) all(is.na(y)))]
jsta <- function(x) janitor::remove_empty(x)
SiboJiang <- function(x) x %>% dplyr::select_if(~!all(is.na(.)))
akrun <- function(x) Filter(function(y) !all(is.na(y)), x)
mbm <- microbenchmark(
"MadSconeF1" = {MadSconeF1(df)},
"MadSconeF2" = {MadSconeF2(df)},
"BradCannell" = {BradCannell(df)},
"SimonOHanlon" = {SimonOHanlon(df)},
"SiboJiang" = {SiboJiang(df)},
"jsta" = {jsta(df)},
"akrun" = {akrun(df)},
times = 1000)
mbm
Resultados:
Unit: microseconds
expr min lq mean median uq max neval cld
MadSconeF1 154.5 178.35 257.9396 196.05 219.25 5001.0 1000 a
MadSconeF2 180.4 209.75 281.2541 226.40 251.05 6322.1 1000 a
BradCannell 2579.4 2884.90 3330.3700 3059.45 3379.30 33667.3 1000 d
SimonOHanlon 511.0 565.00 943.3089 586.45 623.65 210338.4 1000 b
SiboJiang 2558.1 2853.05 3377.6702 3010.30 3310.00 89718.0 1000 d
jsta 1544.8 1652.45 2031.5065 1706.05 1872.65 11594.9 1000 c
akrun 93.8 111.60 139.9482 121.90 135.45 3851.2 1000 a
autoplot(mbm)
mbm %>%
tbl_df() %>%
ggplot(aes(sample = time)) +
stat_qq() +
stat_qq_line() +
facet_wrap(~expr, scales = "free")