Creating new variables for -n exact months to an enddate
04:50 18 Nov 2025

I have datasets that contain information about healthcare use of individuals called data2014-data2021. Each individual has an enddate (called 'limiet' in the code) which can be somewhere in 2014-2021. I want to see if someone received care in -n months prior to the enddate. So for example: if someone has an enddate of 2018-06-09 then 1monthtoend (1mte) should look at 2018-05-09:2018-06-09 and 2mte should look at 2018-04-09:2018-05-09 etc. For each individual i have data regarding dates of their care use per data2014-2021, up until the enddate. For each year it gives a variable with the beginning date of the care (BEGINDATUMZORGPRESTATIE) and the enddate of the care (EINDDATUMZORGPRESTATIE), there can be multiple of these for a single year for an individual, therefore the string split. Given these dates i want to check whether someone received care in each exact month prior to the enddate (if 1 or more days then yes, else no). This goes until 2014-01-01 so thats the limit, but i now put 60 months prior to enddate. The beginning and end dates that are created seem to correctly follow enddate -nmonths. But all values remain 'no' or NA except for 60mte. The code seemed to work properly when using calendar months (i.e., 2015-01-01:2015-01-30), but i need exact months prior to the enddate.

alle_jaren <- 2014:2021
start_boundary <- as.Date("2014-01-01")
max_months_back <- 60

for (jaar in alle_jaren) {

  dataset_naam <- paste0("data", jaar)

  df <- get(dataset_naam)

  result_list <- vector("list", nrow(df))

  for (r in seq_len(nrow(df))) {
    limiet <- as.Date(df$end_date[r])

    month_ends <- as.Date(character())
    current_end <- limiet

    months_back <- 0
    while (current_end >= start_boundary && months_back < max_months_back) {
      month_ends <- c(month_ends, as.Date(current_end))
      current_end <- as.Date(current_end %m-% months(1))
      months_back <- months_back + 1
    }
    
    month_starts <- month_ends %m-% months(1) + days(1)
    month_starts <- as.Date(month_starts)
    month_starts[month_starts < start_boundary] <- start_boundary
    
    month_starts <- rev(month_starts)
    month_ends <- rev(month_ends)

    n_months <- length(month_starts)
    maand_labels <- paste0(n_months:1, "mte")

    zorg_yesno <- rep("No", n_months)
    zorg_types <- rep(NA_character_, n_months)

    jaar_kolommen <- alle_jaren[alle_jaren <= jaar &
                                  paste0("BEGINDATUM_PRESTATIE_", alle_jaren) %in% names(df)]

    for (j in jaar_kolommen) {
      beginkol <- paste0("BEGINDATUM_PRESTATIE_", j)
      eindkol  <- paste0("EINDDATUM_PRESTATIE_", j)
      prodkol  <- paste0("PRODUCTCODE_", j)

      begindata_raw <- df[[beginkol]][r]
      einddata_raw  <- df[[eindkol]][r]
      zorgtypes_raw <- df[[prodkol]][r]

      if (all(is.na(c(begindata_raw, einddata_raw, zorgtypes_raw)))) next

      begin_list <- str_split(begindata_raw, ";")[[1]]
      eind_list  <- str_split(einddata_raw, ";")[[1]]
      prod_list  <- str_split(zorgtypes_raw, ";")[[1]]

      begin_dates <- suppressWarnings(as.Date(begin_list, "%Y%m%d"))
      eind_dates  <- suppressWarnings(as.Date(eind_list, "%Y%m%d"))

      for (i in seq_along(begin_dates)) {
        if (is.na(begin_dates[i]) | is.na(eind_dates[i])) next

        for (m in seq_len(n_months)) {
          start_month <- as.Date(month_starts[m])
          end_month   <- as.Date(month_ends[m])
          
           if(begin_dates[i] <= end_month && eind_dates[i] >= start_month){
            zorg_yesno[m] <- "Yes"
            zorg_types[m] <- ifelse(
              is.na(zorg_types[m]),
              prod_list[i],
              paste0(zorg_types[m], ";", prod_list[i])
            )
          }
        }
      }
    }

    out <- setNames(
      c(zorg_yesno, zorg_types),
      c(paste0("zorg_", maand_labels), paste0("type_", maand_labels))
    )

    result_list[[r]] <- out
  }

  df <- bind_cols(df, bind_rows(result_list))
  assign(dataset_naam, df, envir = .GlobalEnv)
}
r