【问题标题】:Group by cumulative sums with conditions按条件累计和分组
【发布时间】:2021-02-14 15:35:04
【问题描述】:

在这个数据框中:

df <- data.frame(
  ID = c("C", "B", "B", "B", NA, "C", "A", NA, "B", "B", "B")
)

我想使用 cumsum 对行进行分组,有两个条件:(i) cumsum 不应继续,如果 is.na(ID) 和 (ii) 如果 next 则不应继续ID 的值与之前的相同。我确实符合条件(i):

df %>%
  group_by(grp = cumsum(!is.na(ID)))
# A tibble: 11 x 2
# Groups:   grp [9]
   ID      grp
   <chr> <int>
 1 C         1
 2 B         2
 3 B         3
 4 B         4
 5 NA        4
 6 C         5
 7 A         6
 8 NA        6
 9 B         7
10 B         8
11 B         9

但我也不知道如何实现条件(ii)以获得期望的结果

 1 C         1
 2 B         2
 3 B         2
 4 B         2
 5 NA        2
 6 C         3
 7 A         4
 8 NA        4
 9 B         5
10 B         5
11 B         5

我用这个试过了,但我不工作:

df %>%
  group_by(grp = cumsum(!is.na(ID) |!lag(ID,1) == ID))

【问题讨论】:

    标签: r dplyr cumsum


    【解决方案1】:

    使用 zoo 中的 na.locf0 填写 NA,然后应用 data.table 中的 rleid:

    library(data.table)
    library(zoo)
    
    rleid(na.locf0(df$ID))
    ##  [1] 1 2 2 2 2 3 4 4 5 5 5
    

    【讨论】:

      【解决方案2】:

      使用tidyrdplyr,您可以:

      df %>%
       mutate(grp = fill(., ID) %>% pull(),
              grp = cumsum(grp != lag(grp, default = first(grp))))
      
           ID grp
      1     C   0
      2     B   1
      3     B   1
      4     B   1
      5  <NA>   1
      6     C   2
      7     A   3
      8  <NA>   3
      9     B   4
      10    B   4
      11    B   4
      

      【讨论】:

        【解决方案3】:

        使用rle

        library(zoo)
        with(rle(na.locf0(df$ID)), rep(seq_along(values), lengths))
        #[1] 1 2 2 2 2 3 4 4 5 5 5
        

        【讨论】:

          猜你喜欢
          • 2017-03-04
          • 1970-01-01
          • 2015-07-22
          • 1970-01-01
          • 2023-02-25
          • 1970-01-01
          • 2021-02-03
          • 2013-05-26
          相关资源
          最近更新 更多