首页 > 解决方案 > Dplyr filter_if 以大 tibble 中断

问题描述

我有一个有 7000 行和 10000 列的大标题。如果所有列中至少有一个非零元素,我想过滤行。我编写了以下代码,它在小 tibble 上运行良好。一旦我增加列数,它就会中断

谁能告诉故障在哪里?

谢谢。

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 包(v0.3.0)于 2019 年 7 月 19 日创建

标签: rdplyr

解决方案


当您有 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以获得有效且不打印所有列的东西)。


推荐阅读