【问题标题】:Filter by testing logical condition across multiple columns通过跨多列测试逻辑条件进行过滤
【发布时间】:2018-05-24 06:01:25
【问题描述】:

dplyr 中是否有一个函数允许您针对选择的列测试相同的条件?

获取以下数据框:

Demo1 <- c(8,9,10,11)
Demo2 <- c(13,14,15,16)
Condition <- c('A', 'A', 'B', 'B')
Var1 <- c(13,76,105,64)
Var2 <- c(12,101,23,23)
Var3 <- c(5,5,5,5)

df <- as.data.frame(cbind(Demo1, Demo2, Condition, Var1, Var2, Var3), stringsAsFactors = F)
df[4:6] <- lapply(df[4:6], as.numeric)

我想取出 Var1、Var2 或 Var3 中至少有一个大于 100 的所有行。我意识到我可以使用一系列 or 语句来做到这一点,如下所示:

df <- df %>% 
  filter(Var1 > 100 | Var2 > 100 | Var3 > 100)

但是,由于我的实际数据集中有很多列,因此这将非常耗时。我假设有一些相当简单的方法可以做到这一点,但无法在 SO 上找到解决方案。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以通过filter_atany_vars 做到这一点

    df %>% 
      filter_at(vars(matches("^Var")), any_vars(.> 100))
    #   Demo1 Demo2 Condition Var1 Var2 Var3
    #1     9    14         A   76  101    5
    #2    10    15         B  105   23    5
    

    或者使用base R,创建一个包含lapplyReduce 的逻辑表达式并对行进行子集化

    df[Reduce(`|`, lapply(df[grepl("^Var", names(df))], `>`, 100)),]
    

    【讨论】:

    • df %&gt;% filter_if(str_detect(colnames(.), "^Var"), any_vars(. &gt; 100)) 也可以使用
    • df %&gt;% filter_at(vars(starts_with("Var")), any_vars(.&gt; 100)) 更像是一个基于dplyr 的选项。
    • 谢谢,所有这些答案和 cmets 都很有用。
    【解决方案2】:

    base-R 中,可以使用rowSums 编写相同的过滤器:

    df[rowSums((df[,grepl("^Var",names(df))] > 100)) >= 1, ]
    
    #   Demo1 Demo2 Condition Var1 Var2 Var3
    # 2     9    14         A   76  101    5
    # 3    10    15         B  105   23    5
    

    【讨论】:

      猜你喜欢
      • 2022-01-10
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多