【问题标题】:Filtering/subsetting in R applied to multiple columnsR中的过滤/子集应用于多列
【发布时间】:2016-09-23 12:30:06
【问题描述】:
Index   odx1    odx2    odx3    odx4    odx5
1       123     0       0       0       0
2       0       321     0       0       0
3       0       0       0       123     0
4       0       321     0       0       0
5       0       0       0       0       0

我在上面附上了我的数据集示例。我想过滤 R 中的多个列,以子集包含例如 123 或 321 的数据集。

到目前为止,我尝试的是使用 dplyr -

df %>% filter(., odx1==123 | odx2==123 | odx3==123 | odx4==123 | odx5==123 | odx1==321| odx2==321| odx3==321| odx4==321| odx5==321)

虽然上述方法可行,但是否有更简洁、更简化的方法来执行此操作?

我的实际数据集包含 odx1-odx25,我有一个包含大约 15 个字符串的列表,用于过滤大约 100K 行。

编辑:

实际的数据集包含随机的数字字符串,但我只是使用 0 来作为示例以提高可见性和简单性。

Index   odx1    odx2    odx3    odx4    odx5
1       123     421     532     414     981
2       243     321     765     132     321
3       144     322     587     123     444
4       655     321     459     091     676
5       456     421     523     431     768

【问题讨论】:

  • df[rowSums(df == 123 | df == 321) > 0, ]怎么样
  • 如果数据始终采用这种通用格式(只是想摆脱由所有0s 组成的观察结果,那么更快一点(就击键和计算时间而言)解决方案将是:df[rowSums(df!=0)!=0,]

标签: r filter dplyr subset


【解决方案1】:

基础包:

df[apply(df, 1, function(x) {any(x == 123 | x == 321)}),]

dplyr

library(dplyr)
filter(df, rowSums(mutate_each(df, funs(. %in% c(123, 321)))) >= 1L)

输出:

  Index odx1 odx2 odx3 odx4 odx5
1     1  123    0    0    0    0
2     2    0  321    0    0    0
3     3    0    0    0  123    0
4     4    0  321    0    0    0

【讨论】:

    【解决方案2】:

    正如我的评论:

    如果数据始终采用这种通用格式(只是想摆脱由全 0 组成的观察结果,那么更快(就击键和计算时间而言)的解决方案将是:

    df[rowSums(df[, -1]!=0)!=0,]
    

    【讨论】:

    • 你需要排除索引列,所以rowSums中的df[, -1]?另外,如果速度是关键,system.time(df[rowSums(df[, -1]) != 0, ]); user system elapsed 2.744 0.798 3.894 system.time(df[rowSums(df!=0)!=0,]) user system elapsed 5.086 1.617 6.939
    • 你是对的。在我的脑海中 Index 是 row.names (因为有时人们不小心将它们包括在内),并且在执行上述代码之前我已经放弃了它。我这样编辑了我的代码。谢谢
    【解决方案3】:

    或者,如果您需要过滤一组明确的值(您说过要过滤 15 个字符串),您可以使用它来过滤所有列。

    library(dplyr)
    conditions.to.match <- c(123, 321)
    df %>% filter(Reduce('|', lapply(df, '%in%', conditions.to.match)))
    

    (Idea from here)

    【讨论】:

      猜你喜欢
      • 2020-08-11
      • 2019-03-27
      • 2020-09-29
      • 2018-06-23
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      相关资源
      最近更新 更多