在 R 中,有没有办法计算一个事件结束和另一个事件开始之间的天数?

In R, is there a way to calculate the number of days between the end of one event and the beginning of another?

(注:酒店数据用作示例。)

我正在处理一个数据集,该数据集包含每个客户 (custID) 的多条记录(例如 'hotelStays')。我的目标是获取自客户上次入住以来的天数作为数据框中的新列(即每个客户的第一次入住将具有 'NA' 作为其值)。为此,我想从每个客户当前的 checkInDt 中减去他们之前的 checkOutDt。但是,当我尝试使用 lag() 这样做时,新列中的所有值都是 'NA'.

下面是我正在处理的数据类型的示例。

客户ID 住宿ID 留在Dt checkInDt checkOutDt
AAAAA 11111 1995 年 1 月 15 日 1995 年 1 月 10 日 1995 年 1 月 17 日
BBBBB 11112 1995 年 2 月 8 日 1995 年 2 月 2 日 1995 年 2 月 25 日
AAAAA 11113 1995 年 3 月 1 日 1995 年 3 月 1 日 1995 年 3 月 3 日
AAAAA 11114 1995 年 6 月 24 日 1995 年 6 月 22 日 1995 年 7 月 2 日
BBBBB 11115 10/02/1995 10/01/1995 10/10/1995
CCCCC 11116 1996 年 1 月 8 日 1996 年 1 月 5 日 1996 年 1 月 17 日
AAAAA 11117 1996 年 5 月 15 日 1996 年 5 月 10 日 1996 年 5 月 28 日

理想情况下,新列 'daysSinceLastStay' 应具有以下值:

上次入住天数
不适用
不适用
43
111
218
不适用
313

不过,我想我需要先按 custID 和 stayDt 排序。


下面是我目前对代码的尝试:

hotelData <- hotelData %>%
                arrange(custID, stayDt) %>%
                mutate(daysSinceLastStay = 
                       checkInDt - lag(checkOutDt))

非常感谢任何建议!

根据您期望的数据,您似乎需要使用 group_by() 函数。这应该可以满足您的需求。

# t*r*ibble, for creating data by row
hotelData <- tibble::tribble(
  ~custID, ~stayID, ~stayDt, ~checkInDt, ~checkOutDt,
  "AAAAA",  11111,  "01/15/1995",   "01/10/1995",   "01/17/1995",
  "BBBBB",  11112,  "02/08/1995",   "02/02/1995",   "02/25/1995",
  "AAAAA",  11113,  "03/01/1995",   "03/01/1995",   "03/03/1995",
  "AAAAA",  11114,  "06/24/1995",   "06/22/1995",   "07/02/1995",
  "BBBBB",  11115,  "10/02/1995",   "10/01/1995",   "10/10/1995",
  "CCCCC",  11116,  "01/08/1996",   "01/05/1996",   "01/17/1996",
  "AAAAA",  11117,  "05/15/1996",   "05/10/1996",   "05/28/1996"
)

# convert the date columns to the proper data type
# then, sort the data by customer ID and stayID
hotelData <- hotelData %>%
  mutate(across(stayDt:checkOutDt, lubridate::mdy)) %>%
  arrange(custID, stayID)

# within each customer, take the difference in days
hotelData %>%
  group_by(custID) %>%
  mutate(daysSinceLastStay = as.numeric(checkInDt - lag(checkOutDt)))

# A tibble: 7 x 6
# Groups:   custID [3]
  custID stayID stayDt     checkInDt  checkOutDt daysSinceLastStay
  <chr>   <dbl> <date>     <date>     <date>                 <dbl>
1 AAAAA   11111 1995-01-15 1995-01-10 1995-01-17                NA
2 AAAAA   11113 1995-03-01 1995-03-01 1995-03-03                43
3 AAAAA   11114 1995-06-24 1995-06-22 1995-07-02               111
4 AAAAA   11117 1996-05-15 1996-05-10 1996-05-28               313
5 BBBBB   11112 1995-02-08 1995-02-02 1995-02-25                NA
6 BBBBB   11115 1995-10-02 1995-10-01 1995-10-10               218
7 CCCCC   11116 1996-01-08 1996-01-05 1996-01-17                NA