【问题标题】:(R) Cumulatively Count Gaps in Sequential Numbers(R) 累积计算序号中的间隙
【发布时间】:2020-01-28 19:20:12
【问题描述】:

我想解决一个棘手的问题:

我的数据类似于以下示例:

UniqueID  Month  
ABC123    1       
ABC123    2      
ABC123    3      
ABC123    4      
ABC123    6      
ABC123    7      
DEF456    3      
DEF456    4      
DEF456    10     
DEF456    11     
DEF456    12     
DEF456    14     
GHI789    2      
GHI789    3  
JKL012    12     
JKL012    13     
JKL012    14         

UniqueID 每个月都是唯一的。月份列指的是特定月份。例如:1=2018 年 10 月,2=2019 年 11 月,以此类推。我们总共有 14 个不同的月份有数据。我想累计计算我们跳过一个月的次数,以及每个 UniqueID 的最后一个月不是 14 的时间。起始月份不计入计算中。结果计算将产生以下示例:

UniqueID  Month  CountSkip
ABC123    1      0  
ABC123    2      0
ABC123    3      0
ABC123    4      0
ABC123    6      1
ABC123    7      2
DEF456    3      0
DEF456    4      0
DEF456    10     1
DEF456    11     1
DEF456    12     1
DEF456    14     2
GHI789    2      0
GHI789    3      1
JKL012    12     0
JKL012    13     0
JKL012    14     0

我有一个 sn-p 通过执行以下操作来计算跳过的总数:

data %>% 
  group_by(UniqueID) %>%
  mutate(Skipped = sum(diff(Month) > 1))

我如何修改它以累计计算跳过次数并考虑上个月的值不是 14?

任何帮助将不胜感激!谢谢!

【问题讨论】:

    标签: r dplyr count


    【解决方案1】:

    这是一种方法。让我知道这是否符合您的要求。

    library(tidyverse)
    
    data %>%
      group_by(UniqueID) %>%
      mutate(Skip = if_else(Month - lag(Month, default = first(Month) - 1) - 1 > 0 | 
                              (Month == last(Month) & Month != 14), 1, 0),
             CountSkip = cumsum(Skip))
    
    # A tibble: 17 x 4
    # Groups:   UniqueID, CountSkip [9]
       UniqueID Month  Skip CountSkip
       <chr>    <int> <dbl>     <dbl>
     1 ABC123       1     0         0
     2 ABC123       2     0         0
     3 ABC123       3     0         0
     4 ABC123       4     0         0
     5 ABC123       6     1         1
     6 ABC123       7     1         2
     7 DEF456       3     0         0
     8 DEF456       4     0         0
     9 DEF456      10     1         1
    10 DEF456      11     0         1
    11 DEF456      12     0         1
    12 DEF456      14     1         2
    13 GHI789       2     0         0
    14 GHI789       3     1         1
    15 JKL012      12     0         0
    16 JKL012      13     0         0
    17 JKL012      14     0         0
    

    数据(来自@akrun)

    data <- structure(list(UniqueID = c("ABC123", "ABC123", "ABC123", "ABC123", 
                                        "ABC123", "ABC123", "DEF456", "DEF456", "DEF456", "DEF456", "DEF456", 
                                        "DEF456", "GHI789", "GHI789", "JKL012", "JKL012", "JKL012"), 
                           Month = c(1L, 2L, 3L, 4L, 6L, 7L, 3L, 4L, 10L, 11L, 12L, 
                                     14L, 2L, 3L, 12L, 13L, 14L)), class = "data.frame", row.names = c(NA, 
                                                                                                       -17L))
    

    【讨论】:

    • 不清楚为什么要最后一个group_bydata %&gt;% group_by(UniqueID) %&gt;% mutate(Skip = cumsum(c(FALSE, diff(Month) &gt; 1) |(Month == last(Month) &amp; Month != 14)))
    • 我的错误 - 感谢您的纠正!我会编辑答案。我忘了我已经分组了,只需要在最后变异。
    【解决方案2】:

    我们可以直接在diff逻辑向量上使用cumsum

    library(dplyr)
    data %>% 
       group_by(UniqueID) %>%
       mutate(i1 = c(FALSE, diff(Month) > 1)) %>%
       group_by(grp = cumsum(c(TRUE, i1[-1])), add = TRUE) %>%
       mutate(Count = row_number() * any(i1) ) %>%
       ungroup %>%
       select(-i1, -grp)
    # A tibble: 17 x 3
    #   UniqueID Month Count
    #   <chr>    <int> <int>
    # 1 ABC123       1     0
    # 2 ABC123       2     0
    # 3 ABC123       3     0
    # 4 ABC123       4     0
    # 5 ABC123       6     1
    # 6 ABC123       7     2
    # 7 DEF456       3     0
    # 8 DEF456       4     0
    # 9 DEF456      10     1
    #10 DEF456      11     2
    #11 DEF456      12     3
    #12 DEF456      14     1
    #13 GHI789       2     0
    #14 GHI789       3     0
    #15 JKL012      12     0
    #16 JKL012      13     0
    #17 JKL012      14     0
    

    数据

    data <- structure(list(UniqueID = c("ABC123", "ABC123", "ABC123", "ABC123", 
    "ABC123", "ABC123", "DEF456", "DEF456", "DEF456", "DEF456", "DEF456", 
    "DEF456", "GHI789", "GHI789", "JKL012", "JKL012", "JKL012"), 
        Month = c(1L, 2L, 3L, 4L, 6L, 7L, 3L, 4L, 10L, 11L, 12L, 
        14L, 2L, 3L, 12L, 13L, 14L)), class = "data.frame", row.names = c(NA, 
    -17L))
    

    【讨论】:

    • 嘿akrun,感谢您回答我的问题!我使用了您的代码,并且每个 UniqueID 的第一次出现都为零,但所有其他值都是 NA。另外,我收到了 4 行警告消息 --> "In Ops.factor(diff(Month),1) : '>' 对因素没有意义
    • @user2813606 你应该提供一个reproducible example。使用dput(head(data,17)) 而不是复制/粘贴。
    • 我还注意到计数不太正确:第 10、11、12 和 14 行不正确
    • @user2813606 如果您检查6 and 7,我使用了相同的方法
    • 第 10-12 行应该是 1、1,然后是 2,然后第 14 行应该是 1,因为它是最后一个值,并且它的值不等于 14
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多