我有一個帶有 ID 和治療日期的資料框,如下所示
ID Dates
1 01/2/2012
1 02/8/2012
1 03/8/2012
1 04/5/2013
1 05/5/2013
2 01/2/2012
2 03/5/2013
2 04/6/2013
我需要為每個 ID 查找,如果有超過一年的治療日期中斷。如果是,那么我需要將它們分成兩門課程,并列出開始和結束日期。所以在執行 R 代碼后,它將如下所示:
ID Course1StarteDate Course1EndDate Break1to2(Yr) Course2StartDate Course2EndDate
1 01/2/2012 03/8/2012 1.075 04/5/2013 05/5/2013
2 01/2/2012 01/2/2012 1.173 03/5/2013 04/6/2013
我擁有的dataframe包含了數百個ID,不知道會有多少課程。有沒有一種有效的方法可以使用 R 來解決這個問題?提前致謝!
uj5u.com熱心網友回復:
如果d是您的資料,您可以確定一行日期與前一行日期之間的差異何時超過 365(或者可能是 365.25),然后用于cumsum生成不同的治療課程。最后添加一列,估計課程之間“休息”的持續時間。
as_tibble(d) %>%
group_by(ID) %>%
mutate(trt=as.numeric(Dates-lag(Dates)),
trt=cumsum(if_else(is.na(trt),0,trt)>365) 1) %>%
group_by(ID,trt) %>%
summarize(StartDate = min(Dates),
EndDate = max(Dates),.groups = "drop_last") %>%
mutate(Break:=as.numeric(lead(StartDate) - EndDate)/365)
輸出:
ID trt StartDate EndDate Break
<dbl> <dbl> <date> <date> <dbl>
1 1 1 2012-01-02 2012-03-08 1.08
2 1 2 2013-04-05 2013-05-05 NA
3 2 1 2012-01-02 2012-01-02 1.17
4 2 2 2013-03-05 2013-04-06 NA
我建議保持這種長格式,而不是像您在示例中那樣切換到寬格式,尤其是使用數百個 ID,所有這些 ID 都可能具有不同數量的課程。長格式幾乎總是更好。
但是,如果你真的想要這個,你可以從上面繼續管道,如下所示:
ungroup %>%
pivot_wider(id_cols =ID,
names_from = trt,
values_from = c(StartDate:Break),
names_glue = "Course{trt}_{.value}",
names_vary = "slowest")
產生這種“寬”格式:
ID Course1_StartDate Course1_EndDate Course1_Break Course2_StartDate Course2_EndDate Course2_Break
<dbl> <date> <date> <dbl> <date> <date> <dbl>
1 1 2012-01-02 2012-03-08 1.08 2013-04-05 2013-05-05 NA
2 2 2012-01-02 2012-01-02 1.17 2013-03-05 2013-04-06 NA
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/451449.html
