r - 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 日创建
解决方案
当您有 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
以获得有效且不打印所有列的东西)。