【问题标题】:How to filter dataframe with multiple conditions?如何过滤具有多个条件的数据框?
【发布时间】:2015-07-14 06:08:43
【问题描述】:

我有想要子集的这个数据框(如果可能,使用dplyr 或base R 函数):

df <- data.frame(x = c(1,1,1,2,2,2), y = c(30,10,8,10,18,5))

x  y
1 30
1 10
1  8
2 10
2 18
2  5

假设 x 是因子(所以 2 个条件/级别),我如何子集/过滤此数据帧,以便我仅获得大于 15 的 df$x == 1 的 df$y 值和更大的 df$y 值df$x == 2 超过 5 个?

这是我想要的:

df2 <- data.frame(x = c(1,2,2), y = c(30,10,18))

x y
1 30
2 10
2 18

感谢任何帮助!谢谢!

【问题讨论】:

    标签: r dataframe subset dplyr


    【解决方案1】:

    你可以试试这个

    with(df, df[ (x==1 & y>15) | (x==2 & y>5), ])
      x  y
    1 1 30
    4 2 10
    5 2 18
    

    或dplyr

    library(dplyr)
    filter(df, (x==1 & y>15) | (x==2 & y>5))
    

    【讨论】:

    • 谢谢! dplyr 解决方案效果很好。但我不太了解with() 解决方案。 with() 函数有什么作用?
    • with让你直接使用变量名,不用写df$x。你可以用attach做类似的事情。
    • 啊,谢谢!现在我记得我以前用过with,但完全忘记了它,因为我几乎不使用它。再次感谢!
    【解决方案2】:

    如果您有多个“x”组,一种选择是使用mapply。我们split 'y' 使用'x' 作为分组变量,创建值向量以与 (c(15,5)) 进行比较,并使用mapply 获取子集'df' 的逻辑索引。

    df[unlist(mapply('>', split(df$y, df$x), c(15,5))),]
    #  x  y
    #1 1 30
    #4 2 10
    #5 2 18
    

    【讨论】:

    • 谢谢@akrun!虽然我更喜欢上面的dplyr 解决方案,因为它更容易理解,但您的mapply 解决方案也相当简洁,但我不完全理解mapply 在这里的工作原理。你能解释一下mapply('&gt;', split(df$y, df$x), c(15,5)) 是什么意思吗?非常感谢!
    • @hsl 是的,dplyr 和其他解决方案在这里很简洁。但是,我为大量组出售此 ((:-),即,如果您说 100 x 唯一值,并且每个“x”有 100 个值与y 元素进行比较,那么,@ 987654332@ 将使用&gt; 将对应的列表元素(split 的输出)与对应的向量元素(c(15,5))进行比较。
    • 感谢您的解释。我正在玩代码,并意识到如果每个“x”值的数字不同,比如data.frame(x = c(1,1,1,2,2,2,2), y = c(30,10,8,10,18,5,9))(三个 1 和四个 2),这种方法似乎不起作用。这是因为要让它工作,mapply 必须返回一个数据框,而不是列表? @akrun
    • @hsl 你必须使用unlist。我认为它适用于大多数情况。 df[unlist(mapply('&gt;', split(df$y, df$x), c(15,5))),] 在提供的示例中,长度是相等的,所以 mapply 将结果强制转换为 matrix,而这里它保留为 list。所以,最好使用unlist
    • 太好了,现在说得通了。非常感谢! @akrun
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 2023-01-07
    • 2012-12-21
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    相关资源
    最近更新 更多