【问题标题】:remove duplicates from chunks of rows based on one group in a data.frame根据 data.frame 中的一组从行块中删除重复项
【发布时间】:2019-04-13 22:23:49
【问题描述】:

我需要根据data.frame 中的一个组删除重复的行。

在下面的示例中,每组 'a' 观察 (>1) 需要减少到只有一个观察,该观察必须是具有较低 time 值的观察:

df_1 = data.frame(time = c(1,2,8,12,19,22,23,30), group = 'a')

df_2 = data.frame(time = c(4,5,6,15,16,18,21,24,25,27), group = 'b')

df = rbind(df_1, df_2)

> df
   time group
1     1     a
2     2     a
3     4     b
4     5     b
5     6     b
6     8     a
7    12     a
8    15     b
9    16     b
10   18     b
11   19     a
12   21     b
13   22     a
14   23     a
15   24     b
16   25     b
17   27     b
18   30     a

这是我的预期输出:

   time group
1     1     a
3     4     b
4     5     b
5     6     b
6     8     a
8    15     b
9    16     b
10   18     b
11   19     a
12   21     b
13   22     a
15   24     b
16   25     b
17   27     b
18   30     a

有什么建议吗?

谢谢

【问题讨论】:

    标签: r dataframe duplicates


    【解决方案1】:

    我们可以使用rleiddata.table拆分groupifgroupa然后返回time的最小值,对于b组返回整个组原样.

    library(tidyverse)
    library(data.table)
    
    df %>%
      group_split(rleid(group), keep = FALSE) %>%
      map_dfr(~ if(.$group[1] == 'a') .[which.min(.$time), ] else .)
    
    
    #    time group
    #   <int> <fct>
    # 1     1 a    
    # 2     4 b    
    # 3     5 b    
    # 4     6 b    
    # 5     8 a    
    # 6    15 b    
    # 7    16 b    
    # 8    18 b    
    # 9    19 a    
    #10    21 b    
    #11    22 a    
    #12    24 b    
    #13    25 b    
    #14    27 b    
    #15    30 a    
    

    【讨论】:

    • 请注意:group_split 在 dplyr v0.8 以上版本中可用
    【解决方案2】:

    使用data.table,我们可以更轻松地做到这一点。只需按'group'的run-length-id(rleid),orderi中的'time'进行分组,获取不是duplicated的元素的索引行(.I),其中“组”是“a”或“b”。使用它来子集行

    library(data.table)
    i1 <- setDT(df)[order(time), .I[!duplicated(group == 'a')|
            group == 'b'] , .(grp = rleid(group))]$V1
    df[i1]
    #    time group
    # 1:    1     a
    # 2:    4     b
    # 3:    5     b
    # 4:    6     b
    # 5:    8     a
    # 6:   15     b
    # 7:   16     b
    # 8:   18     b
    # 9:   19     a
    #10:   21     b
    #11:   22     a
    #12:   24     b
    #13:   25     b
    #14:   27     b
    #15:   30     a
    

    注意:不需要if/else 或循环

    数据

    df <- structure(list(time = c(1L, 2L, 4L, 5L, 6L, 8L, 12L, 15L, 16L, 
    18L, 19L, 21L, 22L, 23L, 24L, 25L, 27L, 30L), group = c("a", 
     "a", "b", "b", "b", "a", "a", "b", "b", "b", "a", "b", "a", "a", 
     "b", "b", "b", "a")), class = "data.frame", row.names = c("1", 
     "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
      "14", "15", "16", "17", "18"))
    

    【讨论】:

      猜你喜欢
      • 2021-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-25
      • 2016-01-09
      • 2013-04-04
      • 2020-11-06
      相关资源
      最近更新 更多