79823714

Date: 2025-11-18 18:36:23
Score: 1
Natty:
Report link

A quickish go with my own preferred tools. Is this what you're describing?

library(data.table)
library(fjoin) # install.packages("fjoin", repos=c("https://trobx.r-universe.dev"))
# individual-specific end dates
df_limits <- fread("
id   end_date
 1 2021-06-15
 2 2018-09-03
 3 2016-03-30 
")

# spells of care
df_spells <- fread("
id spell      start        end
 1     1 2015-01-13 2015-07-19
 1     2 2016-04-14 2017-02-07
 1     3 2018-05-24 2019-10-15
 2     1 2015-07-23 2017-01-05
 2     2 2018-02-13 2018-06-04
 2     3 2019-07-31 2021-02-04
 3     1 2015-02-16 2016-11-19
 3     2 2018-04-29 2020-03-01
")
START <- as.IDate("2014-01-01")

# how many months back do we need to go per id?
df_limits[, months_back := 12L * (year(end_date) - year(START)) + month(end_date)]

# expand to a grid for each id
grid <- df_limits[, .(id, end_date, month_end=seq(end_date, length.out = months_back, by = "-1 month")), by=.I][, I := NULL]
grid[, month_start:= fifelse(id==shift(id, type="lead"), shift(month_end, type="lead") +1L, START)]
grid[.N, month_start := START]
setcolorder(grid, c("id", "end_date", "month_start", "month_end")) 
setkeyv(grid, c("id", "month_start", "month_end")) 

# overlaps of care spells with the grid for each patient
ans <- fjoin_left(grid,
                  df_spells,
                  on = c("id", "month_end >= start", "month_start <= end"),
                  mult.x = "first", # in case there are overlapping care spells (we don't want multiple "hits")
                  indicate = TRUE) # 3L if match, 1L if not
ans[, in_care := .join==3L]

# output (for patient 2)
ans[id==2L]

Key: <id, month_start, month_end>
    .join    id   end_date month_start  month_end spell      start        end in_care
    <int> <int>     <IDat>      <IDat>     <IDat> <int>     <IDat>     <IDat>  <lgcl>
 1:     1     2 2018-09-03  2014-01-01 2014-01-03    NA       <NA>       <NA>   FALSE
 2:     1     2 2018-09-03  2014-01-04 2014-02-03    NA       <NA>       <NA>   FALSE
 3:     1     2 2018-09-03  2014-02-04 2014-03-03    NA       <NA>       <NA>   FALSE
 4:     1     2 2018-09-03  2014-03-04 2014-04-03    NA       <NA>       <NA>   FALSE
 5:     1     2 2018-09-03  2014-04-04 2014-05-03    NA       <NA>       <NA>   FALSE
 6:     1     2 2018-09-03  2014-05-04 2014-06-03    NA       <NA>       <NA>   FALSE
 7:     1     2 2018-09-03  2014-06-04 2014-07-03    NA       <NA>       <NA>   FALSE
 8:     1     2 2018-09-03  2014-07-04 2014-08-03    NA       <NA>       <NA>   FALSE
 9:     1     2 2018-09-03  2014-08-04 2014-09-03    NA       <NA>       <NA>   FALSE
10:     1     2 2018-09-03  2014-09-04 2014-10-03    NA       <NA>       <NA>   FALSE
11:     1     2 2018-09-03  2014-10-04 2014-11-03    NA       <NA>       <NA>   FALSE
12:     1     2 2018-09-03  2014-11-04 2014-12-03    NA       <NA>       <NA>   FALSE
13:     1     2 2018-09-03  2014-12-04 2015-01-03    NA       <NA>       <NA>   FALSE
14:     1     2 2018-09-03  2015-01-04 2015-02-03    NA       <NA>       <NA>   FALSE
15:     1     2 2018-09-03  2015-02-04 2015-03-03    NA       <NA>       <NA>   FALSE
16:     1     2 2018-09-03  2015-03-04 2015-04-03    NA       <NA>       <NA>   FALSE
17:     1     2 2018-09-03  2015-04-04 2015-05-03    NA       <NA>       <NA>   FALSE
18:     1     2 2018-09-03  2015-05-04 2015-06-03    NA       <NA>       <NA>   FALSE
19:     1     2 2018-09-03  2015-06-04 2015-07-03    NA       <NA>       <NA>   FALSE
20:     3     2 2018-09-03  2015-07-04 2015-08-03     1 2015-07-23 2017-01-05    TRUE
21:     3     2 2018-09-03  2015-08-04 2015-09-03     1 2015-07-23 2017-01-05    TRUE
22:     3     2 2018-09-03  2015-09-04 2015-10-03     1 2015-07-23 2017-01-05    TRUE
23:     3     2 2018-09-03  2015-10-04 2015-11-03     1 2015-07-23 2017-01-05    TRUE
24:     3     2 2018-09-03  2015-11-04 2015-12-03     1 2015-07-23 2017-01-05    TRUE
25:     3     2 2018-09-03  2015-12-04 2016-01-03     1 2015-07-23 2017-01-05    TRUE
26:     3     2 2018-09-03  2016-01-04 2016-02-03     1 2015-07-23 2017-01-05    TRUE
27:     3     2 2018-09-03  2016-02-04 2016-03-03     1 2015-07-23 2017-01-05    TRUE
28:     3     2 2018-09-03  2016-03-04 2016-04-03     1 2015-07-23 2017-01-05    TRUE
29:     3     2 2018-09-03  2016-04-04 2016-05-03     1 2015-07-23 2017-01-05    TRUE
30:     3     2 2018-09-03  2016-05-04 2016-06-03     1 2015-07-23 2017-01-05    TRUE
31:     3     2 2018-09-03  2016-06-04 2016-07-03     1 2015-07-23 2017-01-05    TRUE
32:     3     2 2018-09-03  2016-07-04 2016-08-03     1 2015-07-23 2017-01-05    TRUE
33:     3     2 2018-09-03  2016-08-04 2016-09-03     1 2015-07-23 2017-01-05    TRUE
34:     3     2 2018-09-03  2016-09-04 2016-10-03     1 2015-07-23 2017-01-05    TRUE
35:     3     2 2018-09-03  2016-10-04 2016-11-03     1 2015-07-23 2017-01-05    TRUE
36:     3     2 2018-09-03  2016-11-04 2016-12-03     1 2015-07-23 2017-01-05    TRUE
37:     3     2 2018-09-03  2016-12-04 2017-01-03     1 2015-07-23 2017-01-05    TRUE
38:     3     2 2018-09-03  2017-01-04 2017-02-03     1 2015-07-23 2017-01-05    TRUE
39:     1     2 2018-09-03  2017-02-04 2017-03-03    NA       <NA>       <NA>   FALSE
40:     1     2 2018-09-03  2017-03-04 2017-04-03    NA       <NA>       <NA>   FALSE
41:     1     2 2018-09-03  2017-04-04 2017-05-03    NA       <NA>       <NA>   FALSE
42:     1     2 2018-09-03  2017-05-04 2017-06-03    NA       <NA>       <NA>   FALSE
43:     1     2 2018-09-03  2017-06-04 2017-07-03    NA       <NA>       <NA>   FALSE
44:     1     2 2018-09-03  2017-07-04 2017-08-03    NA       <NA>       <NA>   FALSE
45:     1     2 2018-09-03  2017-08-04 2017-09-03    NA       <NA>       <NA>   FALSE
46:     1     2 2018-09-03  2017-09-04 2017-10-03    NA       <NA>       <NA>   FALSE
47:     1     2 2018-09-03  2017-10-04 2017-11-03    NA       <NA>       <NA>   FALSE
48:     1     2 2018-09-03  2017-11-04 2017-12-03    NA       <NA>       <NA>   FALSE
49:     1     2 2018-09-03  2017-12-04 2018-01-03    NA       <NA>       <NA>   FALSE
50:     1     2 2018-09-03  2018-01-04 2018-02-03    NA       <NA>       <NA>   FALSE
51:     3     2 2018-09-03  2018-02-04 2018-03-03     2 2018-02-13 2018-06-04    TRUE
52:     3     2 2018-09-03  2018-03-04 2018-04-03     2 2018-02-13 2018-06-04    TRUE
53:     3     2 2018-09-03  2018-04-04 2018-05-03     2 2018-02-13 2018-06-04    TRUE
54:     3     2 2018-09-03  2018-05-04 2018-06-03     2 2018-02-13 2018-06-04    TRUE
55:     3     2 2018-09-03  2018-06-04 2018-07-03     2 2018-02-13 2018-06-04    TRUE
56:     1     2 2018-09-03  2018-07-04 2018-08-03    NA       <NA>       <NA>   FALSE
57:     1     2 2018-09-03  2018-08-04 2018-09-03    NA       <NA>       <NA>   FALSE
    .join    id   end_date month_start  month_end spell      start        end in_care

Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • Ends in question mark (2):
  • Low reputation (0.5):
Posted by: Tobo