首页 > 解决方案 > R: dplyr::filter 中的 IF 语句需要 ELSE 否则会失败?

问题描述

根据其他答案,可以if在管道和dplyr函数中包含语句。但是对于filter,似乎需要使用 anelse而不仅仅是 an if,否则filter将不返回任何内容,并调用错误:

没有适用于“过滤器_”的方法应用于“NULL”类的对象

恕我直言,这是相当误导的,因为我没有使用filter_并且没有亲自为管道提供 NULL 类对象。最小代表:

data(mtcars)
a <- 1
mtcars %>% filter(if (a == 1) cyl == 6) # if in filter works
a <- NA
mtcars %>% filter(if (is.na(a)) cyl == 6) # is.na in if in filter works if it evaluates to true
a <- 4
mtcars %>% filter(if (!is.na(a)) cyl == a) # !is.na works if it evaluates to true
a <- NA
mtcars %>% filter(if (!is.na(a)) cyl == a) # doesn't work if it evaluates to false
# Input `..1` must be of size 32 or 1, not size 0.

通过选择将包含所有结果的过滤器约束,可以使用 else 从过滤器生成输出。

mtcars %>% filter(if (!is.na(a)) cyl == a else carb > 0

可能有一个更好的包罗万象的过滤器约束,实际上可能是一种更优雅的方式来做这件事,但我找不到其他人发现这个问题,所以如果没有别的,希望我的进步能达到它的正常目的

任何关于这是否是一个错误或其他方法来解决这个问题的情报,都非常受欢迎。谢谢。

标签: rif-statementfilterdplyr

解决方案


我们可以TRUEelse条件中返回,这将选择所有行,以防条件FALSE依赖和不依赖于我们正在测试的列中的值。

library(dplyr)
a <- NA
mtcars %>% filter(if(!is.na(a)) cyl == a else TRUE)

并回答你的问题,是if的需要else部分,因为没有它,它只会返回NULL,而filter. 看这个例子:

num <- 2
a <- if(num > 1) 'yes'
a
#[1] "yes"
a <- if(num > 3) 'yes'
a
#NULL

因此,当您使用

a <- NA
mtcars %>% filter(if(!is.na(a)) cyl == a)

实际发生的是

mtcars %>% filter(NULL)

它返回相同的错误消息。


推荐阅读