【问题标题】:Finding end-date of last sickness incident in R在 R 中查找最后一次疾病事件的结束日期
【发布时间】:2021-08-15 18:23:48
【问题描述】:

我有一个文件记录某人何时生病以及何时康复。有些记录有几起疾病事件,我试图在每一行添加一个新列,即“上次疾病结束的日期”(如果不适用,则为“记录开始的日期”)。有 10,000 条记录,可能有 10 多起疾病事件。但在最简单的例子中,我试图从这个出发:

| ID      | RecordBegins | SickStartDate | SickEndDate |

| person1 | 1990-01-01 | 2017-03-04 | 2017-07-01 |

| person1 | 1990-01-01 | 2018-11-01 | 2019-02-04 |

到这里:


| ID      | RecordBegins | SickStartDate | SickEndDate | EndLastSick

| person1 | 1990-01-01 | 2017-03-04 | 2017-07-01 | 1990-01-01

| person1 | 1990-01-01 | 2018-11-01 | 2019-02-04 | 2017-07-01

我是 R 新手,并且是自学成才的。我一直试图留在 tidyverse 世界中,但对其他方法持开放态度。

当数据集中只有一个独特的人时,我可以使用下面的代码编写我想要的代码。当我将数据集扩展到多个人时,我尝试使用 group_by() 对其进行扩展,但我想不出一种使它起作用的方法。

sick <-tribble(
  ~ID, ~RecordBegins, ~SickStartDate, ~SickEndDate,
  "person1", as.Date("1990-01-01"), as.Date("2017-03-04"), as.Date("2017-07-01"),
  "person1", as.Date("1990-01-01"), as.Date("2018-11-01"), as.Date("2019-02-04"),
)

var1 <- sick$SickEndDate %>% sort(decreasing = TRUE) # place date of last sick at position [1]
var1[1] = sick$`RecordBegins`[1] # replace date of last sick with record start date
var1 <- sort(var1) # re-sort so in date order
sick <- mutate(sick, startExposure = var1)

但是,这感觉很笨拙,当扩展到多人时,我想不出一种方法让它发挥作用,例如:

sick <-tribble(
  ~ID, ~RecordBegins, ~SickStartDate, ~SickEndDate,
  "person1", as.Date("1990-01-01"), as.Date("2017-03-04"), as.Date("2017-07-01"),
  "person1", as.Date("1990-01-01"), as.Date("2018-11-01"), as.Date("2019-02-04"),
  "person2", as.Date("1995-01-01"), as.Date("2014-10-07"), as.Date("2017-01-04"),
  "person2", as.Date("1995-01-01"), as.Date("2017-11-01"), as.Date("2017-11-23"),
)

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    如果我对您的问题的解释正确,您可以按ID 分组,并使用lag

    library(dplyr)
    
    sick %>%
        arrange(ID, SickStartDate) %>%
        group_by(ID) %>%
        mutate(EndLastSick = case_when(
            # if this is the first record for this person, use RecordBegins
            is.na(lag(SickEndDate)) ~ RecordBegins,
            # otherwise, get the most recent SicKEndDate
            TRUE ~ lag(SickEndDate)
        ))
    
    ## A tibble: 4 x 5
    ## Groups:   ID [2]
    #  ID      RecordBegins SickStartDate SickEndDate EndLastSick
    #  <chr>   <date>       <date>        <date>      <date>     
    #1 person1 1990-01-01   2017-03-04    2017-07-01  1990-01-01 
    #2 person1 1990-01-01   2018-11-01    2019-02-04  2017-07-01 
    #3 person2 1995-01-01   2014-10-07    2017-01-04  1995-01-01 
    #4 person2 1995-01-01   2017-11-01    2017-11-23  2017-01-04 
    

    数据:

    sick <-tribble(
      ~ID, ~RecordBegins, ~SickStartDate, ~SickEndDate,
      "person1", as.Date("1990-01-01"), as.Date("2017-03-04"), as.Date("2017-07-01"),
      "person1", as.Date("1990-01-01"), as.Date("2018-11-01"), as.Date("2019-02-04"),
      "person2", as.Date("1995-01-01"), as.Date("2014-10-07"), as.Date("2017-01-04"),
      "person2", as.Date("1995-01-01"), as.Date("2017-11-01"), as.Date("2017-11-23"),
    )
    

    【讨论】:

    • 谢谢@heds1。我以前没有遇到过lag - 正是我需要的。
    【解决方案2】:

    这类似于@heds1 的答案,但仅使用lag 函数。

    library(dplyr)
    
    sick %>%
      arrange(ID, SickStartDate, SickEndDate) %>%
      group_by(ID) %>%
      mutate(EndLastSick = lag(SickEndDate, default = first(RecordBegins))) %>%
      ungroup
    
    #   ID    RecordBegins SickStartDate SickEndDate EndLastSick
    #  <chr>   <date>       <date>        <date>      <date>     
    #1 person1 1990-01-01   2017-03-04    2017-07-01  1990-01-01 
    #2 person1 1990-01-01   2018-11-01    2019-02-04  2017-07-01 
    #3 person2 1995-01-01   2014-10-07    2017-01-04  1995-01-01 
    #4 person2 1995-01-01   2017-11-01    2017-11-23  2017-01-04 
    

    【讨论】:

    • 谢谢@shahronak47。这是完美的,非常简洁。 first() 函数在这里做什么?我已经阅读了 dplyr 文档,并且可以看到它是 [[.我已经尝试过使用和不使用 first() 函数的上述代码。如果没有 first() 函数,我会收到错误消息 "x default must be size 1, not size 2",我不明白:is not the RecordBegins element length 1 ?
    • 因为我们已经按ID 分组,所以RecordBegins 向量(以及所有其他变量)的长度将等于每个ID 组重复的ID 值的数量@ 组.所以因为有两个person1s,RecordBegins 是一个长度为 2 的向量(对应于那个 IDRecordBegins 行)。所以无论如何,default 需要是单个值,这就是 Ronak 使用 first 的原因(以获取 RecordBegins 的第一个值)。
    • 谢谢@heds1
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多