在data.frame中使用dplyr过滤全部案例(逐案删除)

是否有可能使用dplyr过滤完整个案的data.frame? complete.cases一个包含所有variables的列表。 但是,这是a)详细的时候有很多的variables,b)当variables名称是不可知的(例如在一个函数,处理任何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)) 

尝试这个:

 df %>% na.omit 

或这个:

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

已更新以反映最新版本的dplyr和评论。

这适用于我:

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

或者更一般一点:

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

这样做的好处是数据可以在链中传递给filter之前进行修改。

与更多专栏的另一个基准:

 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 

这是一个简短的函数,它可以让你指定不应该有任何NA值(在pandas df.dropna()之后build模)的列(基本上dplyr::select可以理解的所有东西):

 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现在是tidyr的一部分 :上面可以replace为library("tidyr") ]

例子:

 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 

尝试这个

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

甚至这个

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

上述命令负责检查data.frame中所有列(variables)的完整性。

以下是格洛腾迪克答复的一些基准结果。 na.omit()比其他两个解决scheme花费的时间要多20倍。 如果dplyr有一个函数可能作为filter的一部分,我认为这将是很好的。

 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 

只是为了完整性, dplyr::filter可以完全避免,但是仍然可以通过使用magrittr:extract (一个别名为[

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

额外的好处是速度,这是filterna.omit变种中最快的方法(使用@MihaTroštmicrobenchmarks进行testing)。