(R) Кумулятивный подсчет пробелов в последовательных числах - PullRequest
0 голосов
/ 28 января 2020

У меня есть хитрая проблема, которую я пытаюсь решить:

У меня есть данные, которые выглядят следующим образом:

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         

Уникальный идентификатор уникален в месяц. Столбец месяца относится к конкретному месяцу. Например: 1 = октябрь 2018 года, 2 = ноябрь 2019 года и т. Д. У нас есть 14 различных месяцев, для которых у нас есть данные. Я хочу подсчитать, сколько раз мы пропускаем месяц, и когда последний месяц для уникального идентификатора не равен 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

У меня есть фрагмент для вычисления общего количества пропусков, выполнив следующие действия:

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

Как я могу изменить это на кумулятивно подсчитайте пропуски, а также учтите, что значение за последний месяц не равно 14?

Любая помощь будет принята с благодарностью! Спасибо!

Ответы [ 2 ]

2 голосов
/ 29 января 2020

Вот один из подходов. Дайте мне знать, если у вас есть логин c, который вы ищете.

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))
1 голос
/ 28 января 2020

Мы можем использовать cumsum непосредственно на diff логическом векторе

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

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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...