Dplyr filter_if出现较大的中断

时间:2019-07-19 02:39:06

标签: r dplyr

我有一个小标题,有7000行和10000列。如果行中所有列中至少有一个非零元素,我想对其进行过滤。我写了下面的代码,可以很好地解决小问题。一旦增加列数,它就会中断

谁能告诉我故障在哪里?

谢谢。

library(tidyverse)
ncol = 10000
nrow = 7000

rr = sample(c(0,1) , nrow * ncol , replace = TRUE) %>% 
  matrix(ncol = ncol) %>% 
  as.data.frame() %>% 
  as_tibble()

rr %>% dplyr::filter_if(is.numeric , .vars_predicate = any_vars(. != 0 ))
#> Error: evaluation nested too deeply: infinite recursion / options(expressions=)?

reprex package(v0.3.0)于2019-07-19创建

2 个答案:

答案 0 :(得分:1)

当您具有4953列和任何(甚至很少)行数时,代码将失败。如果您阅读该错误消息,则会提及options(expressions=)。将此值设置为更大的值即可修复它。默认情况下为5000。我不知道其他47个嵌套表达式来自何处,但是:

使用默认设置:

> options(expressions=5000)

和4953列,10行的数据集:

> dim(rrf)
[1]   10 4953

失败。...

> rrf %>% dplyr::filter_if(is.numeric , .vars_predicate = any_vars(. != 0 ))
Error in filter_impl(.data, quo) : 
  Evaluation error: evaluation nested too deeply: infinite recursion / options(expressions=)?.

因此,如错误消息中明确指出的那样,请尝试设置表达式选项:

> options(expressions=6000)

shazam起作用了

> rrf %>% dplyr::filter_if(is.numeric , .vars_predicate = any_vars(. != 0 )) %>% nrow
[1] 10

(我刚刚将其通过管道传送到nrow中,但可以正常工作,并且无法打印所有列)。

答案 1 :(得分:0)

您不需要tidyverse进行过滤。为此使用矩阵子集。我认为在过滤之前转换为tibble只会减慢处理速度,并在您的情况下造成不必要的开销,因为在这种情况下,您所有的数据都是mode数字和矩阵运算都足够快。您可以将它变成一些小词。

rr = matrix(sample(0:1 , nrow * ncol , replace = TRUE, 
            prob = c(.99999, .00001)), nrow = nrow, ncol =ncol)
keep <- rr[rowSums(rr) !=0,] # if there are nonzero elements 
                      # rowSums(rr)!= 0 is TRUE 
dim(keep) # shows that most rows were dropped
[1]   669 10000

summary(rowSums(keep)) # show that there are no lines full of zeros in keep
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   1.000   1.000   1.061   1.000   3.000

keep <- as_tibble(keep)