在 dplyr 中按组过滤多个条件的条件 IF

Posted

技术标签:

【中文标题】在 dplyr 中按组过滤多个条件的条件 IF【英文标题】:conditional IF to filter with multiple conditions by group in dplyr 【发布时间】:2019-10-20 10:45:07 【问题描述】:

所以我有 LARGE 数据集,但需要实现一个复杂的数据过滤系统。我想我可以使用 dplyr 和 group_by 但我遇到了如何在组内实现 IF 语句的问题。

这是我尝试并认为可行的方法,但我认为索引可能存在问题,因此每组获得多个 TRUE/FALSE。我不确定如何在每个组中建立索引。

例如在下面的示例中, 如果组 GP 包含字符串“a”,则保留 Var4 等于 J 或 J1 的任何记录(对于那个我可以做“包含字母“J”的记录),但如果组 GP 包含字符串“b " 并且还有字符串“2”(这里也是一个简单的数字,但实际上它是所有内容的字符串和数字的组合),然后如果为“J”,则保留 Var4 的记录,但如果组 GP 包含字符串“b”并且还有字符串“3”,然后记录 Var4 如果“U”......这里有这个例子中的案例,但最终我给出了我需要应用的规则,我将有 300+那些“如果团队有这些品质,那么就保留这些记录”。

testing <- data.frame(var1 = c("a", "a", "b", "b","a", "a","b", "b"),
                      var2 = c(1, 1, 2, 2, 1, 1, 3, 3),
                      var3 = c("A", "A", "A", "A","B", "B","B", "B"),
                      var4 = c("U", "J", "J", "A", "1", "J1", "U", "A"))
testing$GP <- paste(testing$var1,testing$var2, testing$var3, sep = "-")
cleaned <- testing %>% 
  group_by("GP") %>% 
  if (grepl("a", testing$GP))
    filter(testing, testing$var4 == "J" | testing, testing$var4 == "J1")
   else if  (grepl("b", testing$GP) & grepl("2", testing$GP))
    filter(testing, testing$var4 == "J")
   else if  (grepl("b", testing$GP) & grepl("3", testing$GP))
    filter(testing, testing$var4 == "U")
  

最终我想要一个与下面等效的结果,但有 100000 条记录并且能够构建我需要的 300 个条件(“Joy”;-P)

  var1 var2 var3 var4    GP
1    a    1    A    U a-1-A
3    b    2    A    J b-2-A
6    a    1    B   J1 a-1-B
7    b    3    B    U b-3-B

我需要它能够根据应用于三个变量的条件有条件地过滤掉大量数据。例如,对于每个单独的三个变量的唯一组(例如,如果查找最后一组,则为 b-3-B),我需要保留适合结果的记录(例如“U”),但前提是满足某些条件(例如“GP”包含字符串“b”和字符串“3”)。但我必须为 300 个有时具有复杂 IF 语句的不同组执行此操作(例如,对于 GP,如果“GP”包含某些字符串“EG”,则在第 4 个变量中保留结果为“U”的记录,但如果它有字符串“RT”然后在第 4 个变量中保留“J”的记录...

谢谢。 萨布

【问题讨论】:

第一篇文章做得很好。我建议在代码之外单独描述您的条件,这样人们就不必猜测您需要什么。您的尝试可能与您的实际需要大相径庭,从而导致人们误入歧途。 你能用语言描述你想要做什么吗? testing$wierdID 也不见了。 @markus,谢谢,我已经更新了代码。这就是我在原始数据集中调用的“GP”变量。 @Shree 我需要什么才能根据应用于三个变量的条件有条件地过滤掉大量数据。例如,我需要为每个单独的三个变量的唯一组(例如 b-3-B)保留符合结果的记录(例如“U”),但前提是满足某些条件(例如“ GP”包含字符串“b”和字符串“3”) @SabP 只需在原始帖子中列出您的条件即可。这样你会更快地得到帮助。如果太多,则至少列出一些并描述模式(如果有)。 【参考方案1】:

我希望您可以结合某些条件并减少一些多余的输入。

对于给定的示例,我们可以使用grepl 语句与&amp;| 运算符的组合来包含各种条件组合。希望您能够根据您的要求进一步扩展它。

library(dplyr)

testing %>%
  filter(grepl("a", GP) & grepl("J|J1", var4) | 
         grepl("b", GP) & grepl("2", GP) & grepl("J", var4) |
         grepl("b", GP) & grepl("3", GP) & grepl("U", var4))


#  var1   var2 var3  var4  GP   
# <fct>  <dbl> <fct> <fct> <chr>
#1 a         1 A     J     a-1-A
#2 b         2 A     J     b-2-A
#3 a         1 B     J1    a-1-B
#4 b         3 B     U     b-3-B

或使用相同的条件直接在基础 R 中设置子集

testing[with(testing,grepl("a", GP) & grepl("J|J1", var4) | 
                     grepl("b", GP) & grepl("2", GP) & grepl("J", var4) |
                     grepl("b", GP) & grepl("3", GP) & grepl("U", var4)), ]

【讨论】:

谢谢,但是条件会根据前三个变量的唯一组合的集合而变化;因此我试图让它适用于 group_by @SabP 但如果您的条件遵循相同的模式,您可以将它们添加到另一个下方,如示例中的 3 个所示?最终,您需要过滤行而不考虑组,对吗?至少组在所示示例中没有任何作用。 谢谢。我需要重新检查给我的条件;因为它们是根据组给我的,例如如果在 Var1:3 的每组中,如果 Var1 == X1,并且为 Var4 列出的可能性是 Z1 或 Z2,则保留 Z2,但如果它们是 Z1 或 Z3,然后保持Z1。我的猜测是,条件会根据 Var1-var3 组合而改变,因为它们是这样给我的。 我验证过,它确实取决于每组 var4 的选项/选择。对于大多数组,您提供的上面的简化代码会起作用,因为对于特定的 var1,它始终是 var4 中相同的选择组合,但并非总是如此。例如,在我上面的示例中,这里选择了 J 选项的一种形式,但是如果 var1:3 的组合存在比 J“更好”的东西,那么我应该抓住那个而不是 J。

以上是关于在 dplyr 中按组过滤多个条件的条件 IF的主要内容,如果未能解决你的问题,请参考以下文章

在Javascript中按多个条件过滤数组

如何在 Flask SQLAlchemy 中按多个条件进行过滤?

dplyr - 按组大小过滤

R语言dplyr包filter函数通过逻辑条件过滤数据实战

在 Shiny 的反应函数中使用 dplyr 条件过滤器

Django,在模型外键中按组过滤用户