filtrar por casos completos en data.frame utilizando dplyr (eliminación de mayúsculas y minúsculas)

¿Es posible filtrar un data.frame para casos completos usando dplyr? complete.cases con una lista de todas las variables funciona, por supuesto. Pero eso es a) detallado cuando hay muchas variables yb) imposible cuando los nombres de las variables no se conocen (por ejemplo, en una función que procesa cualquier data.frame).

 library(dplyr) df = data.frame( x1 = c(1,2,3,NA), x2 = c(1,2,NA,5) ) df %.% filter(complete.cases(x1,x2)) 

Prueba esto:

 df %>% na.omit 

o esto:

 df %>% filter(complete.cases(.)) 

o esto:

 library(tidyr) df %>% drop_na 

Si desea filtrar en función de la falta de una variable, use un condicional:

 df %>% filter(!is.na(x1)) 

o

 df %>% drop_na(x1) 

Otras respuestas indican que las soluciones anteriores a na.omit son mucho más lentas, pero tienen que na.omit contra el hecho de que devuelve y fila los índices de las filas omitidas como el atributo na.action mientras que las otras soluciones anteriores no lo hacen.

 str(df %>% na.omit) ## 'data.frame': 2 obs. of 2 variables: ## $ x1: num 1 2 ## $ x2: num 1 2 ## - attr(*, "na.action")= 'omit' Named int 3 4 ## ..- attr(*, "names")= chr "3" "4" 

AÑADIDO Se ha actualizado para reflejar la última versión de dplyr y comentarios.

AÑADIDO Se ha actualizado para reflejar la última versión de tidyr y comentarios.

Esto funciona para mí:

 df %>% filter(complete.cases(df)) 

O un poco más general:

 library(dplyr) # 0.4 df %>% filter(complete.cases(.)) 

Esto tendría la ventaja de que los datos podrían haberse modificado en la cadena antes de pasarlos al filtro.

Otro punto de referencia con más columnas:

 set.seed(123) x <- sample(1e5,1e5*26, replace = TRUE) x[sample(seq_along(x), 1e3)] <- NA df <- as.data.frame(matrix(x, ncol = 26)) library(microbenchmark) microbenchmark( na.omit = {df %>% na.omit}, filter.anonymous = {df %>% (function(x) filter(x, complete.cases(x)))}, rowSums = {df %>% filter(rowSums(is.na(.)) == 0L)}, filter = {df %>% filter(complete.cases(.))}, times = 20L, unit = "relative") #Unit: relative # expr min lq median uq max neval # na.omit 12.252048 11.248707 11.327005 11.0623422 12.823233 20 #filter.anonymous 1.149305 1.022891 1.013779 0.9948659 4.668691 20 # rowSums 2.281002 2.377807 2.420615 2.3467519 5.223077 20 # filter 1.000000 1.000000 1.000000 1.0000000 1.000000 20 

Aquí hay algunos resultados de referencia para la respuesta de Grothendieck. na.omit () toma 20 veces más tiempo que las otras dos soluciones. Creo que sería bueno si dplyr tuviera una función para esto tal vez como parte del filtro.

 library('rbenchmark') library('dplyr') n = 5e6 n.na = 100000 df = data.frame( x1 = sample(1:10, n, replace=TRUE), x2 = sample(1:10, n, replace=TRUE) ) df$x1[sample(1:n, n.na)] = NA df$x2[sample(1:n, n.na)] = NA benchmark( df %>% filter(complete.cases(x1,x2)), df %>% na.omit(), df %>% (function(x) filter(x, complete.cases(x)))() , replications=50) # test replications elapsed relative # 3 df %.% (function(x) filter(x, complete.cases(x)))() 50 5.422 1.000 # 1 df %.% filter(complete.cases(x1, x2)) 50 6.262 1.155 # 2 df %.% na.omit() 50 109.618 20.217 

Esta es una función corta que le permite especificar columnas (básicamente todo lo que dplyr::select puede comprender) que no debe tener ningún valor NA (modelado después de pandas df.dropna () ):

 drop_na <- function(data, ...){ if (missing(...)){ f = complete.cases(data) } else { f <- complete.cases(select_(data, .dots = lazyeval::lazy_dots(...))) } filter(data, f) } 

[ drop_na ahora es parte de tidyr : lo anterior puede ser reemplazado por library("tidyr") ]

Ejemplos:

 library("dplyr") df <- data.frame(a=c(1,2,3,4,NA), b=c(NA,1,2,3,4), ac=c(1,2,NA,3,4)) df %>% drop_na(a,b) df %>% drop_na(starts_with("a")) df %>% drop_na() # drops all rows with NAs 

prueba esto

 df[complete.cases(df),] #output to console 

O incluso esto

 df.complete <- df[complete.cases(df),] #assign to a new data.frame 

Los comandos anteriores se encargan de verificar la integridad de todas las columnas (variables) en su data.frame.

Solo para completar, dplyr::filter puede evitarse por completo, pero aún así ser capaz de componer cadenas usando solo magrittr:extract (un alias de [ ):

 library(magrittr) df = data.frame( x1 = c(1,2,3,NA), x2 = c(1,2,NA,5)) df %>% extract(complete.cases(.), ) 

La ventaja adicional es la velocidad, este es el método más rápido entre las variantes de filter y na.omit (probadas usando @Miha Trošt microbenchmarks).