Как использовать R, чтобы найти начало и конец наибольшей непрерывной последовательности для каждого идентификатора? - PullRequest
3 голосов
/ 20 сентября 2019

У меня есть набор данных.Каждый идентификатор имеет последовательность из 0 и 1, столбец даты и другой столбец num.day.Я хотел бы найти начало и конец самой длинной 1 последовательности для каждого идентификатора.Затем вычислите разрыв между датами от начала до конца.После этого добавьте соответствующий num.day конечной даты.

Например, следующий идентификатор таблицы = 1, самая длинная последовательность начинается с даты 4 (одна запись выше) и заканчивается 9. Таким образом, разрыв составляет 5.Добавьте число num.day для даты окончания должно быть day_gap = (9-4) +3 = 8. Если один идентификатор имеет несколько последовательностей, имеющих одинаковую самую длинную длину, то возьмите max day_gap из этих последовательностей для этого идентификатора.

enter image description here

Вот код для создания фиктивной таблицы

library(data.table)

ID=c(rep(1,10),rep(2,10),rep(3,10))
set.seed(1)
fill=sample(c(0,1),length(ID),replace=TRUE)

dat=data.table(ID,fill)[,date:=seq(.N),by="ID"][date==1,fill:=0]
set.seed(1)
dat$num.days=sample(1:10,nrow(dat),replace=TRUE)

Ответы [ 2 ]

0 голосов
/ 23 сентября 2019

Опция, использующая base::rle в data.table:

dat[, {
        r <- rle(fill)
        i <- which.max(r$lengths * r$values)
        .(day_gap = r$lengths[i] + num.days[sum(r$lengths[1L:i])])
    }, ID]

выход:

   ID day_gap
1:  1      11
2:  2      12
3:  3       8

данные:

library(data.table)

ID = c(rep(1,10),rep(2,10),rep(3,10))
set.seed(1)
fill = sample(c(0,1),length(ID),replace=TRUE)

dat = data.table(ID,fill)[,date:=seq(.N),by="ID"][date==1,fill:=0]
set.seed(1)
dat$num.days=sample(1:10,nrow(dat),replace=TRUE)
dat

dat:

    ID fill date num.days
 1:  1    0    1        3
 2:  1    0    2        4
 3:  1    1    3        6
 4:  1    1    4       10
 5:  1    0    5        3
 6:  1    1    6        9
 7:  1    1    7       10
 8:  1    1    8        7
 9:  1    1    9        7
10:  1    0   10        1
11:  2    0    1        3
12:  2    0    2        2
13:  2    1    3        7
14:  2    0    4        4
15:  2    1    5        8
16:  2    0    6        5
17:  2    1    7        8
18:  2    1    8       10
19:  2    0    9        4
20:  2    1   10        8
21:  3    0    1       10
22:  3    0    2        3
23:  3    1    3        7
24:  3    0    4        2
25:  3    0    5        3
26:  3    0    6        4
27:  3    0    7        1
28:  3    0    8        4
29:  3    1    9        9
30:  3    0   10        4
    ID fill date num.days
0 голосов
/ 20 сентября 2019

Вот мое решение с dplyr:

dat %>% 
 group_by(ID) %>% 
 mutate(group = cumsum(fill != lag(fill, default = fill[[1]])) + 1) %>% 
 ungroup() %>% 
 filter(fill == 1) %>% 
 group_by(ID, group) %>% 
 mutate(fill_group_no_max = max(row_number())) %>% 
 ungroup() %>% 
 group_by(ID) %>% 
 filter(fill_group_no_max == max(fill_group_no_max),
        group == max(group)) %>% 
 summarise(dategap = max(date) - min(date) + last(num.days)) %>% 
 ungroup() 

Обновление: Извините!Я забыл итоговую часть

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...