Как мне сделать промежуточный итог с условным сбросом из двух столбцов по человеку? - PullRequest
0 голосов
/ 20 июня 2019

В RV парке есть гостевой журнал жителей. По городскому законодательству жители могут проживать не более 150 дней без 14-дневного перерыва в парке. Если резидент уезжает на <10 дней и регистрируется обратно, эти дни добавляются к его промежуточной сумме. </p>

Так что я ищу способ подвести итог времени каждого жителя в парке, перезапуская тот промежуточный итог, когда берется перерыв, превышающий 10 дней.

Нам предоставляется таблица с датами прибытия и отъезда каждого человека.

today <- Sys.Date(01/01/2019,"%m/%d/%Y")
hiatus <- ifelse(name == lag(name), arrival-lag(depart), 0)
stay <- ifelse(is.na(depart), as.numeric(today-arrival), depart-arrival)

resident     arrival     departure    hiatus    stay   sincehiatus
Snow, Jon    17633       17652        0         19     19          
Snow, Jon    17656       17683        4         27     50        
Snow, Jon    17683       17713        0         30     80
Snow, Jon    17713       17752        0         39     119
Snow, Jon    17763       17775        11        12     12
Snow, Jon    17775       17805        0         30     42
Snow, Jon    17805       17836        0         31     73
Snow, Jon    17836       17882        0         46     119
Snow, Jon    17895       N/A          13        2      2
Stark, Bran  17823       17831        0         8      10
Stark, Bran  17831       17845        0         14     24
Stark, Bran  17845       17847        0         2      26
Stark, Bran  17847       17849        0         2      28
Stark, Bran  17859       N/A          10        38     38

Я пошел вперед и создал переменную " hiatus " и переменную " stay ", определенные ниже.

Для N / A при выезде это означает, что резидент все еще находится на месте. Таким образом, сегодняшняя дата используется в качестве даты их отправления при расчете пребывания .

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

Я вручную ввел то, что " Sincehiatus " должно выглядеть, у меня просто проблемы с этим.

Для каждого человека: Sincehiatus = Hiatus + остаться + лаг ( Sincehiatus ), а когда Hiatus > 10, sincehiatus = остаться

Мне интересно, как сделать промежуточный итог на человека. У меня проблемы с подключением точек к другим сообщениям, которые я видел. Спасибо!

1 Ответ

0 голосов
/ 20 июня 2019

«Уловка» состоит в том, чтобы найти полосы «смежных» остановок, то есть там, где любой перерыв был менее 10 дней.Это достигается путем создания stay.id для каждого resident по cumsum(hiatus >= 10) и группировки соответственно.

dplyr

library(dplyr)
today <- as.Date("01/01/2019","%m/%d/%Y")
ds %>% 
  arrange(resident, arrival) %>% # just to ensure proper row order
  group_by(resident) %>% 
  mutate(stay.id = cumsum(arrival - lag(departure, default = 0) >= 10)) %>% 
  group_by(resident, stay.id) %>% 
  mutate(sh = ifelse(is.na(departure), today, departure) - min(arrival))
# A tibble: 14 x 8
# Groups:   resident, stay.id [5]
   resident    arrival departure hiatus  stay sincehiatus stay.id    sh
   <chr>         <dbl>     <dbl>  <dbl> <dbl>       <dbl>   <int> <dbl>
 1 Snow, Jon     17633     17652      0    19          19       1    19
 2 Snow, Jon     17656     17683      4    27          50       1    50
 3 Snow, Jon     17683     17713      0    30          80       1    80
 4 Snow, Jon     17713     17752      0    39         119       1   119
 5 Snow, Jon     17763     17775     11    12          12       2    12
 6 Snow, Jon     17775     17805      0    30          42       2    42
 7 Snow, Jon     17805     17836      0    31          73       2    73
 8 Snow, Jon     17836     17882      0    46         119       2   119
 9 Snow, Jon     17895        NA     13     2           2       3     2
10 Stark, Bran   17823     17831      0     8          10       1     8
11 Stark, Bran   17831     17845      0    14          24       1    22
12 Stark, Bran   17845     17847      0     2          26       1    24
13 Stark, Bran   17847     17849      0     2          28       1    26
14 Stark, Bran   17859        NA     10    38          38       2    38

новый столбец sh соответствует объяснениям ОП (за исключением строк с 10 по 13, где ОП, кажется, добавил 2 дня от последнего визита Джона Сноу к первому Брану Старку).

data.table

Для полноты, здесь также есть версия data.table, которая создает переменную группировки на лету и обновляет ds по ссылке , т. Е. Добавляется новый столбецбез копирования всего объекта данных.

library(data.table)
today <- as.Date("01/01/2019","%m/%d/%Y")
setDT(ds)[order(arrival), sh := ifelse(is.na(departure), today, departure) - min(arrival), 
          by = .(resident, cumsum(arrival - shift(departure, fill = 0) >= 10))][]
ds
       resident arrival departure hiatus stay sincehiatus  sh
 1:   Snow, Jon   17633     17652      0   19          19  19
 2:   Snow, Jon   17656     17683      4   27          50  50
 3:   Snow, Jon   17683     17713      0   30          80  80
 4:   Snow, Jon   17713     17752      0   39         119 119
 5:   Snow, Jon   17763     17775     11   12          12  12
 6:   Snow, Jon   17775     17805      0   30          42  42
 7:   Snow, Jon   17805     17836      0   31          73  73
 8:   Snow, Jon   17836     17882      0   46         119 119
 9:   Snow, Jon   17895        NA     13    2           2   2
10: Stark, Bran   17823     17831      0    8          10   8
11: Stark, Bran   17831     17845      0   14          24  22
12: Stark, Bran   17845     17847      0    2          26  24
13: Stark, Bran   17847     17849      0    2          28  26
14: Stark, Bran   17859        NA     10   38          38  38

Данные

ds <- readr::read_table("
resident     arrival     departure    hiatus    stay   sincehiatus
Snow, Jon    17633       17652        0         19     19          
Snow, Jon    17656       17683        4         27     50        
Snow, Jon    17683       17713        0         30     80
Snow, Jon    17713       17752        0         39     119
Snow, Jon    17763       17775        11        12     12
Snow, Jon    17775       17805        0         30     42
Snow, Jon    17805       17836        0         31     73
Snow, Jon    17836       17882        0         46     119
Snow, Jon    17895       N/A          13        2      2
Stark, Bran  17823       17831        0         8      10
Stark, Bran  17831       17845        0         14     24
Stark, Bran  17845       17847        0         2      26
Stark, Bran  17847       17849        0         2      28
Stark, Bran  17859       N/A          10        38     38"
                  , na = "N/A")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...