如何按人员从两列中进行有条件重置的运行总计?

时间:2019-06-20 16:45:24

标签: r database dplyr

在RV公园有居民的访客日志。根据城市法律,居民在公园停留14天之内不得停留超过150天。如果居民离开的时间少于10天,然后重新签到,则这些天将添加到他们的总营业时间中。

因此,我正在寻找一种方法来汇总每个居民在公园的时间,同时当中断时间超过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 ,这意味着该居民仍在现场。因此,在计算 stay 时,将今天的日期用作出发日期。

我需要创建一个变量,该变量显示自最近10天中断( sincehiatus )起的天数。

我已经手动输入了“ sincehiatus ”的外观,但是我很难到达那里。

对于每个人, sincehiatus = hiatus + stay + lag( sincehiatus ),以及何时 hiatus > 10, sincehiatus = 逗留

我想知道每个人的总成绩如何。我在将点与我看到的其他帖子连接起来时遇到麻烦。谢谢!

1 个答案:

答案 0 :(得分:0)

“技巧”是查找“连续”停留的条纹,即任何中断少于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与OP的要求保持一致(第10至13行除外,OP从Jon Snow的最后一次访问到Bran Stark的第一次访问相距两天而已)。

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")