Совокупный пробел в последовательных числах приводит к различным ответам при добавлении новых данных - PullRequest
1 голос
/ 30 января 2020

Я несколько дней задавал вопрос go, который вы, ребята, помогли мне решить, и я всегда благодарен! Тем не менее, появилась новая проблема, и я снова нуждаюсь в вашей помощи!

Вот ссылка на исходную проблему: (R) Совокупное количество пробелов в последовательных числах

Я пытался подсчитать разрывы в последовательных числах для каждого выбора уникальных идентификаторов. Это был мой набор данных:

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    

Используя вашу помощь, я настроил код, предоставленный по ссылке выше, следующим образом:

data2=data %>%
       group_by(UniqueID) %>%
       mutate(Skip = if_else(Month - lag(Month, default = first(Month) - 1) - 1 > 0, 1, 0),
       CountSkip = cumsum(Skip))

data2 = data2%>% 
       group_by(UniqueID) %>%
       mutate(LastValue = if_else(Month == last(Month), 1, 0))

data2=as.data.frame(data2)
data2$FinalTally=ifelse(data2$LastValue==1 & data2$Month!=14,1,0)
data2$SeqCount=data2$FinalTally+data2$CountSkip

Это был результирующий набор данных:

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

Это то, что я хотел ... или я так думал.

Добавляя новые данные за следующий месяц (15), я редактировал в строке кода от второй до последней строки 15 быть новым заключительным месяцем. Однако я заметил, что сумма SeqCount по месяцам отличалась от суммы за тот же месяц до добавления новых данных. Я отфильтровал до одного месяца и нашел пример одного уникального идентификатора, в котором сумма SeqCount отличалась.

Вот пример перед включением новых данных:

UniqueID  Month  Skip CountSkip LastValue  FinalTally   SeqCount
ZZZ999    2      0    0         0          0            0
ZZZ999    3      0    0         0          0            0
ZZZ999    4      0    0         0          0            0 
ZZZ999    5      0    0         0          0            0
ZZZ999    6      0    0         1          1            1

Вот пример когда были включены новые данные:

UniqueID  Month  Skip CountSkip LastValue  FinalTally   SeqCount
ZZZ999    2      0    0         0          0            0
ZZZ999    3      0    0         0          0            0
ZZZ999    4      0    0         0          0            0 
ZZZ999    5      0    0         0          0            0
ZZZ999    6      0    0         0          0            0
ZZZ999    15     1    1         1          0            1

Это проблема: 6-й месяц теряет значение SeqCount при добавлении новых данных.

Моя конечная цель - запустить регрессионную модель для каждого месяца с SeqCount в качестве ответа с некоторыми другими столбцами в качестве предикторов (я не включил их для простоты чтения). Всякий раз, когда я добавляю новые данные, ответ меняется, и мои оценки не будут соответствовать.

Есть ли способ, которым я могу структурировать свой код по-разному, чтобы при добавлении новых данных лог c кода не изменял информацию из предыдущих значений SeqCount?

Любая помощь Буду признателен!

Спасибо!

1 Ответ

2 голосов
/ 05 февраля 2020

Следующее, кажется, воспроизводит то, что вы хотите, без жесткого кодирования любых значений в логи c.

Примечание. Как отмечают другие, похоже, что существует несоответствие между результатами в вопросе и предоставленным кодом. Например, в посте с вопросом UniqueID GHI789 для месяца 3 имеет значение CountSkip 1, хотя код возвращает 0. Код в этом ответе возвращает 0.

data <- cbind.data.frame(UniqueID = c('ABC123','ABC123','ABC123','ABC123','ABC123','ABC123','DEF456','DEF456','DEF456','DEF456','DEF456','DEF456','GHI789','GHI789','JKL012','JKL012','JKL012'),
                         Month = c(1,2,3,4,6,7,3,4,10,11,12,14,2,3,12,13,14))

cartesian <- expand.grid(UniqueID = unique(as.character(data$UniqueID)),
                  Month = seq(from=min(data$Month), to=max(data$Month), by=1))

BA <- cartesian %>% 
  left_join(data %>% mutate(Month_orig=Month), by=c("UniqueID","Month")) %>% 
  arrange(UniqueID, Month) %>% 
  group_by(UniqueID) %>% 
  mutate(Skip = ifelse(Month==Month_orig & 
                         is.na(lag(Month_orig,1)) & 
                         Month!=min(Month[!is.na(Month_orig)]), 
                       1, 0)) %>%
  mutate(Skip = ifelse(Skip==1 & is.na(lag(Month_orig,2)), 0, Skip)) %>% # contstrain to only one skipped period?
  filter(!is.na(Month_orig)) %>% 
  mutate(CountSkip = cumsum(Skip)) %>% 
  mutate(LastValue = ifelse(Month==max(Month), 1, 0)) %>%
  mutate(FinalTally = ifelse(LastValue==1 & Month != max(Month),1,0)) %>% 
  mutate(SeqCount = FinalTally + CountSkip) %>% 
  select(-Month_orig)
BA
# A tibble: 17 x 7
# Groups:   UniqueID [4]
   UniqueID Month  Skip CountSkip LastValue FinalTally SeqCount
   <fct>    <dbl> <dbl>     <dbl>     <dbl>      <dbl>    <dbl>
 1 ABC123       1     0         0         0          0        0
 2 ABC123       2     0         0         0          0        0
 3 ABC123       3     0         0         0          0        0
 4 ABC123       4     0         0         0          0        0
 5 ABC123       6     1         1         0          0        1
 6 ABC123       7     0         1         1          0        1
 7 DEF456       3     0         0         0          0        0
 8 DEF456       4     0         0         0          0        0
 9 DEF456      10     0         0         0          0        0
10 DEF456      11     0         0         0          0        0
11 DEF456      12     0         0         0          0        0
12 DEF456      14     1         1         1          0        1
13 GHI789       2     0         0         0          0        0
14 GHI789       3     0         0         1          0        0
15 JKL012      12     0         0         0          0        0
16 JKL012      13     0         0         0          0        0
17 JKL012      14     0         0         1          0        0

При чтении вопроса и комментарии более внимательно - я согласен, что для реализации решения потребуется ссылка на предыдущую версию таблицы. Вы можете попробовать rbind (old_data, new_rows), где new_rows является результатом обработки всех данных и сохранения только уникального (UniqueID, Month), не содержащегося в old_data. Я не полностью следую логике или намерениям здесь, так что, возможно, это не очень хорошая идея.

...