efu_dir <- "/Users/to909/Partners HealthCare Dropbox/Tianqi Ouyang/Extended Data Collection/Finalized Files/09SEP2026"
# Study IDs differ in formatting between REDCap exports (e.g. `YAL-003` in the
# EFU file vs `Yale-3` in the master). Normalize both sides to
# `<UPPERCASE PREFIX>-<integer>` before joining.
norm_id <- function(x) {
x <- str_trim(x)
prefix <- toupper(str_extract(x, "^[A-Za-z]+"))
prefix <- if_else(prefix == "YAL", "YALE", prefix)
number <- as.integer(str_extract(x, "[0-9]+$"))
paste0(prefix, "-", number)
}
# Field types from the EFU data dictionary
efu_yesno <- c(
"codestatus", "efu_readmit", "efu_readmit_cirrhosiscomp", "efu_readmitaki",
"efu_status", "efu_rrt", "efu_listingstatus", "efu_listing", "efu_lt",
"efu_slkt", "efu_kal", "efu_ltrrt", "efu_90_rrt", "efu_90lt_rrt",
"efu_180_rrt", "efu_180lt_rrt", "efu_1yr_rrt", "efu_1yrlt_rrt"
)
efu_numeric <- c(
"efu_daysreadmit", "efu_readmitscr", "efu_dayslastencounter", "efu_daysdod",
"efu_daysrrtstart", "efu_dayslisting", "efu_dayswlremoval", "efu_dayslt",
"efu_dayskal", "efu_ltna", "efu_lttbili", "efu_ltscr", "efu_lt_albumin",
"efu_lt_inr", "efu_90_scr", "efu_90_readmit", "efu_90lt_scr", "efu_180_scr",
"efu_180_readmit", "efu_180lt_scr", "efu_1yr_scr", "efu_1yr_readmit",
"efu_1yrlt_scr"
)
efu_raw <- list.files(efu_dir, pattern = "_09092026\\.csv$", full.names = TRUE) %>%
set_names(~ str_remove(basename(.x), "_09092026\\.csv$")) %>%
map_dfr(
~ read_csv(.x, col_types = cols(.default = col_character()), show_col_types = FALSE),
.id = "efu_center"
) %>%
mutate(
id_key = norm_id(subjectid),
across(all_of(efu_yesno), as.integer),
# parse_number() keeps below-detection strings such as "<0.2" (-> 0.2)
across(all_of(efu_numeric), readr::parse_number)
) %>%
select(-subjectid)
master <- master %>% mutate(id_key = norm_id(subjectid))
efu_cohort <- master %>%
inner_join(efu_raw, by = "id_key")