【问题标题】:How to subset data based on two conditions如何根据两个条件对数据进行子集化
【发布时间】:2020-04-15 23:36:07
【问题描述】:

假设我有一个数据框 df

> df
      ID Year Weight
1  Brown 1960    5.0
2  Green 1990    3.0
3 Yellow 1961    4.8
4  Green 1994    7.0
5  Green 1993    6.0
6  Brown 1964    8.0
7 Yellow 1960    4.6

如果我想对所有权重大于等于 5 的 ID 进行子集化,我会简单地说:

> df[df$Weight >= 5, ]
     ID Year Weight
1 Brown 1960      5
4 Green 1994      7
5 Green 1993      6
6 Brown 1964      8

很遗憾,1990年以下的Green因为权重小于5而被排除在外。有没有办法可以保留所有ID,只要其中一个权重大于等于5?

期望的输出

> output
     ID Year Weight
1 Green 1990      3
2 Green 1993      6
3 Green 1994      7
4 Brown 1960      5
5 Brown 1964      8

非常感谢!

【问题讨论】:

  • 重量 >= 5 | (ID ==“绿色”和年份 == 1990)

标签: r subset threshold


【解决方案1】:

我们可以在这里使用dplyr,并且只保留每个ID 的行,这样组中的一个成员的权重为5 或更高:

temp <- df %>%
    group_by(ID) %>%
    mutate(Min_Weight = max(Weight))

output <- temp[temp$Min_Weight >= 5, ]
output[order(output$ID), ]

  ID     Year Weight Min_Weight
  <chr> <dbl>  <dbl>      <dbl>
1 Brown  1960      5          8
2 Brown  1964      8          8
3 Green  1990      3          7
4 Green  1994      7          7
5 Green  1993      6          7

数据:

df <- data.frame(ID=c("Brown", "Green", "Yellow", "Green", "Green", "Brown", "Yellow"),
                 Year=c(1960, 1990, 1961, 1994, 1993, 1964, 1960),
                 Weight=c(5.0, 3.0, 4.8, 7.0, 6.0, 8.0, 4.6), stringsAsFactors=FALSE)

【讨论】:

    【解决方案2】:

    这是带有ave()subset() 的基本R 解决方案

    dfout <- subset(df, as.logical(with(df,ave(Weight, ID, FUN = function(x) any(x>=5)))))
    

    这样

    > dfout
         ID Year Weight
    1 Brown 1960      5
    2 Green 1990      3
    4 Green 1994      7
    5 Green 1993      6
    6 Brown 1964      8
    

    【讨论】:

    • 短:subset(df, ave(Weight &gt; 5, ID, FUN = any))
    【解决方案3】:

    使用dplyr,我们可以group_byID和使用filter

    library(dplyr)
    df %>% group_by(ID) %>% filter(any(Weight > 5))
    
    #   ID     Year Weight
    #  <chr> <dbl>  <dbl>
    #1 Brown  1960      5
    #2 Green  1990      3
    #3 Green  1994      7
    #4 Green  1993      6
    #5 Brown  1964      8
    

    或者data.table

    library(data.table)
    
    setDT(df)
    df[, .SD[any(Weight > 5)], ID]
    

    【讨论】:

      【解决方案4】:

      转换为data.table

      > library(data.table)
      > setDT(df)
      
      > df[ID %in% df[Weight>5, ID]]
            ID Year Weight
      1: Brown 1960      5
      2: Green 1990      3
      3: Green 1994      7
      4: Green 1993      6
      5: Brown 1964      8
      

      【讨论】:

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