【问题标题】:In R, is there a way to calculate the number of days between the end of one event and the beginning of another?在 R 中,有没有办法计算一个事件结束和另一个事件开始之间的天数?
【发布时间】:2021-06-25 22:42:28
【问题描述】:

注意:酒店数据用作说明性示例。

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

以下是我正在使用的数据类型的示例。

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

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

daysSinceLastStay
NA
NA
43
111
218
NA
313

但是,我想我需要先按 custID 和 stayDt 排序。


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

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

非常感谢任何建议!

【问题讨论】:

    标签: r dplyr difftime


    【解决方案1】:

    根据您预期的数据,您似乎需要使用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
    

    【讨论】:

    • 谢谢@Andrew!快速跟进:为什么这里的 group_by(custID) 是必要的?
    • 根据您的描述和问题中所需的列输出,我的理解是您需要根据每个客户计算上次入住的时间。 group_by() 函数确保函数(例如 lag())在分组的基础上应用,即作为单独的数据帧。在我的输出中,客户 CCCCC 没有超过 1 次停留,因此您不想使用 BBBBB 数据的最后一行(即第 6 行)。
    • 知道了,谢谢!我之前已经对该 df 进行了分组,但没有意识到这样做对于每个客户执行的每个操作都是必要的。有道理,欣赏。
    猜你喜欢
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    相关资源
    最近更新 更多