首页 > 解决方案 > 多个 if 语句来定义在 R 中应用和忽略哪些过滤器

问题描述

我搜索了与此问题相关的各种帖子,但仍然找不到解决方案。

我正在尝试在涉及 if() 语句的数据帧上应用多个过滤器,如果满足条件,则它在过滤器集中包含 {} 内的单个过滤器,如果不满足该语句,则忽略该特定筛选。考虑以下可以完美运行的基本代码,尽管它还没有包含 if 语句。

library(tidyverse)
llibrary(purrr)
library(dplyr)

Cb1 <- 0.75
Cb2 <- 1.0
Cb3 <- 20
Cb4 <- 8

test <- map(metrics, ~filter(., 
                             industry == "Technology",
                             price <= (median(price, na.rm = TRUE)) * Cb1,
                             ror >= (median(ror, na.rm = TRUE)) * Cb2,
                             debt <= Cb3,
                             periods >= Cb4,
                             price >= 0)) 

该代码引用了一个名为“指标”的 3 个数据框列表,为简单起见,我没有将其包含在代码中(这意味着您将无法测试此代码)。但它包含大量数据列,其中一些包括:行业、价格、债务、期间和风险。哪些是我有兴趣过滤的列。请注意,这包括一个地图功能,因为它正在对列表“指标”中包含的 3 个数据帧执行过滤,但这在我的问题中并不重要。

我想添加一些 if 语句来检查常量 Cb 是否不等于 0,然后 {} 中的过滤器包含在多个过滤器的集合中。但是如果常数 Cb 等于 0,那么这个特定的过滤器将被排除在多组过滤器中(并且其他过滤器仍然可能适用)。通过一些研究,我认为也许在 {} 之后使用“else”并且在“else”之后没有任何内容可以实现我正在寻找的东西。但它不起作用。这是我尝试在过滤器函数中使用 if 语句的代码,但这同样不起作用。为了澄清,代码运行没有错误,但过滤器不能正常工作。

Cb1 <- 0.75
Cb2 <- 0
Cb3 <- 20
Cb4 <- 8

test <- map(metrics, ~filter(., 
                                industry == "Technology",
                                if(Cb1 != 0) {price <= (median(price, na.rm = TRUE)) * Cb1} else
                                if(Cb2 != 0) {ror >= (median(ror, na.rm = TRUE)) * Cb2} else
                                if(Cb3 != 0) {debt <= Cb3} else
                                if(Cb4 != 0) {periods >= Cb4} else
                                price >= 0)) 

我觉得这是一些相对简单的东西,比如我放置 {}、() 甚至逗号的语法。或者它可能是布尔运算符(& 或 |)的某种组合。但我似乎无法让它工作。请注意,还有一些过滤器不包含 if 检查,因为我希望它们始终适用。

我通常会尝试包含预期的结果,但这很困难,因为这是我无法包含的数据帧上的一组过滤器。我希望有人可以在 if 语句代码中帮助我的语法,这将解决问题。

任何帮助表示赞赏!

标签: rif-statementfilter

解决方案


filter()函数期望它的每个输入都是一个逻辑向量,长度等于数据帧的行数或 1。“排除”过滤器可能意味着过滤器始终解析为TRUE,将所有行保留在原位。

所以你可以把你的陈述改成这样(注意最后的逗号):

if (Cb1 != 0) { price <= (median(price, na.rm = TRUE)) * Cb1 } else TRUE,

不过我有一个评论:你在这里做的事情感觉有点违反直觉。也许如果你能更好地描述你为什么要这样做,可能会有一个更像 dplyr 的解决方案。


推荐阅读