【问题标题】:How to select lowest value or remove duplicates after using group_by function in r [duplicate]在 r [重复] 中使用 group_by 函数后如何选择最小值或删除重复项
【发布时间】:2019-05-31 07:57:00
【问题描述】:

我查看了许多线程,但找不到我要查找的内容。我有一个具有多个 ID 和日期的数据集,如下所示。

id  date       code
1   2000-10-08  690
1   2000-10-08  75
1   2000-10-08  35
1   2001-01-01  315
1   2001-01-01  70
1   2008-09-05  690
1   2008-09-05  5
1   2008-09-05  60
2   2006-02-01  188
2   2006-02-01  198
2   2006-02-01  555
2   2006-02-01  690
3   2010-10-10  120
3   2010-10-10  75
3   2010-10-10  25

我不希望每个 id 有重复的日期,并希望根据最低代码值来选择它,所以它最终会像这样:

id  date       code
1   2000-10-08  35
1   2001-01-01  70
1   2008-09-05  5
2   2006-02-01  188
3   2010-10-10  25

我使用了 group_by 函数,以便它按 id 和日期处理数据:

df %>%
 group_by(id, date) %>%
 arrange(code)

但是,我正在努力找出要使用的代码,以便现在只保留每个 id/date 组合的最低值。

谁能帮我解决这个问题?

谢谢

【问题讨论】:

标签: r dplyr grouping


【解决方案1】:

data.table 接近

library( data.table )
dt[, .( min = min( code ) ), by = .( id, date )]

#    id       date min
# 1:  1 2000-10-08  35
# 2:  1 2001-01-01  70
# 3:  1 2008-09-05   5
# 4:  2 2006-02-01 188
# 5:  3 2010-10-10  25

样本数据

dt <- fread("id  date       code
1   2000-10-08  690
1   2000-10-08  75
1   2000-10-08  35
1   2001-01-01  315
1   2001-01-01  70
1   2008-09-05  690
1   2008-09-05  5
1   2008-09-05  60
2   2006-02-01  188
2   2006-02-01  198
2   2006-02-01  555
2   2006-02-01  690
3   2010-10-10  120
3   2010-10-10  75
3   2010-10-10  25", header = TRUE)

【讨论】:

    【解决方案2】:

    使用tidyverse,您可以:

    library(tidyverse)
    dt %>% 
        group_by(id, date) %>% 
        summarise(code = min(code))
    
      id       date   x
    1  1 2000-10-08  35
    2  1 2001-01-01  70
    3  1 2008-09-05   5
    4  2 2006-02-01 188
    5  3 2010-10-10  25
    

    【讨论】:

      【解决方案3】:

      tidyverse的角度来看,如果有很多列并且需要每个组的'code'的minimum值的行,最好filter有一个逻辑条件

      library(tidyverse)
      df %>%
         group_by(id, date) %>%
         filter(code == min(code))
      # A tibble: 5 x 3
      # Groups:   id, date [5]
      #     id date        code
      #  <int> <chr>      <int>
      #1     1 2000-10-08    35
      #2     1 2001-01-01    70
      #3     1 2008-09-05     5
      #4     2 2006-02-01   188
      #5     3 2010-10-10    25
      

      如果每个组的 min 值存在关联,并且只希望 min 'code' 的第一次出现

      df %>%
         group_by(id, date) %>%
         slice(which.min(code))
      

      或者另一个选项是使用top_n

      df %>%
         group_by(id, date) %>%
         top_n(1, -code)
      

      使用来自base Raggregate

      aggregate(code ~ id + date, df, min)
      #  id       date code
      #1  1 2000-10-08   35
      #2  1 2001-01-01   70
      #3  2 2006-02-01  188
      #4  1 2008-09-05    5
      #5  3 2010-10-10   25
      

      数据

      df <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
      2L, 2L, 3L, 3L, 3L), date = c("2000-10-08", "2000-10-08", "2000-10-08", 
      "2001-01-01", "2001-01-01", "2008-09-05", "2008-09-05", "2008-09-05", 
      "2006-02-01", "2006-02-01", "2006-02-01", "2006-02-01", "2010-10-10", 
       "2010-10-10", "2010-10-10"), code = c(690L, 75L, 35L, 315L, 70L,
       690L, 5L, 60L, 188L, 198L, 555L, 690L, 120L, 75L, 25L)), 
       class = "data.frame", row.names = c(NA, -15L))
      

      【讨论】:

        【解决方案4】:

        只需在代码末尾添加slice(1)

        df %>%
         group_by(id, date) %>%
            arrange(code) %>%
            slice(1)
        ## # A tibble: 5 x 3
        ## # Groups:   id, date [5]
        ##      id date        code
        ##   <int> <fct>      <int>
        ## 1     1 2000-10-08    35
        ## 2     1 2001-01-01    70
        ## 3     1 2008-09-05     5
        ## 4     2 2006-02-01   188
        ## 5     3 2010-10-10    25
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-06-17
          • 2015-11-08
          • 2023-03-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多