【问题标题】:R: Collapse duplicated values in a column while keeping the orderR:在保持顺序的同时折叠列中的重复值
【发布时间】:2018-05-29 13:51:23
【问题描述】:

我确信这非常简单,但就是找不到答案。我有一个这样的数据框

    Id  event
1   1   A
2   1   B
3   1   A
4   1   A
5   2   C
6   2   C
7   2   A

我想按Id 分组并折叠不同的event 值,同时保持这样的事件顺序

    Id  event
1   1   A
2   1   B
3   1   A
4   2   C
5   2   A

我的大部分搜索最终都使用distinct()unique() 函数,但这会导致Id 1 在第3 行中丢失A 事件。

提前致谢!

【问题讨论】:

    标签: r dplyr unique distinct


    【解决方案1】:

    我们可以使用lead 来比较每一行,并使用filter 来比较那些与之前不同的行。 is.na(lead(Id)) 也包括最后一行。

    library(dplyr)
    
    dat2 <- dat %>% 
      filter(!(Id == lead(Id) & event == lead(event)) | is.na(lead(Id)))
    dat2
    #   Id event
    # 1  1     A
    # 2  1     B
    # 3  1     A
    # 4  2     C
    # 5  2     A
    

    数据

    dat <- read.table(text = "    Id  event
    1   1   A
                      2   1   B
                      3   1   A
                      4   1   A
                      5   2   C
                      6   2   C
                      7   2   A",
                      header = TRUE, stringsAsFactors = FALSE)
    

    【讨论】:

    • 很好,我不知道 dplyr 的 Lead() 函数!
    • 你们都是英雄!!非常感谢!这比我想象的要复杂,但我很高兴你也介绍了 lead 函数,我也在其他一些代码中使用了 lag 函数,所以管道这个对我来说很有意义。
    【解决方案2】:

    您可以将每一行与后面的行进行比较。

    df = read.table(text=" Id  event
    1   1   A
    2   1   B
    3   1   A
    4   1   A
    5   2   C
    6   2   C
    7   2   A", 
    header=TRUE)
    
    df[rowSums(df[-1,] == head(df, -1)) !=2, ]
      Id event
    1  1     A
    2  1     B
    4  1     A
    6  2     C
    7  2     A
    

    【讨论】:

    • 哇,这是一个聪明的解决方案。
    【解决方案3】:

    这是data.table的解决方案:

    library("data.table")
    dt <- fread(
    " Id  event
       1   A
       1   B
       1   A
       1   A
       2   C
       2   C
       2   A")
    unique(dt[, r:=rleidv(event), Id])[, -3]
    #    Id event
    # 1:  1     A
    # 2:  1     B
    # 3:  1     A
    # 4:  2     C
    # 5:  2     A
    

    dt[, .SD[unique(rleidv(event))], by = Id]
    

    (感谢@mt1022 的评论)

    【讨论】:

    • 或者,dt[, .SD[!duplicated(rleid(event))], by = Id]
    【解决方案4】:

    使用tapplyrle 的基本R 解决方案:

    x <- tapply(dat$event,dat$Id,function(x) rle(x)$values)
    do.call(rbind,Map(data.frame,Id=names(x),event=x))
    #     Id event
    # 1.1  1     A
    # 1.2  1     B
    # 1.3  1     A
    # 2.1  2     C
    # 2.2  2     A
    

    【讨论】:

      【解决方案5】:

      我认为distinct 函数将能够解决问题。

      dat %>% distinct(Id, event)

      【讨论】:

        猜你喜欢
        • 2020-05-15
        • 2021-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-13
        • 1970-01-01
        • 2020-04-05
        • 2010-12-05
        相关资源
        最近更新 更多