【问题标题】:group_by and keep all groups that does not not contain specific value and filter where there is valuegroup_by 并保留所有不包含特定值的组并过滤有值的地方
【发布时间】:2025-12-27 09:50:11
【问题描述】:

我有以下数据框:

df <- data.frame(
  Code = c("a", "a", "a", "a", "a", "b", "b", "b", "b", "b"),
  Inst = c("Yes", "No", "No", "No", "No", "No", "No", "No", "No", "No"),
  Date = c(
    "2021-01-01", "2021-01-02", "2021-01-03", "2021-01-04", "2021-01-05", 
    "2021-01-06", "2021-01-06", "2021-01-06", "2021-01-09", "2021-01-10"
  )
)

我想将dplyr::group_by 应用于变量Code 并过滤特定值“是”和最小Date,但我想保留不包含“是”值的组的所有观察结果。我试过filter(any(Inst == "Yes")),但这不起作用。

我想要这个结果:

Code  Inst  Date
a      Yes  2021-01-01
b      No   2021-01-06
b      No   2021-01-06
b      No   2021-01-06

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    如果可能有多个Yes 值:

    df %>%
     group_by(Code) %>%
     slice(if(all(Inst != "Yes")) 1:n() else which(Inst == "Yes"))
    
      Code  Inst 
      <chr> <chr>
    1 a     Yes  
    2 b     No   
    3 b     No   
    4 b     No   
    5 b     No   
    6 b     No  
    

    考虑更新的问题:

    df %>%
     mutate(Date = as.Date(Date, format = "%Y-%m-%d")) %>%
     group_by(Code) %>%
     slice(if(all(Inst != "Yes")) 1:n() else which(Inst == "Yes")) %>%
     filter(Date == min(Date))
    
      Code  Inst  Date      
      <chr> <chr> <date>    
    1 a     Yes   2021-01-01
    2 b     No    2021-01-06
    3 b     No    2021-01-06
    4 b     No    2021-01-06
    

    【讨论】:

    • 这项工作。谢谢....如果在我的数据框中我有另一列包含所有行的日期,我想过滤最小日期。如何修改你的代码?我想使用两个 codintions == "yes" 和 Date == min(Date)
    • 请更新您的示例数据集和预期结果。
    • 更新数据框和结果
    • 不错的答案,点赞!其实你不需要mutate(Date = as.Date(Date, format = "%Y-%m-%d")) 这行,请看我的尝试。
    【解决方案2】:

    dplyr

    library(dplyr)
    
    df %>%
      group_by(Code) %>%
      summarize(
        across(everything(), function(x) {
          if (any(Inst == "Yes")) x[which.max(Inst == "Yes")] else x
        })
      ) %>%
      ungroup()
    
    #> `summarise()` has grouped output by 'Code'. You can override using the `.groups` argument.
    #> # A tibble: 6 x 3
    #>   Code  Inst  Date      
    #>   <chr> <chr> <chr>     
    #> 1 a     Yes   2021-01-01
    #> 2 b     No    2021-01-06
    #> 3 b     No    2021-01-06
    #> 4 b     No    2021-01-06
    #> 5 b     No    2021-01-09
    #> 6 b     No    2021-01-10
    

    【讨论】:

    • 很好的解决方案,但删除了我的数据框的其他列。在我的问题中,我使用了一个示例
    • 我更新了我对日期列的其他第二个条件的问题。我想在 min(Date) 上添加过滤器。
    【解决方案3】:

    dplyr 选项

    df %>%
      group_by(Code) %>%
      filter(ifelse(all(Inst == "No"), c, `!`)(Inst == "No")) %>%
      filter(Date == min(Date)) %>%
      ungroup()
    

    给予

    # A tibble: 4 x 3
      Code  Inst  Date      
      <chr> <chr> <chr>
    1 a     Yes   2021-01-01
    2 b     No    2021-01-06
    3 b     No    2021-01-06
    4 b     No    2021-01-06
    

    【讨论】:

      最近更新 更多