Setup

# ── Packages ──────────────────────────────────────────────────────────────────
if (!requireNamespace("pacman", quietly = TRUE)) install.packages("pacman")
pacman::p_load(
  readxl, tableone, lubridate, gt, flextable, officer, fs,
  dplyr, tidyr, ggplot2, broom, forcats, glue, scales, gridExtra, knitr
)

knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE, fig.align = "center")

# ── Source helper functions ───────────────────────────────────────────────────
if (file.exists(params$helper_path)) {
  source(params$helper_path)
  message("Helper functions loaded from: ", params$helper_path)
} else {
  stop("Helper file not found at: ", params$helper_path)
}

# ── Create output directory ──────────────────────────────────────────────────
dir.create(params$export_dir, showWarnings = FALSE, recursive = TRUE)
message("Outputs will be saved to: ", params$export_dir)

Load Both Datasets

# ── Read OLD dataset ─────────────────────────────────────────────────────────
raw_old <- read_excel(params$old_data_path, sheet = params$sheet_name)
message(glue("OLD dataset loaded: {params$old_data_path}"))
message(glue("  Dimensions: {nrow(raw_old)} rows x {ncol(raw_old)} cols"))

# ── Read NEW dataset ─────────────────────────────────────────────────────────
raw_new <- read_excel(params$new_data_path, sheet = params$sheet_name)
message(glue("NEW dataset loaded: {params$new_data_path}"))
message(glue("  Dimensions: {nrow(raw_new)} rows x {ncol(raw_new)} cols"))

# ── Trim trailing rows (if applicable) ───────────────────────────────────────
if (!is.null(params$trim_rows) && length(params$trim_rows) > 0) {
  # Only trim if the dataset has enough rows
  trim_old <- params$trim_rows[params$trim_rows <= nrow(raw_old)]
  trim_new <- params$trim_rows[params$trim_rows <= nrow(raw_new)]

  if (length(trim_old) > 0) {
    raw_old <- raw_old[-trim_old, ]
    message(glue("OLD: Trimmed rows {paste(trim_old, collapse=',')}. New dims: {nrow(raw_old)} x {ncol(raw_old)}"))
  }
  if (length(trim_new) > 0) {
    raw_new <- raw_new[-trim_new, ]
    message(glue("NEW: Trimmed rows {paste(trim_new, collapse=',')}. New dims: {nrow(raw_new)} x {ncol(raw_new)}"))
  }
}

# ── Quick dimension comparison ────────────────────────────────────────────────
dim_compare <- tibble(
  Dataset  = c("OLD", "NEW", "Delta"),
  Rows     = c(nrow(raw_old), nrow(raw_new), nrow(raw_new) - nrow(raw_old)),
  Columns  = c(ncol(raw_old), ncol(raw_new), ncol(raw_new) - ncol(raw_old))
)
knitr::kable(dim_compare, caption = "Dataset Dimension Comparison")
Dataset Dimension Comparison
Dataset Rows Columns
OLD 1304 41
NEW 1304 46
Delta 0 5

Raw Data Comparison

# ── Column differences ────────────────────────────────────────────────────────
cols_old <- names(raw_old)
cols_new <- names(raw_new)

cols_added   <- setdiff(cols_new, cols_old)
cols_removed <- setdiff(cols_old, cols_new)
cols_shared  <- intersect(cols_old, cols_new)

message(glue("Shared columns: {length(cols_shared)}"))
if (length(cols_added) > 0)   message(glue("Columns ADDED in NEW: {paste(cols_added, collapse=', ')}"))
if (length(cols_removed) > 0) message(glue("Columns REMOVED from OLD: {paste(cols_removed, collapse=', ')}"))
if (length(cols_added) == 0 && length(cols_removed) == 0) message("Column names are IDENTICAL between datasets.")

# ── Per-column NA comparison (shared columns only) ────────────────────────────
na_old <- sapply(raw_old[cols_shared], function(x) sum(is.na(x)))
na_new <- sapply(raw_new[cols_shared], function(x) sum(is.na(x)))

na_compare <- tibble(
  Column     = cols_shared,
  NA_Old     = na_old,
  NA_New     = na_new,
  Delta_NA   = na_new - na_old
) %>% dplyr::filter(Delta_NA != 0)  # Show only columns where NAs changed

if (nrow(na_compare) > 0) {
  knitr::kable(na_compare, caption = "Columns Where Missing Value Count Changed")
} else {
  message("No changes in missing value counts across shared columns.")
}

# ── Per-column unique-value comparison ────────────────────────────────────────
uniq_old <- sapply(raw_old[cols_shared], function(x) dplyr::n_distinct(x, na.rm = TRUE))
uniq_new <- sapply(raw_new[cols_shared], function(x) dplyr::n_distinct(x, na.rm = TRUE))

uniq_compare <- tibble(
  Column       = cols_shared,
  Unique_Old   = uniq_old,
  Unique_New   = uniq_new,
  Delta_Unique = uniq_new - uniq_old
) %>% dplyr::filter(Delta_Unique != 0)

if (nrow(uniq_compare) > 0) {
  knitr::kable(uniq_compare, caption = "Columns Where Unique Value Count Changed")
} else {
  message("No changes in unique value counts across shared columns.")
}

Data Wrangling

# ── Apply factor conversions and derived variables to BOTH datasets ───────────
data_old <- convert_factors_and_derive(raw_old)
message(glue("data_old created. Dims: {nrow(data_old)} x {ncol(data_old)}"))

data_new <- convert_factors_and_derive(raw_new)
message(glue("data_new created. Dims: {nrow(data_new)} x {ncol(data_new)}"))

# ── Derive _ordered variables (needed for Tables 3 & 4) ──────────────────────
# These are derived from the _rslt factor columns:
# In unified_helpers.R, NA values → "Not Sent"
derive_ordered_vars <- function(df) {
  df$csfpcr_ordered <- factor(
    ifelse(df$csfpcr_rslt == "Not Sent", 0, 1),
    levels = c(0, 1), labels = c("CSF PCR Not Ordered", "CSF PCR Ordered")
  )
  df$csfigm_ordered <- factor(
    ifelse(df$csfigm_rslt == "Not Sent", 0, 1),
    levels = c(0, 1), labels = c("CSF IgM Not Ordered", "CSF IgM Ordered")
  )
  df$serumigm_ordered <- factor(
    ifelse(df$serumigm_rslt == "Not Sent", 0, 1),
    levels = c(0, 1), labels = c("Serum IgM Not Ordered", "Serum IgM Ordered")
  )
  return(df)
}

data_old <- derive_ordered_vars(data_old)
data_new <- derive_ordered_vars(data_new)

# ── Verify factor level consistency ───────────────────────────────────────────
key_factors <- c("sex", "race", "dead", "medicaid", "site", "service",
                 "immunosup", "transplant", "bcellmed", "guideline2",
                 "wnvpos", "csftp60", "csftnc5", "csflymph50", "inseasontest")

factor_issues <- character(0)
for (fv in key_factors) {
  if (fv %in% names(data_old) && fv %in% names(data_new)) {
    lvl_old <- levels(data_old[[fv]])
    lvl_new <- levels(data_new[[fv]])
    if (!identical(lvl_old, lvl_new)) {
      factor_issues <- c(factor_issues,
        glue("{fv}: OLD levels = [{paste(lvl_old, collapse=', ')}] vs NEW = [{paste(lvl_new, collapse=', ')}]"))
    }
  }
}

if (length(factor_issues) > 0) {
  message("WARNING: Factor level mismatches detected:")
  for (fi in factor_issues) message("  ", fi)
} else {
  message("All key factor variables have identical levels between OLD and NEW datasets.")
}

Table 1: Demographics by Guideline Adherence

# ── Common definitions ────────────────────────────────────────────────────────
table1_vars <- c(
  "sex", "csfageyr", "race", "nonwhite", "dead", "medicaid",
  "site", "service", "immunosup", "transplant", "bcellmed", "csfadmit_day",
  "inseasontest", "serumwbc", "csftp", "csftp60", "csfgluc", "csftnc",
  "csftnc5", "csflymph", "csflymph50"
)
continuous_vars <- c("csfageyr", "serumwbc", "csftp", "csfgluc", "csftnc", "csflymph", "csfadmit_day")
factor_vars_t1 <- setdiff(table1_vars, continuous_vars)

# ── Helper: build a simple TableOne dataframe ─────────────────────────────────
build_tableone_df <- function(data, vars, strata, cont_vars, fac_vars) {
  # Ensure continuous vars are numeric
  data[cont_vars] <- lapply(data[cont_vars], function(x) as.numeric(as.character(x)))

  tobj <- tableone::CreateTableOne(
    vars = vars, strata = strata, data = data,
    factorVars = fac_vars, addOverall = TRUE
  )
  tmat <- print(tobj, nonnormal = cont_vars, showAllLevels = TRUE,
                printToggle = FALSE, noSpaces = TRUE)
  tdf <- as.data.frame(tmat, stringsAsFactors = FALSE)

  # Preserve unique rownames as row_id BEFORE any modifications
  tdf$row_id <- rownames(tdf)

  colnames(tdf)[1] <- "level"
  tdf$level <- trimws(tdf$level)

  # Copy p-values
  fld <- lapply(fac_vars, function(x) levels(data[[x]]))
  names(fld) <- fac_vars
  tdf <- suppressMessages(copyPvalueToAllLevels(tdf, fld))

  # Remove first row (n) and test column
  tdf <- tdf[tdf$level != "n", ]
  if ("test" %in% colnames(tdf)) tdf <- dplyr::select(tdf, -test)
  return(tdf)
}

# ── Helper: build a highlighted delta gt table from two TableOne DFs ──────────
build_delta_gt <- function(df_old, df_new, title_text = "Delta Comparison") {
  # Join by row_id (unique rownames from TableOne) — NOT by level text
  delta <- dplyr::inner_join(
    df_old %>% dplyr::select(row_id, Characteristic = level, Overall_OLD = Overall, p_OLD = p),
    df_new %>% dplyr::select(row_id, Overall_NEW = Overall, p_NEW = p),
    by = "row_id"
  ) %>%
    dplyr::mutate(
      overall_changed = (Overall_OLD != Overall_NEW),
      p_changed = (!is.na(p_OLD) & !is.na(p_NEW) & p_OLD != "" & p_NEW != "" & p_OLD != p_NEW)
    ) %>%
    dplyr::select(Characteristic, Overall_OLD, p_OLD, Overall_NEW, p_NEW, overall_changed, p_changed)

  # Build gt with highlighting
  gt_out <- delta %>%
    dplyr::select(-overall_changed, -p_changed) %>%
    gt::gt() %>%
    gt::tab_header(title = gt::md(paste0("**", title_text, "**"))) %>%
    gt::cols_label(
      Characteristic = "",
      Overall_OLD = gt::md("**Overall (OLD)**"),
      p_OLD       = gt::md("**P (OLD)**"),
      Overall_NEW = gt::md("**Overall (NEW)**"),
      p_NEW       = gt::md("**P (NEW)**")
    ) %>%
    gt::tab_spanner(label = gt::md("**OLD Dataset**"), columns = c(Overall_OLD, p_OLD)) %>%
    gt::tab_spanner(label = gt::md("**NEW Dataset**"), columns = c(Overall_NEW, p_NEW)) %>%
    gt::cols_align(align = "center", columns = c(Overall_OLD, p_OLD, Overall_NEW, p_NEW)) %>%
    gt::cols_align(align = "left", columns = Characteristic) %>%
    gt::tab_options(table.width = gt::pct(100), table.font.size = gt::px(12))

  # Highlight rows where Overall changed
  changed_rows <- which(delta$overall_changed)
  if (length(changed_rows) > 0) {
    gt_out <- gt_out %>%
      gt::tab_style(
        style = gt::cell_fill(color = "#FFFFCC"),
        locations = gt::cells_body(columns = c(Overall_OLD, Overall_NEW), rows = changed_rows)
      )
  }

  # Highlight rows where p-value changed
  p_rows <- which(delta$p_changed)
  if (length(p_rows) > 0) {
    gt_out <- gt_out %>%
      gt::tab_style(
        style = gt::cell_fill(color = "#FFE0B2"),
        locations = gt::cells_body(columns = c(p_OLD, p_NEW), rows = p_rows)
      )
  }

  # Return both the gt object and the raw delta dataframe (for Word export)
  return(list(gt = gt_out, data = delta))
}

# ── Build Table 1 for OLD and NEW ────────────────────────────────────────────
t1_old <- build_tableone_df(data_old, table1_vars, "guideline2", continuous_vars, factor_vars_t1)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: sex"
## [1] "  Factor levels for sex : Male, Female"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of sex : 2"
## [1] "  P-value found for sex : 0.612"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: race"
## [1] "  Factor levels for race : White, Black, Other/Multiple, Unknown"
## [1] "  Rows in df_tableone for these levels: 5, 6, 7, 8, 9"
## [1] "  Rows with p-value in factor levels of race : 5, 9"
## [1] "  P-value found for race : 0.032"
## [1] "  P-value copied to rows: 5, 6, 7, 8, 9"
## [1] "Processing variable: nonwhite"
## [1] "  Factor levels for nonwhite : White, Non-White"
## [1] "  Rows in df_tableone for these levels: 5, 9, 10"
## [1] "  Rows with p-value in factor levels of nonwhite : 5, 9"
## [1] "  P-value found for nonwhite : 0.032"
## [1] "  P-value copied to rows: 5, 9, 10"
## [1] "Processing variable: dead"
## [1] "  Factor levels for dead : Not Reported Dead, Reported Dead"
## [1] "  Rows in df_tableone for these levels: 11, 12"
## [1] "  Rows with p-value in factor levels of dead : 11"
## [1] "  P-value found for dead : 0.172"
## [1] "  P-value copied to rows: 11, 12"
## [1] "Processing variable: medicaid"
## [1] "  Factor levels for medicaid : Other Insurance, Medicaid/Safety Net"
## [1] "  Rows in df_tableone for these levels: 13, 14"
## [1] "  Rows with p-value in factor levels of medicaid : 13"
## [1] "  P-value found for medicaid : 0.246"
## [1] "  P-value copied to rows: 13, 14"
## [1] "Processing variable: site"
## [1] "  Factor levels for site : Mass General Hospital, Brigham and Women's Hospital"
## [1] "  Rows in df_tableone for these levels: 15, 16"
## [1] "  Rows with p-value in factor levels of site : 15"
## [1] "  P-value found for site : <0.001"
## [1] "  P-value copied to rows: 15, 16"
## [1] "Processing variable: service"
## [1] "  Factor levels for service : Neurology, Medicine/Subspecialties, Oncology, Other"
## [1] "  Rows in df_tableone for these levels: 17, 18, 19, 20"
## [1] "  Rows with p-value in factor levels of service : 17"
## [1] "  P-value found for service : <0.001"
## [1] "  P-value copied to rows: 17, 18, 19, 20"
## [1] "Processing variable: immunosup"
## [1] "  Factor levels for immunosup : Not Immunosuppressed, Immunosuppressed"
## [1] "  Rows in df_tableone for these levels: 21, 22"
## [1] "  Rows with p-value in factor levels of immunosup : 21"
## [1] "  P-value found for immunosup : <0.001"
## [1] "  P-value copied to rows: 21, 22"
## [1] "Processing variable: transplant"
## [1] "  Factor levels for transplant : No Transplant History, History of Transplant"
## [1] "  Rows in df_tableone for these levels: 23, 24"
## [1] "  Rows with p-value in factor levels of transplant : 23"
## [1] "  P-value found for transplant : <0.001"
## [1] "  P-value copied to rows: 23, 24"
## [1] "Processing variable: bcellmed"
## [1] "  Factor levels for bcellmed : No B-cell Depleting Meds, B-cell Depletion"
## [1] "  Rows in df_tableone for these levels: 25, 26"
## [1] "  Rows with p-value in factor levels of bcellmed : 25"
## [1] "  P-value found for bcellmed : 0.005"
## [1] "  P-value copied to rows: 25, 26"
## [1] "Processing variable: inseasontest"
## [1] "  Factor levels for inseasontest : Test Sent Off-Season, Test Sent June-Nov"
## [1] "  Rows in df_tableone for these levels: 28, 29"
## [1] "  Rows with p-value in factor levels of inseasontest : 28"
## [1] "  P-value found for inseasontest : 0.369"
## [1] "  P-value copied to rows: 28, 29"
## [1] "Processing variable: csftp60"
## [1] "  Factor levels for csftp60 : CSF TP < 60, CSF TP ≥ 60"
## [1] "  Rows in df_tableone for these levels: 32, 33"
## [1] "  Rows with p-value in factor levels of csftp60 : 32"
## [1] "  P-value found for csftp60 : <0.001"
## [1] "  P-value copied to rows: 32, 33"
## [1] "Processing variable: csftnc5"
## [1] "  Factor levels for csftnc5 : CSF TNC < 5, CSF TNC ≥ 5"
## [1] "  Rows in df_tableone for these levels: 36, 37"
## [1] "  Rows with p-value in factor levels of csftnc5 : 36"
## [1] "  P-value found for csftnc5 : <0.001"
## [1] "  P-value copied to rows: 36, 37"
## [1] "Processing variable: csflymph50"
## [1] "  Factor levels for csflymph50 : Normal CSF Cell Count (CSF TNC < 5), Pleocytosis (Lymph ≥ 50%), Pleocytosis (Lymph < 50%)"
## [1] "  Rows in df_tableone for these levels: 39, 40, 41"
## [1] "  Rows with p-value in factor levels of csflymph50 : 39"
## [1] "  P-value found for csflymph50 : <0.001"
## [1] "  P-value copied to rows: 39, 40, 41"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
t1_new <- build_tableone_df(data_new, table1_vars, "guideline2", continuous_vars, factor_vars_t1)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: sex"
## [1] "  Factor levels for sex : Male, Female"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of sex : 2"
## [1] "  P-value found for sex : 0.646"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: race"
## [1] "  Factor levels for race : White, Black, Other/Multiple, Unknown"
## [1] "  Rows in df_tableone for these levels: 5, 6, 7, 8, 9"
## [1] "  Rows with p-value in factor levels of race : 5, 9"
## [1] "  P-value found for race : 0.052"
## [1] "  P-value copied to rows: 5, 6, 7, 8, 9"
## [1] "Processing variable: nonwhite"
## [1] "  Factor levels for nonwhite : White, Non-White"
## [1] "  Rows in df_tableone for these levels: 5, 9, 10"
## [1] "  Rows with p-value in factor levels of nonwhite : 5, 9"
## [1] "  P-value found for nonwhite : 0.052"
## [1] "  P-value copied to rows: 5, 9, 10"
## [1] "Processing variable: dead"
## [1] "  Factor levels for dead : Not Reported Dead, Reported Dead"
## [1] "  Rows in df_tableone for these levels: 11, 12"
## [1] "  Rows with p-value in factor levels of dead : 11"
## [1] "  P-value found for dead : 0.213"
## [1] "  P-value copied to rows: 11, 12"
## [1] "Processing variable: medicaid"
## [1] "  Factor levels for medicaid : Other Insurance, Medicaid/Safety Net"
## [1] "  Rows in df_tableone for these levels: 13, 14"
## [1] "  Rows with p-value in factor levels of medicaid : 13"
## [1] "  P-value found for medicaid : 0.143"
## [1] "  P-value copied to rows: 13, 14"
## [1] "Processing variable: site"
## [1] "  Factor levels for site : Mass General Hospital, Brigham and Women's Hospital"
## [1] "  Rows in df_tableone for these levels: 15, 16"
## [1] "  Rows with p-value in factor levels of site : 15"
## [1] "  P-value found for site : <0.001"
## [1] "  P-value copied to rows: 15, 16"
## [1] "Processing variable: service"
## [1] "  Factor levels for service : Neurology, Medicine/Subspecialties, Oncology, Other"
## [1] "  Rows in df_tableone for these levels: 17, 18, 19, 20"
## [1] "  Rows with p-value in factor levels of service : 17"
## [1] "  P-value found for service : <0.001"
## [1] "  P-value copied to rows: 17, 18, 19, 20"
## [1] "Processing variable: immunosup"
## [1] "  Factor levels for immunosup : Not Immunosuppressed, Immunosuppressed"
## [1] "  Rows in df_tableone for these levels: 21, 22"
## [1] "  Rows with p-value in factor levels of immunosup : 21"
## [1] "  P-value found for immunosup : <0.001"
## [1] "  P-value copied to rows: 21, 22"
## [1] "Processing variable: transplant"
## [1] "  Factor levels for transplant : No Transplant History, History of Transplant"
## [1] "  Rows in df_tableone for these levels: 23, 24"
## [1] "  Rows with p-value in factor levels of transplant : 23"
## [1] "  P-value found for transplant : <0.001"
## [1] "  P-value copied to rows: 23, 24"
## [1] "Processing variable: bcellmed"
## [1] "  Factor levels for bcellmed : No B-cell Depleting Meds, B-cell Depletion"
## [1] "  Rows in df_tableone for these levels: 25, 26"
## [1] "  Rows with p-value in factor levels of bcellmed : 25"
## [1] "  P-value found for bcellmed : 0.005"
## [1] "  P-value copied to rows: 25, 26"
## [1] "Processing variable: inseasontest"
## [1] "  Factor levels for inseasontest : Test Sent Off-Season, Test Sent June-Nov"
## [1] "  Rows in df_tableone for these levels: 28, 29"
## [1] "  Rows with p-value in factor levels of inseasontest : 28"
## [1] "  P-value found for inseasontest : 0.308"
## [1] "  P-value copied to rows: 28, 29"
## [1] "Processing variable: csftp60"
## [1] "  Factor levels for csftp60 : CSF TP < 60, CSF TP ≥ 60"
## [1] "  Rows in df_tableone for these levels: 32, 33"
## [1] "  Rows with p-value in factor levels of csftp60 : 32"
## [1] "  P-value found for csftp60 : <0.001"
## [1] "  P-value copied to rows: 32, 33"
## [1] "Processing variable: csftnc5"
## [1] "  Factor levels for csftnc5 : CSF TNC < 5, CSF TNC ≥ 5"
## [1] "  Rows in df_tableone for these levels: 36, 37"
## [1] "  Rows with p-value in factor levels of csftnc5 : 36"
## [1] "  P-value found for csftnc5 : <0.001"
## [1] "  P-value copied to rows: 36, 37"
## [1] "Processing variable: csflymph50"
## [1] "  Factor levels for csflymph50 : Normal CSF Cell Count (CSF TNC < 5), Pleocytosis (Lymph ≥ 50%), Pleocytosis (Lymph < 50%)"
## [1] "  Rows in df_tableone for these levels: 39, 40, 41"
## [1] "  Rows with p-value in factor levels of csflymph50 : 39"
## [1] "  P-value found for csflymph50 : <0.001"
## [1] "  P-value copied to rows: 39, 40, 41"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
# ── Display both tables ──────────────────────────────────────────────────────
cat("### Table 1 — OLD Dataset\n")
## ### Table 1 — OLD Dataset
knitr::kable(t1_old, caption = "Table 1 (OLD): Demographics & Lab Values by Guideline Adherence")
Table 1 (OLD): Demographics & Lab Values by Guideline Adherence
level Overall Adherent Nonadherent p row_id
n 1304 333 971 n
sex…. Male 703 (53.9) 184 (55.3) 519 (53.5) 0.612 sex….
X Female 601 (46.1) 149 (44.7) 452 (46.5) 0.612 X
csfageyr..median..IQR.. 63.00 [48.00, 73.00] 62.00 [44.00, 74.00] 64.00 [50.00, 73.00] 0.072 csfageyr..median..IQR..
race…. White 994 (76.2) 254 (76.3) 740 (76.2) 0.032 race….
X.1 Black 105 (8.1) 16 (4.8) 89 (9.2) 0.032 X.1
X.2 Other/Multiple 129 (9.9) 39 (11.7) 90 (9.3) 0.032 X.2
X.3 Unknown 76 (5.8) 24 (7.2) 52 (5.4) 0.032 X.3
nonwhite…. White 1070 (82.1) 278 (83.5) 792 (81.6) 0.032 nonwhite….
X.4 Non-White 234 (17.9) 55 (16.5) 179 (18.4) 0.032 X.4
dead…. Not Reported Dead 915 (70.2) 244 (73.3) 671 (69.1) 0.172 dead….
X.5 Reported Dead 389 (29.8) 89 (26.7) 300 (30.9) 0.172 X.5
medicaid…. Other Insurance 933 (71.5) 247 (74.2) 686 (70.6) 0.246 medicaid….
X.6 Medicaid/Safety Net 371 (28.5) 86 (25.8) 285 (29.4) 0.246 X.6
site…. Mass General Hospital 706 (54.1) 231 (69.4) 475 (48.9) <0.001 site….
X.7 Brigham and Women’s Hospital 598 (45.9) 102 (30.6) 496 (51.1) <0.001 X.7
service…. Neurology 584 (44.8) 210 (63.1) 374 (38.5) <0.001 service….
X.8 Medicine/Subspecialties 456 (35.0) 87 (26.1) 369 (38.0) <0.001 X.8
X.9 Oncology 178 (13.7) 22 (6.6) 156 (16.1) <0.001 X.9
X.10 Other 86 (6.6) 14 (4.2) 72 (7.4) <0.001 X.10
immunosup…. Not Immunosuppressed 1133 (86.9) 320 (96.1) 813 (83.7) <0.001 immunosup….
X.11 Immunosuppressed 171 (13.1) 13 (3.9) 158 (16.3) <0.001 X.11
transplant…. No Transplant History 1160 (89.0) 321 (96.4) 839 (86.4) <0.001 transplant….
X.12 History of Transplant 144 (11.0) 12 (3.6) 132 (13.6) <0.001 X.12
bcellmed…. No B-cell Depleting Meds 1271 (97.5) 332 (99.7) 939 (96.7) 0.005 bcellmed….
X.13 B-cell Depletion 33 (2.5) 1 (0.3) 32 (3.3) 0.005 X.13
csfadmit_day..median..IQR.. 1.00 [1.00, 4.00] 2.00 [1.00, 4.00] 1.00 [1.00, 4.00] 0.756 csfadmit_day..median..IQR..
inseasontest…. Test Sent Off-Season 479 (36.7) 115 (34.5) 364 (37.5) 0.369 inseasontest….
X.14 Test Sent June-Nov 825 (63.3) 218 (65.5) 607 (62.5) 0.369 X.14
serumwbc..median..IQR.. 8.17 [5.68, 11.40] 8.46 [6.38, 11.29] 8.07 [5.47, 11.47] 0.171 serumwbc..median..IQR..
csftp..median..IQR.. 47.50 [31.70, 78.05] 57.50 [37.00, 92.60] 45.00 [30.00, 69.90] <0.001 csftp..median..IQR..
csftp60…. CSF TP < 60 834 (64.0) 172 (51.7) 662 (68.2) <0.001 csftp60….
X.15 CSF TP ≥ 60 469 (36.0) 161 (48.3) 308 (31.8) <0.001 X.15
csfgluc..median..IQR.. 68.00 [58.00, 85.00] 66.00 [56.00, 81.00] 69.00 [59.00, 86.00] 0.001 csfgluc..median..IQR..
csftnc..median..IQR.. 3.00 [1.00, 21.00] 13.00 [2.00, 77.00] 2.00 [1.00, 10.00] <0.001 csftnc..median..IQR..
csftnc5…. CSF TNC < 5 769 (59.0) 125 (37.5) 644 (66.3) <0.001 csftnc5….
X.16 CSF TNC ≥ 5 535 (41.0) 208 (62.5) 327 (33.7) <0.001 X.16
csflymph..median..IQR.. 66.00 [25.00, 86.00] 74.00 [39.00, 89.00] 62.00 [20.00, 85.00] <0.001 csflymph..median..IQR..
csflymph50…. Normal CSF Cell Count (CSF TNC < 5) 769 (59.0) 125 (37.5) 644 (66.3) <0.001 csflymph50….
X.17 Pleocytosis (Lymph ≥ 50%) 350 (26.8) 153 (45.9) 197 (20.3) <0.001 X.17
X.18 Pleocytosis (Lymph < 50%) 185 (14.2) 55 (16.5) 130 (13.4) <0.001 X.18
cat("\n### Table 1 — NEW Dataset\n")
## 
## ### Table 1 — NEW Dataset
knitr::kable(t1_new, caption = "Table 1 (NEW): Demographics & Lab Values by Guideline Adherence")
Table 1 (NEW): Demographics & Lab Values by Guideline Adherence
level Overall Adherent Nonadherent p row_id
n 1304 330 974 n
sex…. Male 703 (53.9) 182 (55.2) 521 (53.5) 0.646 sex….
X Female 601 (46.1) 148 (44.8) 453 (46.5) 0.646 X
csfageyr..median..IQR.. 63.00 [48.00, 73.00] 62.00 [44.75, 74.00] 64.00 [49.00, 73.00] 0.116 csfageyr..median..IQR..
race…. White 994 (76.2) 254 (77.0) 740 (76.0) 0.052 race….
X.1 Black 105 (8.1) 16 (4.8) 89 (9.1) 0.052 X.1
X.2 Other/Multiple 129 (9.9) 36 (10.9) 93 (9.5) 0.052 X.2
X.3 Unknown 76 (5.8) 24 (7.3) 52 (5.3) 0.052 X.3
nonwhite…. White 1070 (82.1) 278 (84.2) 792 (81.3) 0.052 nonwhite….
X.4 Non-White 234 (17.9) 52 (15.8) 182 (18.7) 0.052 X.4
dead…. Not Reported Dead 915 (70.2) 241 (73.0) 674 (69.2) 0.213 dead….
X.5 Reported Dead 389 (29.8) 89 (27.0) 300 (30.8) 0.213 X.5
medicaid…. Other Insurance 933 (71.5) 247 (74.8) 686 (70.4) 0.143 medicaid….
X.6 Medicaid/Safety Net 371 (28.5) 83 (25.2) 288 (29.6) 0.143 X.6
site…. Mass General Hospital 706 (54.1) 229 (69.4) 477 (49.0) <0.001 site….
X.7 Brigham and Women’s Hospital 598 (45.9) 101 (30.6) 497 (51.0) <0.001 X.7
service…. Neurology 584 (44.8) 208 (63.0) 376 (38.6) <0.001 service….
X.8 Medicine/Subspecialties 456 (35.0) 86 (26.1) 370 (38.0) <0.001 X.8
X.9 Oncology 178 (13.7) 22 (6.7) 156 (16.0) <0.001 X.9
X.10 Other 86 (6.6) 14 (4.2) 72 (7.4) <0.001 X.10
immunosup…. Not Immunosuppressed 1114 (85.4) 317 (96.1) 797 (81.8) <0.001 immunosup….
X.11 Immunosuppressed 190 (14.6) 13 (3.9) 177 (18.2) <0.001 X.11
transplant…. No Transplant History 1160 (89.0) 318 (96.4) 842 (86.4) <0.001 transplant….
X.12 History of Transplant 144 (11.0) 12 (3.6) 132 (13.6) <0.001 X.12
bcellmed…. No B-cell Depleting Meds 1271 (97.5) 329 (99.7) 942 (96.7) 0.005 bcellmed….
X.13 B-cell Depletion 33 (2.5) 1 (0.3) 32 (3.3) 0.005 X.13
csfadmit_day..median..IQR.. 1.00 [1.00, 4.00] 2.00 [1.00, 4.00] 1.00 [1.00, 4.00] 0.819 csfadmit_day..median..IQR..
inseasontest…. Test Sent Off-Season 479 (36.7) 113 (34.2) 366 (37.6) 0.308 inseasontest….
X.14 Test Sent June-Nov 825 (63.3) 217 (65.8) 608 (62.4) 0.308 X.14
serumwbc..median..IQR.. 8.17 [5.68, 11.40] 8.50 [6.43, 11.30] 8.07 [5.46, 11.46] 0.117 serumwbc..median..IQR..
csftp..median..IQR.. 47.50 [31.70, 78.05] 57.05 [36.78, 92.60] 45.00 [30.00, 70.00] <0.001 csftp..median..IQR..
csftp60…. CSF TP < 60 834 (64.0) 172 (52.1) 662 (68.0) <0.001 csftp60….
X.15 CSF TP ≥ 60 469 (36.0) 158 (47.9) 311 (32.0) <0.001 X.15
csfgluc..median..IQR.. 68.00 [58.00, 85.00] 66.00 [56.00, 81.00] 69.00 [59.00, 86.00] 0.003 csfgluc..median..IQR..
csftnc..median..IQR.. 3.00 [1.00, 21.00] 13.00 [2.00, 74.75] 2.00 [1.00, 10.00] <0.001 csftnc..median..IQR..
csftnc5…. CSF TNC < 5 769 (59.0) 124 (37.6) 645 (66.2) <0.001 csftnc5….
X.16 CSF TNC ≥ 5 535 (41.0) 206 (62.4) 329 (33.8) <0.001 X.16
csflymph..median..IQR.. 66.00 [25.00, 86.00] 74.00 [39.00, 89.00] 62.00 [20.00, 85.00] <0.001 csflymph..median..IQR..
csflymph50…. Normal CSF Cell Count (CSF TNC < 5) 769 (59.0) 124 (37.6) 645 (66.2) <0.001 csflymph50….
X.17 Pleocytosis (Lymph ≥ 50%) 350 (26.8) 151 (45.8) 199 (20.4) <0.001 X.17
X.18 Pleocytosis (Lymph < 50%) 185 (14.2) 55 (16.7) 130 (13.3) <0.001 X.18
# ── Delta table with highlighting ─────────────────────────────────────────────
delta_t1_result <- build_delta_gt(t1_old, t1_new, "Table 1 Delta: Demographics by Guideline Adherence")
delta_t1 <- delta_t1_result$data
delta_t1_result$gt
Table 1 Delta: Demographics by Guideline Adherence
OLD Dataset NEW Dataset
Overall (OLD) P (OLD) Overall (NEW) P (NEW)
1304 1304
Male 703 (53.9) 0.612 703 (53.9) 0.646
Female 601 (46.1) 0.612 601 (46.1) 0.646
63.00 [48.00, 73.00] 0.072 63.00 [48.00, 73.00] 0.116
White 994 (76.2) 0.032 994 (76.2) 0.052
Black 105 (8.1) 0.032 105 (8.1) 0.052
Other/Multiple 129 (9.9) 0.032 129 (9.9) 0.052
Unknown 76 (5.8) 0.032 76 (5.8) 0.052
White 1070 (82.1) 0.032 1070 (82.1) 0.052
Non-White 234 (17.9) 0.032 234 (17.9) 0.052
Not Reported Dead 915 (70.2) 0.172 915 (70.2) 0.213
Reported Dead 389 (29.8) 0.172 389 (29.8) 0.213
Other Insurance 933 (71.5) 0.246 933 (71.5) 0.143
Medicaid/Safety Net 371 (28.5) 0.246 371 (28.5) 0.143
Mass General Hospital 706 (54.1) <0.001 706 (54.1) <0.001
Brigham and Women's Hospital 598 (45.9) <0.001 598 (45.9) <0.001
Neurology 584 (44.8) <0.001 584 (44.8) <0.001
Medicine/Subspecialties 456 (35.0) <0.001 456 (35.0) <0.001
Oncology 178 (13.7) <0.001 178 (13.7) <0.001
Other 86 (6.6) <0.001 86 (6.6) <0.001
Not Immunosuppressed 1133 (86.9) <0.001 1114 (85.4) <0.001
Immunosuppressed 171 (13.1) <0.001 190 (14.6) <0.001
No Transplant History 1160 (89.0) <0.001 1160 (89.0) <0.001
History of Transplant 144 (11.0) <0.001 144 (11.0) <0.001
No B-cell Depleting Meds 1271 (97.5) 0.005 1271 (97.5) 0.005
B-cell Depletion 33 (2.5) 0.005 33 (2.5) 0.005
1.00 [1.00, 4.00] 0.756 1.00 [1.00, 4.00] 0.819
Test Sent Off-Season 479 (36.7) 0.369 479 (36.7) 0.308
Test Sent June-Nov 825 (63.3) 0.369 825 (63.3) 0.308
8.17 [5.68, 11.40] 0.171 8.17 [5.68, 11.40] 0.117
47.50 [31.70, 78.05] <0.001 47.50 [31.70, 78.05] <0.001
CSF TP < 60 834 (64.0) <0.001 834 (64.0) <0.001
CSF TP ≥ 60 469 (36.0) <0.001 469 (36.0) <0.001
68.00 [58.00, 85.00] 0.001 68.00 [58.00, 85.00] 0.003
3.00 [1.00, 21.00] <0.001 3.00 [1.00, 21.00] <0.001
CSF TNC < 5 769 (59.0) <0.001 769 (59.0) <0.001
CSF TNC ≥ 5 535 (41.0) <0.001 535 (41.0) <0.001
66.00 [25.00, 86.00] <0.001 66.00 [25.00, 86.00] <0.001
Normal CSF Cell Count (CSF TNC < 5) 769 (59.0) <0.001 769 (59.0) <0.001
Pleocytosis (Lymph ≥ 50%) 350 (26.8) <0.001 350 (26.8) <0.001
Pleocytosis (Lymph < 50%) 185 (14.2) <0.001 185 (14.2) <0.001

Table New: Demographics by Immune Status

# ── Build for OLD and NEW stratified by immunosup ─────────────────────────────
tn_old <- build_tableone_df(data_old, table1_vars, "immunosup", continuous_vars, factor_vars_t1)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: sex"
## [1] "  Factor levels for sex : Male, Female"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of sex : 2"
## [1] "  P-value found for sex : 0.090"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: race"
## [1] "  Factor levels for race : White, Black, Other/Multiple, Unknown"
## [1] "  Rows in df_tableone for these levels: 5, 6, 7, 8, 9"
## [1] "  Rows with p-value in factor levels of race : 5, 9"
## [1] "  P-value found for race : 0.074"
## [1] "  P-value copied to rows: 5, 6, 7, 8, 9"
## [1] "Processing variable: nonwhite"
## [1] "  Factor levels for nonwhite : White, Non-White"
## [1] "  Rows in df_tableone for these levels: 5, 9, 10"
## [1] "  Rows with p-value in factor levels of nonwhite : 5, 9"
## [1] "  P-value found for nonwhite : 0.074"
## [1] "  P-value copied to rows: 5, 9, 10"
## [1] "Processing variable: dead"
## [1] "  Factor levels for dead : Not Reported Dead, Reported Dead"
## [1] "  Rows in df_tableone for these levels: 11, 12"
## [1] "  Rows with p-value in factor levels of dead : 11"
## [1] "  P-value found for dead : <0.001"
## [1] "  P-value copied to rows: 11, 12"
## [1] "Processing variable: medicaid"
## [1] "  Factor levels for medicaid : Other Insurance, Medicaid/Safety Net"
## [1] "  Rows in df_tableone for these levels: 13, 14"
## [1] "  Rows with p-value in factor levels of medicaid : 13"
## [1] "  P-value found for medicaid : 0.696"
## [1] "  P-value copied to rows: 13, 14"
## [1] "Processing variable: site"
## [1] "  Factor levels for site : Mass General Hospital, Brigham and Women's Hospital"
## [1] "  Rows in df_tableone for these levels: 15, 16"
## [1] "  Rows with p-value in factor levels of site : 15"
## [1] "  P-value found for site : <0.001"
## [1] "  P-value copied to rows: 15, 16"
## [1] "Processing variable: service"
## [1] "  Factor levels for service : Neurology, Medicine/Subspecialties, Oncology, Other"
## [1] "  Rows in df_tableone for these levels: 17, 18, 19, 20"
## [1] "  Rows with p-value in factor levels of service : 17"
## [1] "  P-value found for service : <0.001"
## [1] "  P-value copied to rows: 17, 18, 19, 20"
## [1] "Processing variable: immunosup"
## [1] "  Factor levels for immunosup : Not Immunosuppressed, Immunosuppressed"
## [1] "  Rows in df_tableone for these levels: 21, 22"
## [1] "  Rows with p-value in factor levels of immunosup : 21"
## [1] "  P-value found for immunosup : <0.001"
## [1] "  P-value copied to rows: 21, 22"
## [1] "Processing variable: transplant"
## [1] "  Factor levels for transplant : No Transplant History, History of Transplant"
## [1] "  Rows in df_tableone for these levels: 23, 24"
## [1] "  Rows with p-value in factor levels of transplant : 23"
## [1] "  P-value found for transplant : <0.001"
## [1] "  P-value copied to rows: 23, 24"
## [1] "Processing variable: bcellmed"
## [1] "  Factor levels for bcellmed : No B-cell Depleting Meds, B-cell Depletion"
## [1] "  Rows in df_tableone for these levels: 25, 26"
## [1] "  Rows with p-value in factor levels of bcellmed : 25"
## [1] "  P-value found for bcellmed : <0.001"
## [1] "  P-value copied to rows: 25, 26"
## [1] "Processing variable: inseasontest"
## [1] "  Factor levels for inseasontest : Test Sent Off-Season, Test Sent June-Nov"
## [1] "  Rows in df_tableone for these levels: 28, 29"
## [1] "  Rows with p-value in factor levels of inseasontest : 28"
## [1] "  P-value found for inseasontest : 0.255"
## [1] "  P-value copied to rows: 28, 29"
## [1] "Processing variable: csftp60"
## [1] "  Factor levels for csftp60 : CSF TP < 60, CSF TP ≥ 60"
## [1] "  Rows in df_tableone for these levels: 32, 33"
## [1] "  Rows with p-value in factor levels of csftp60 : 32"
## [1] "  P-value found for csftp60 : 0.645"
## [1] "  P-value copied to rows: 32, 33"
## [1] "Processing variable: csftnc5"
## [1] "  Factor levels for csftnc5 : CSF TNC < 5, CSF TNC ≥ 5"
## [1] "  Rows in df_tableone for these levels: 36, 37"
## [1] "  Rows with p-value in factor levels of csftnc5 : 36"
## [1] "  P-value found for csftnc5 : 0.658"
## [1] "  P-value copied to rows: 36, 37"
## [1] "Processing variable: csflymph50"
## [1] "  Factor levels for csflymph50 : Normal CSF Cell Count (CSF TNC < 5), Pleocytosis (Lymph ≥ 50%), Pleocytosis (Lymph < 50%)"
## [1] "  Rows in df_tableone for these levels: 39, 40, 41"
## [1] "  Rows with p-value in factor levels of csflymph50 : 39"
## [1] "  P-value found for csflymph50 : 0.651"
## [1] "  P-value copied to rows: 39, 40, 41"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
tn_new <- build_tableone_df(data_new, table1_vars, "immunosup", continuous_vars, factor_vars_t1)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: sex"
## [1] "  Factor levels for sex : Male, Female"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of sex : 2"
## [1] "  P-value found for sex : 0.040"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: race"
## [1] "  Factor levels for race : White, Black, Other/Multiple, Unknown"
## [1] "  Rows in df_tableone for these levels: 5, 6, 7, 8, 9"
## [1] "  Rows with p-value in factor levels of race : 5, 9"
## [1] "  P-value found for race : 0.615"
## [1] "  P-value copied to rows: 5, 6, 7, 8, 9"
## [1] "Processing variable: nonwhite"
## [1] "  Factor levels for nonwhite : White, Non-White"
## [1] "  Rows in df_tableone for these levels: 5, 9, 10"
## [1] "  Rows with p-value in factor levels of nonwhite : 5, 9"
## [1] "  P-value found for nonwhite : 0.615"
## [1] "  P-value copied to rows: 5, 9, 10"
## [1] "Processing variable: dead"
## [1] "  Factor levels for dead : Not Reported Dead, Reported Dead"
## [1] "  Rows in df_tableone for these levels: 11, 12"
## [1] "  Rows with p-value in factor levels of dead : 11"
## [1] "  P-value found for dead : <0.001"
## [1] "  P-value copied to rows: 11, 12"
## [1] "Processing variable: medicaid"
## [1] "  Factor levels for medicaid : Other Insurance, Medicaid/Safety Net"
## [1] "  Rows in df_tableone for these levels: 13, 14"
## [1] "  Rows with p-value in factor levels of medicaid : 13"
## [1] "  P-value found for medicaid : 0.262"
## [1] "  P-value copied to rows: 13, 14"
## [1] "Processing variable: site"
## [1] "  Factor levels for site : Mass General Hospital, Brigham and Women's Hospital"
## [1] "  Rows in df_tableone for these levels: 15, 16"
## [1] "  Rows with p-value in factor levels of site : 15"
## [1] "  P-value found for site : <0.001"
## [1] "  P-value copied to rows: 15, 16"
## [1] "Processing variable: service"
## [1] "  Factor levels for service : Neurology, Medicine/Subspecialties, Oncology, Other"
## [1] "  Rows in df_tableone for these levels: 17, 18, 19, 20"
## [1] "  Rows with p-value in factor levels of service : 17"
## [1] "  P-value found for service : <0.001"
## [1] "  P-value copied to rows: 17, 18, 19, 20"
## [1] "Processing variable: immunosup"
## [1] "  Factor levels for immunosup : Not Immunosuppressed, Immunosuppressed"
## [1] "  Rows in df_tableone for these levels: 21, 22"
## [1] "  Rows with p-value in factor levels of immunosup : 21"
## [1] "  P-value found for immunosup : <0.001"
## [1] "  P-value copied to rows: 21, 22"
## [1] "Processing variable: transplant"
## [1] "  Factor levels for transplant : No Transplant History, History of Transplant"
## [1] "  Rows in df_tableone for these levels: 23, 24"
## [1] "  Rows with p-value in factor levels of transplant : 23"
## [1] "  P-value found for transplant : <0.001"
## [1] "  P-value copied to rows: 23, 24"
## [1] "Processing variable: bcellmed"
## [1] "  Factor levels for bcellmed : No B-cell Depleting Meds, B-cell Depletion"
## [1] "  Rows in df_tableone for these levels: 25, 26"
## [1] "  Rows with p-value in factor levels of bcellmed : 25"
## [1] "  P-value found for bcellmed : <0.001"
## [1] "  P-value copied to rows: 25, 26"
## [1] "Processing variable: inseasontest"
## [1] "  Factor levels for inseasontest : Test Sent Off-Season, Test Sent June-Nov"
## [1] "  Rows in df_tableone for these levels: 28, 29"
## [1] "  Rows with p-value in factor levels of inseasontest : 28"
## [1] "  P-value found for inseasontest : 0.210"
## [1] "  P-value copied to rows: 28, 29"
## [1] "Processing variable: csftp60"
## [1] "  Factor levels for csftp60 : CSF TP < 60, CSF TP ≥ 60"
## [1] "  Rows in df_tableone for these levels: 32, 33"
## [1] "  Rows with p-value in factor levels of csftp60 : 32"
## [1] "  P-value found for csftp60 : 0.931"
## [1] "  P-value copied to rows: 32, 33"
## [1] "Processing variable: csftnc5"
## [1] "  Factor levels for csftnc5 : CSF TNC < 5, CSF TNC ≥ 5"
## [1] "  Rows in df_tableone for these levels: 36, 37"
## [1] "  Rows with p-value in factor levels of csftnc5 : 36"
## [1] "  P-value found for csftnc5 : 0.582"
## [1] "  P-value copied to rows: 36, 37"
## [1] "Processing variable: csflymph50"
## [1] "  Factor levels for csflymph50 : Normal CSF Cell Count (CSF TNC < 5), Pleocytosis (Lymph ≥ 50%), Pleocytosis (Lymph < 50%)"
## [1] "  Rows in df_tableone for these levels: 39, 40, 41"
## [1] "  Rows with p-value in factor levels of csflymph50 : 39"
## [1] "  P-value found for csflymph50 : 0.767"
## [1] "  P-value copied to rows: 39, 40, 41"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
cat("### Table New — OLD Dataset\n")
## ### Table New — OLD Dataset
knitr::kable(tn_old, caption = "Table New (OLD): Demographics & Lab Values by Immune Status")
Table New (OLD): Demographics & Lab Values by Immune Status
level Overall Not Immunosuppressed Immunosuppressed p row_id
n 1304 1133 171 n
sex…. Male 703 (53.9) 600 (53.0) 103 (60.2) 0.090 sex….
X Female 601 (46.1) 533 (47.0) 68 (39.8) 0.090 X
csfageyr..median..IQR.. 63.00 [48.00, 73.00] 63.00 [47.00, 73.15] 65.00 [57.50, 71.50] 0.108 csfageyr..median..IQR..
race…. White 994 (76.2) 850 (75.0) 144 (84.2) 0.074 race….
X.1 Black 105 (8.1) 96 (8.5) 9 (5.3) 0.074 X.1
X.2 Other/Multiple 129 (9.9) 118 (10.4) 11 (6.4) 0.074 X.2
X.3 Unknown 76 (5.8) 69 (6.1) 7 (4.1) 0.074 X.3
nonwhite…. White 1070 (82.1) 919 (81.1) 151 (88.3) 0.074 nonwhite….
X.4 Non-White 234 (17.9) 214 (18.9) 20 (11.7) 0.074 X.4
dead…. Not Reported Dead 915 (70.2) 838 (74.0) 77 (45.0) <0.001 dead….
X.5 Reported Dead 389 (29.8) 295 (26.0) 94 (55.0) <0.001 X.5
medicaid…. Other Insurance 933 (71.5) 808 (71.3) 125 (73.1) 0.696 medicaid….
X.6 Medicaid/Safety Net 371 (28.5) 325 (28.7) 46 (26.9) 0.696 X.6
site…. Mass General Hospital 706 (54.1) 655 (57.8) 51 (29.8) <0.001 site….
X.7 Brigham and Women’s Hospital 598 (45.9) 478 (42.2) 120 (70.2) <0.001 X.7
service…. Neurology 584 (44.8) 564 (49.8) 20 (11.7) <0.001 service….
X.8 Medicine/Subspecialties 456 (35.0) 403 (35.6) 53 (31.0) <0.001 X.8
X.9 Oncology 178 (13.7) 96 (8.5) 82 (48.0) <0.001 X.9
X.10 Other 86 (6.6) 70 (6.2) 16 (9.4) <0.001 X.10
immunosup…. Not Immunosuppressed 1133 (86.9) 1133 (100.0) 0 (0.0) <0.001 immunosup….
X.11 Immunosuppressed 171 (13.1) 0 (0.0) 171 (100.0) <0.001 X.11
transplant…. No Transplant History 1160 (89.0) 1133 (100.0) 27 (15.8) <0.001 transplant….
X.12 History of Transplant 144 (11.0) 0 (0.0) 144 (84.2) <0.001 X.12
bcellmed…. No B-cell Depleting Meds 1271 (97.5) 1133 (100.0) 138 (80.7) <0.001 bcellmed….
X.13 B-cell Depletion 33 (2.5) 0 (0.0) 33 (19.3) <0.001 X.13
csfadmit_day..median..IQR.. 1.00 [1.00, 4.00] 1.00 [0.00, 3.00] 4.00 [1.00, 11.00] <0.001 csfadmit_day..median..IQR..
inseasontest…. Test Sent Off-Season 479 (36.7) 409 (36.1) 70 (40.9) 0.255 inseasontest….
X.14 Test Sent June-Nov 825 (63.3) 724 (63.9) 101 (59.1) 0.255 X.14
serumwbc..median..IQR.. 8.17 [5.68, 11.40] 8.57 [6.17, 11.49] 5.10 [3.15, 8.38] <0.001 serumwbc..median..IQR..
csftp..median..IQR.. 47.50 [31.70, 78.05] 48.00 [31.00, 78.00] 46.55 [33.92, 80.03] 0.935 csftp..median..IQR..
csftp60…. CSF TP < 60 834 (64.0) 722 (63.7) 112 (65.9) 0.645 csftp60….
X.15 CSF TP ≥ 60 469 (36.0) 411 (36.3) 58 (34.1) 0.645 X.15
csfgluc..median..IQR.. 68.00 [58.00, 85.00] 68.00 [58.00, 84.50] 67.00 [57.50, 88.50] 0.890 csfgluc..median..IQR..
csftnc..median..IQR.. 3.00 [1.00, 21.00] 3.00 [1.00, 23.00] 3.00 [1.00, 12.50] 0.463 csftnc..median..IQR..
csftnc5…. CSF TNC < 5 769 (59.0) 665 (58.7) 104 (60.8) 0.658 csftnc5….
X.16 CSF TNC ≥ 5 535 (41.0) 468 (41.3) 67 (39.2) 0.658 X.16
csflymph..median..IQR.. 66.00 [25.00, 86.00] 65.00 [25.00, 86.00] 66.00 [20.50, 87.00] 0.691 csflymph..median..IQR..
csflymph50…. Normal CSF Cell Count (CSF TNC < 5) 769 (59.0) 665 (58.7) 104 (60.8) 0.651 csflymph50….
X.17 Pleocytosis (Lymph ≥ 50%) 350 (26.8) 309 (27.3) 41 (24.0) 0.651 X.17
X.18 Pleocytosis (Lymph < 50%) 185 (14.2) 159 (14.0) 26 (15.2) 0.651 X.18
cat("\n### Table New — NEW Dataset\n")
## 
## ### Table New — NEW Dataset
knitr::kable(tn_new, caption = "Table New (NEW): Demographics & Lab Values by Immune Status")
Table New (NEW): Demographics & Lab Values by Immune Status
level Overall Not Immunosuppressed Immunosuppressed p row_id
n 1304 1114 190 n
sex…. Male 703 (53.9) 587 (52.7) 116 (61.1) 0.040 sex….
X Female 601 (46.1) 527 (47.3) 74 (38.9) 0.040 X
csfageyr..median..IQR.. 63.00 [48.00, 73.00] 63.00 [47.00, 74.00] 65.00 [55.24, 71.00] 0.345 csfageyr..median..IQR..
race…. White 994 (76.2) 843 (75.7) 151 (79.5) 0.615 race….
X.1 Black 105 (8.1) 90 (8.1) 15 (7.9) 0.615 X.1
X.2 Other/Multiple 129 (9.9) 113 (10.1) 16 (8.4) 0.615 X.2
X.3 Unknown 76 (5.8) 68 (6.1) 8 (4.2) 0.615 X.3
nonwhite…. White 1070 (82.1) 911 (81.8) 159 (83.7) 0.615 nonwhite….
X.4 Non-White 234 (17.9) 203 (18.2) 31 (16.3) 0.615 X.4
dead…. Not Reported Dead 915 (70.2) 826 (74.1) 89 (46.8) <0.001 dead….
X.5 Reported Dead 389 (29.8) 288 (25.9) 101 (53.2) <0.001 X.5
medicaid…. Other Insurance 933 (71.5) 804 (72.2) 129 (67.9) 0.262 medicaid….
X.6 Medicaid/Safety Net 371 (28.5) 310 (27.8) 61 (32.1) 0.262 X.6
site…. Mass General Hospital 706 (54.1) 641 (57.5) 65 (34.2) <0.001 site….
X.7 Brigham and Women’s Hospital 598 (45.9) 473 (42.5) 125 (65.8) <0.001 X.7
service…. Neurology 584 (44.8) 558 (50.1) 26 (13.7) <0.001 service….
X.8 Medicine/Subspecialties 456 (35.0) 391 (35.1) 65 (34.2) <0.001 X.8
X.9 Oncology 178 (13.7) 95 (8.5) 83 (43.7) <0.001 X.9
X.10 Other 86 (6.6) 70 (6.3) 16 (8.4) <0.001 X.10
immunosup…. Not Immunosuppressed 1114 (85.4) 1114 (100.0) 0 (0.0) <0.001 immunosup….
X.11 Immunosuppressed 190 (14.6) 0 (0.0) 190 (100.0) <0.001 X.11
transplant…. No Transplant History 1160 (89.0) 1114 (100.0) 46 (24.2) <0.001 transplant….
X.12 History of Transplant 144 (11.0) 0 (0.0) 144 (75.8) <0.001 X.12
bcellmed…. No B-cell Depleting Meds 1271 (97.5) 1114 (100.0) 157 (82.6) <0.001 bcellmed….
X.13 B-cell Depletion 33 (2.5) 0 (0.0) 33 (17.4) <0.001 X.13
csfadmit_day..median..IQR.. 1.00 [1.00, 4.00] 1.00 [0.00, 3.00] 3.00 [1.00, 10.00] <0.001 csfadmit_day..median..IQR..
inseasontest…. Test Sent Off-Season 479 (36.7) 401 (36.0) 78 (41.1) 0.210 inseasontest….
X.14 Test Sent June-Nov 825 (63.3) 713 (64.0) 112 (58.9) 0.210 X.14
serumwbc..median..IQR.. 8.17 [5.68, 11.40] 8.60 [6.19, 11.48] 5.14 [3.14, 8.46] <0.001 serumwbc..median..IQR..
csftp..median..IQR.. 47.50 [31.70, 78.05] 47.95 [31.00, 78.00] 47.10 [33.90, 86.00] 0.721 csftp..median..IQR..
csftp60…. CSF TP < 60 834 (64.0) 712 (63.9) 122 (64.6) 0.931 csftp60….
X.15 CSF TP ≥ 60 469 (36.0) 402 (36.1) 67 (35.4) 0.931 X.15
csfgluc..median..IQR.. 68.00 [58.00, 85.00] 68.00 [58.00, 84.25] 67.00 [56.25, 88.75] 0.935 csfgluc..median..IQR..
csftnc..median..IQR.. 3.00 [1.00, 21.00] 3.00 [1.00, 24.00] 3.00 [1.00, 11.75] 0.377 csftnc..median..IQR..
csftnc5…. CSF TNC < 5 769 (59.0) 653 (58.6) 116 (61.1) 0.582 csftnc5….
X.16 CSF TNC ≥ 5 535 (41.0) 461 (41.4) 74 (38.9) 0.582 X.16
csflymph..median..IQR.. 66.00 [25.00, 86.00] 65.00 [25.00, 86.00] 66.50 [23.50, 87.00] 0.976 csflymph..median..IQR..
csflymph50…. Normal CSF Cell Count (CSF TNC < 5) 769 (59.0) 653 (58.6) 116 (61.1) 0.767 csflymph50….
X.17 Pleocytosis (Lymph ≥ 50%) 350 (26.8) 303 (27.2) 47 (24.7) 0.767 X.17
X.18 Pleocytosis (Lymph < 50%) 185 (14.2) 158 (14.2) 27 (14.2) 0.767 X.18
# ── Delta table with highlighting ─────────────────────────────────────────────
delta_tn_result <- build_delta_gt(tn_old, tn_new, "Table New Delta: Demographics by Immune Status")
delta_tn <- delta_tn_result$data
delta_tn_result$gt
Table New Delta: Demographics by Immune Status
OLD Dataset NEW Dataset
Overall (OLD) P (OLD) Overall (NEW) P (NEW)
1304 1304
Male 703 (53.9) 0.090 703 (53.9) 0.040
Female 601 (46.1) 0.090 601 (46.1) 0.040
63.00 [48.00, 73.00] 0.108 63.00 [48.00, 73.00] 0.345
White 994 (76.2) 0.074 994 (76.2) 0.615
Black 105 (8.1) 0.074 105 (8.1) 0.615
Other/Multiple 129 (9.9) 0.074 129 (9.9) 0.615
Unknown 76 (5.8) 0.074 76 (5.8) 0.615
White 1070 (82.1) 0.074 1070 (82.1) 0.615
Non-White 234 (17.9) 0.074 234 (17.9) 0.615
Not Reported Dead 915 (70.2) <0.001 915 (70.2) <0.001
Reported Dead 389 (29.8) <0.001 389 (29.8) <0.001
Other Insurance 933 (71.5) 0.696 933 (71.5) 0.262
Medicaid/Safety Net 371 (28.5) 0.696 371 (28.5) 0.262
Mass General Hospital 706 (54.1) <0.001 706 (54.1) <0.001
Brigham and Women's Hospital 598 (45.9) <0.001 598 (45.9) <0.001
Neurology 584 (44.8) <0.001 584 (44.8) <0.001
Medicine/Subspecialties 456 (35.0) <0.001 456 (35.0) <0.001
Oncology 178 (13.7) <0.001 178 (13.7) <0.001
Other 86 (6.6) <0.001 86 (6.6) <0.001
Not Immunosuppressed 1133 (86.9) <0.001 1114 (85.4) <0.001
Immunosuppressed 171 (13.1) <0.001 190 (14.6) <0.001
No Transplant History 1160 (89.0) <0.001 1160 (89.0) <0.001
History of Transplant 144 (11.0) <0.001 144 (11.0) <0.001
No B-cell Depleting Meds 1271 (97.5) <0.001 1271 (97.5) <0.001
B-cell Depletion 33 (2.5) <0.001 33 (2.5) <0.001
1.00 [1.00, 4.00] <0.001 1.00 [1.00, 4.00] <0.001
Test Sent Off-Season 479 (36.7) 0.255 479 (36.7) 0.210
Test Sent June-Nov 825 (63.3) 0.255 825 (63.3) 0.210
8.17 [5.68, 11.40] <0.001 8.17 [5.68, 11.40] <0.001
47.50 [31.70, 78.05] 0.935 47.50 [31.70, 78.05] 0.721
CSF TP < 60 834 (64.0) 0.645 834 (64.0) 0.931
CSF TP ≥ 60 469 (36.0) 0.645 469 (36.0) 0.931
68.00 [58.00, 85.00] 0.890 68.00 [58.00, 85.00] 0.935
3.00 [1.00, 21.00] 0.463 3.00 [1.00, 21.00] 0.377
CSF TNC < 5 769 (59.0) 0.658 769 (59.0) 0.582
CSF TNC ≥ 5 535 (41.0) 0.658 535 (41.0) 0.582
66.00 [25.00, 86.00] 0.691 66.00 [25.00, 86.00] 0.976
Normal CSF Cell Count (CSF TNC < 5) 769 (59.0) 0.651 769 (59.0) 0.767
Pleocytosis (Lymph ≥ 50%) 350 (26.8) 0.651 350 (26.8) 0.767
Pleocytosis (Lymph < 50%) 185 (14.2) 0.651 185 (14.2) 0.767

Table 2: Demographics by WNV Positivity

# ── Build for OLD and NEW stratified by wnvpos ────────────────────────────────
t2_old <- build_tableone_df(data_old, table1_vars, "wnvpos", continuous_vars, factor_vars_t1)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: sex"
## [1] "  Factor levels for sex : Male, Female"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of sex : 2"
## [1] "  P-value found for sex : 0.848"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: race"
## [1] "  Factor levels for race : White, Black, Other/Multiple, Unknown"
## [1] "  Rows in df_tableone for these levels: 5, 6, 7, 8, 9"
## [1] "  Rows with p-value in factor levels of race : 5, 9"
## [1] "  P-value found for race : 0.446"
## [1] "  P-value copied to rows: 5, 6, 7, 8, 9"
## [1] "Processing variable: nonwhite"
## [1] "  Factor levels for nonwhite : White, Non-White"
## [1] "  Rows in df_tableone for these levels: 5, 9, 10"
## [1] "  Rows with p-value in factor levels of nonwhite : 5, 9"
## [1] "  P-value found for nonwhite : 0.446"
## [1] "  P-value copied to rows: 5, 9, 10"
## [1] "Processing variable: dead"
## [1] "  Factor levels for dead : Not Reported Dead, Reported Dead"
## [1] "  Rows in df_tableone for these levels: 11, 12"
## [1] "  Rows with p-value in factor levels of dead : 11"
## [1] "  P-value found for dead : 0.587"
## [1] "  P-value copied to rows: 11, 12"
## [1] "Processing variable: medicaid"
## [1] "  Factor levels for medicaid : Other Insurance, Medicaid/Safety Net"
## [1] "  Rows in df_tableone for these levels: 13, 14"
## [1] "  Rows with p-value in factor levels of medicaid : 13"
## [1] "  P-value found for medicaid : 0.694"
## [1] "  P-value copied to rows: 13, 14"
## [1] "Processing variable: site"
## [1] "  Factor levels for site : Mass General Hospital, Brigham and Women's Hospital"
## [1] "  Rows in df_tableone for these levels: 15, 16"
## [1] "  Rows with p-value in factor levels of site : 15"
## [1] "  P-value found for site : 0.011"
## [1] "  P-value copied to rows: 15, 16"
## [1] "Processing variable: service"
## [1] "  Factor levels for service : Neurology, Medicine/Subspecialties, Oncology, Other"
## [1] "  Rows in df_tableone for these levels: 17, 18, 19, 20"
## [1] "  Rows with p-value in factor levels of service : 17"
## [1] "  P-value found for service : 0.146"
## [1] "  P-value copied to rows: 17, 18, 19, 20"
## [1] "Processing variable: immunosup"
## [1] "  Factor levels for immunosup : Not Immunosuppressed, Immunosuppressed"
## [1] "  Rows in df_tableone for these levels: 21, 22"
## [1] "  Rows with p-value in factor levels of immunosup : 21"
## [1] "  P-value found for immunosup : 0.262"
## [1] "  P-value copied to rows: 21, 22"
## [1] "Processing variable: transplant"
## [1] "  Factor levels for transplant : No Transplant History, History of Transplant"
## [1] "  Rows in df_tableone for these levels: 23, 24"
## [1] "  Rows with p-value in factor levels of transplant : 23"
## [1] "  P-value found for transplant : 0.386"
## [1] "  P-value copied to rows: 23, 24"
## [1] "Processing variable: bcellmed"
## [1] "  Factor levels for bcellmed : No B-cell Depleting Meds, B-cell Depletion"
## [1] "  Rows in df_tableone for these levels: 25, 26"
## [1] "  Rows with p-value in factor levels of bcellmed : 25"
## [1] "  P-value found for bcellmed : 0.842"
## [1] "  P-value copied to rows: 25, 26"
## [1] "Processing variable: inseasontest"
## [1] "  Factor levels for inseasontest : Test Sent Off-Season, Test Sent June-Nov"
## [1] "  Rows in df_tableone for these levels: 28, 29"
## [1] "  Rows with p-value in factor levels of inseasontest : 28"
## [1] "  P-value found for inseasontest : <0.001"
## [1] "  P-value copied to rows: 28, 29"
## [1] "Processing variable: csftp60"
## [1] "  Factor levels for csftp60 : CSF TP < 60, CSF TP ≥ 60"
## [1] "  Rows in df_tableone for these levels: 32, 33"
## [1] "  Rows with p-value in factor levels of csftp60 : 32"
## [1] "  P-value found for csftp60 : 0.001"
## [1] "  P-value copied to rows: 32, 33"
## [1] "Processing variable: csftnc5"
## [1] "  Factor levels for csftnc5 : CSF TNC < 5, CSF TNC ≥ 5"
## [1] "  Rows in df_tableone for these levels: 36, 37"
## [1] "  Rows with p-value in factor levels of csftnc5 : 36"
## [1] "  P-value found for csftnc5 : <0.001"
## [1] "  P-value copied to rows: 36, 37"
## [1] "Processing variable: csflymph50"
## [1] "  Factor levels for csflymph50 : Normal CSF Cell Count (CSF TNC < 5), Pleocytosis (Lymph ≥ 50%), Pleocytosis (Lymph < 50%)"
## [1] "  Rows in df_tableone for these levels: 39, 40, 41"
## [1] "  Rows with p-value in factor levels of csflymph50 : 39"
## [1] "  P-value found for csflymph50 : <0.001"
## [1] "  P-value copied to rows: 39, 40, 41"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
t2_new <- build_tableone_df(data_new, table1_vars, "wnvpos", continuous_vars, factor_vars_t1)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: sex"
## [1] "  Factor levels for sex : Male, Female"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of sex : 2"
## [1] "  P-value found for sex : 0.848"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: race"
## [1] "  Factor levels for race : White, Black, Other/Multiple, Unknown"
## [1] "  Rows in df_tableone for these levels: 5, 6, 7, 8, 9"
## [1] "  Rows with p-value in factor levels of race : 5, 9"
## [1] "  P-value found for race : 0.446"
## [1] "  P-value copied to rows: 5, 6, 7, 8, 9"
## [1] "Processing variable: nonwhite"
## [1] "  Factor levels for nonwhite : White, Non-White"
## [1] "  Rows in df_tableone for these levels: 5, 9, 10"
## [1] "  Rows with p-value in factor levels of nonwhite : 5, 9"
## [1] "  P-value found for nonwhite : 0.446"
## [1] "  P-value copied to rows: 5, 9, 10"
## [1] "Processing variable: dead"
## [1] "  Factor levels for dead : Not Reported Dead, Reported Dead"
## [1] "  Rows in df_tableone for these levels: 11, 12"
## [1] "  Rows with p-value in factor levels of dead : 11"
## [1] "  P-value found for dead : 0.587"
## [1] "  P-value copied to rows: 11, 12"
## [1] "Processing variable: medicaid"
## [1] "  Factor levels for medicaid : Other Insurance, Medicaid/Safety Net"
## [1] "  Rows in df_tableone for these levels: 13, 14"
## [1] "  Rows with p-value in factor levels of medicaid : 13"
## [1] "  P-value found for medicaid : 0.694"
## [1] "  P-value copied to rows: 13, 14"
## [1] "Processing variable: site"
## [1] "  Factor levels for site : Mass General Hospital, Brigham and Women's Hospital"
## [1] "  Rows in df_tableone for these levels: 15, 16"
## [1] "  Rows with p-value in factor levels of site : 15"
## [1] "  P-value found for site : 0.011"
## [1] "  P-value copied to rows: 15, 16"
## [1] "Processing variable: service"
## [1] "  Factor levels for service : Neurology, Medicine/Subspecialties, Oncology, Other"
## [1] "  Rows in df_tableone for these levels: 17, 18, 19, 20"
## [1] "  Rows with p-value in factor levels of service : 17"
## [1] "  P-value found for service : 0.146"
## [1] "  P-value copied to rows: 17, 18, 19, 20"
## [1] "Processing variable: immunosup"
## [1] "  Factor levels for immunosup : Not Immunosuppressed, Immunosuppressed"
## [1] "  Rows in df_tableone for these levels: 21, 22"
## [1] "  Rows with p-value in factor levels of immunosup : 21"
## [1] "  P-value found for immunosup : 0.199"
## [1] "  P-value copied to rows: 21, 22"
## [1] "Processing variable: transplant"
## [1] "  Factor levels for transplant : No Transplant History, History of Transplant"
## [1] "  Rows in df_tableone for these levels: 23, 24"
## [1] "  Rows with p-value in factor levels of transplant : 23"
## [1] "  P-value found for transplant : 0.386"
## [1] "  P-value copied to rows: 23, 24"
## [1] "Processing variable: bcellmed"
## [1] "  Factor levels for bcellmed : No B-cell Depleting Meds, B-cell Depletion"
## [1] "  Rows in df_tableone for these levels: 25, 26"
## [1] "  Rows with p-value in factor levels of bcellmed : 25"
## [1] "  P-value found for bcellmed : 0.842"
## [1] "  P-value copied to rows: 25, 26"
## [1] "Processing variable: inseasontest"
## [1] "  Factor levels for inseasontest : Test Sent Off-Season, Test Sent June-Nov"
## [1] "  Rows in df_tableone for these levels: 28, 29"
## [1] "  Rows with p-value in factor levels of inseasontest : 28"
## [1] "  P-value found for inseasontest : <0.001"
## [1] "  P-value copied to rows: 28, 29"
## [1] "Processing variable: csftp60"
## [1] "  Factor levels for csftp60 : CSF TP < 60, CSF TP ≥ 60"
## [1] "  Rows in df_tableone for these levels: 32, 33"
## [1] "  Rows with p-value in factor levels of csftp60 : 32"
## [1] "  P-value found for csftp60 : 0.001"
## [1] "  P-value copied to rows: 32, 33"
## [1] "Processing variable: csftnc5"
## [1] "  Factor levels for csftnc5 : CSF TNC < 5, CSF TNC ≥ 5"
## [1] "  Rows in df_tableone for these levels: 36, 37"
## [1] "  Rows with p-value in factor levels of csftnc5 : 36"
## [1] "  P-value found for csftnc5 : <0.001"
## [1] "  P-value copied to rows: 36, 37"
## [1] "Processing variable: csflymph50"
## [1] "  Factor levels for csflymph50 : Normal CSF Cell Count (CSF TNC < 5), Pleocytosis (Lymph ≥ 50%), Pleocytosis (Lymph < 50%)"
## [1] "  Rows in df_tableone for these levels: 39, 40, 41"
## [1] "  Rows with p-value in factor levels of csflymph50 : 39"
## [1] "  P-value found for csflymph50 : <0.001"
## [1] "  P-value copied to rows: 39, 40, 41"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
cat("### Table 2 — OLD Dataset\n")
## ### Table 2 — OLD Dataset
knitr::kable(t2_old, caption = "Table 2 (OLD): Demographics & Lab Values by WNV Positivity")
Table 2 (OLD): Demographics & Lab Values by WNV Positivity
level Overall Positive WNV No Positive Result p row_id
n 1304 26 1278 n
sex…. Male 703 (53.9) 15 (57.7) 688 (53.8) 0.848 sex….
X Female 601 (46.1) 11 (42.3) 590 (46.2) 0.848 X
csfageyr..median..IQR.. 63.00 [48.00, 73.00] 73.00 [62.00, 79.71] 63.00 [48.00, 73.00] 0.008 csfageyr..median..IQR..
race…. White 994 (76.2) 22 (84.6) 972 (76.1) 0.446 race….
X.1 Black 105 (8.1) 0 (0.0) 105 (8.2) 0.446 X.1
X.2 Other/Multiple 129 (9.9) 2 (7.7) 127 (9.9) 0.446 X.2
X.3 Unknown 76 (5.8) 2 (7.7) 74 (5.8) 0.446 X.3
nonwhite…. White 1070 (82.1) 24 (92.3) 1046 (81.8) 0.446 nonwhite….
X.4 Non-White 234 (17.9) 2 (7.7) 232 (18.2) 0.446 X.4
dead…. Not Reported Dead 915 (70.2) 20 (76.9) 895 (70.0) 0.587 dead….
X.5 Reported Dead 389 (29.8) 6 (23.1) 383 (30.0) 0.587 X.5
medicaid…. Other Insurance 933 (71.5) 20 (76.9) 913 (71.4) 0.694 medicaid….
X.6 Medicaid/Safety Net 371 (28.5) 6 (23.1) 365 (28.6) 0.694 X.6
site…. Mass General Hospital 706 (54.1) 21 (80.8) 685 (53.6) 0.011 site….
X.7 Brigham and Women’s Hospital 598 (45.9) 5 (19.2) 593 (46.4) 0.011 X.7
service…. Neurology 584 (44.8) 10 (38.5) 574 (44.9) 0.146 service….
X.8 Medicine/Subspecialties 456 (35.0) 14 (53.8) 442 (34.6) 0.146 X.8
X.9 Oncology 178 (13.7) 2 (7.7) 176 (13.8) 0.146 X.9
X.10 Other 86 (6.6) 0 (0.0) 86 (6.7) 0.146 X.10
immunosup…. Not Immunosuppressed 1133 (86.9) 25 (96.2) 1108 (86.7) 0.262 immunosup….
X.11 Immunosuppressed 171 (13.1) 1 (3.8) 170 (13.3) 0.262 X.11
transplant…. No Transplant History 1160 (89.0) 25 (96.2) 1135 (88.8) 0.386 transplant….
X.12 History of Transplant 144 (11.0) 1 (3.8) 143 (11.2) 0.386 X.12
bcellmed…. No B-cell Depleting Meds 1271 (97.5) 26 (100.0) 1245 (97.4) 0.842 bcellmed….
X.13 B-cell Depletion 33 (2.5) 0 (0.0) 33 (2.6) 0.842 X.13
csfadmit_day..median..IQR.. 1.00 [1.00, 4.00] 1.00 [0.25, 3.75] 1.00 [1.00, 4.00] 0.484 csfadmit_day..median..IQR..
inseasontest…. Test Sent Off-Season 479 (36.7) 0 (0.0) 479 (37.5) <0.001 inseasontest….
X.14 Test Sent June-Nov 825 (63.3) 26 (100.0) 799 (62.5) <0.001 X.14
serumwbc..median..IQR.. 8.17 [5.68, 11.40] 9.04 [7.88, 11.23] 8.13 [5.65, 11.40] 0.128 serumwbc..median..IQR..
csftp..median..IQR.. 47.50 [31.70, 78.05] 69.50 [54.00, 113.25] 47.00 [31.20, 77.80] 0.001 csftp..median..IQR..
csftp60…. CSF TP < 60 834 (64.0) 8 (30.8) 826 (64.7) 0.001 csftp60….
X.15 CSF TP ≥ 60 469 (36.0) 18 (69.2) 451 (35.3) 0.001 X.15
csfgluc..median..IQR.. 68.00 [58.00, 85.00] 60.50 [53.25, 70.00] 68.00 [58.00, 85.00] 0.025 csfgluc..median..IQR..
csftnc..median..IQR.. 3.00 [1.00, 21.00] 49.50 [12.25, 99.50] 3.00 [1.00, 18.00] <0.001 csftnc..median..IQR..
csftnc5…. CSF TNC < 5 769 (59.0) 4 (15.4) 765 (59.9) <0.001 csftnc5….
X.16 CSF TNC ≥ 5 535 (41.0) 22 (84.6) 513 (40.1) <0.001 X.16
csflymph..median..IQR.. 66.00 [25.00, 86.00] 56.50 [26.25, 75.25] 66.00 [25.00, 86.75] 0.598 csflymph..median..IQR..
csflymph50…. Normal CSF Cell Count (CSF TNC < 5) 769 (59.0) 4 (15.4) 765 (59.9) <0.001 csflymph50….
X.17 Pleocytosis (Lymph ≥ 50%) 350 (26.8) 12 (46.2) 338 (26.4) <0.001 X.17
X.18 Pleocytosis (Lymph < 50%) 185 (14.2) 10 (38.5) 175 (13.7) <0.001 X.18
cat("\n### Table 2 — NEW Dataset\n")
## 
## ### Table 2 — NEW Dataset
knitr::kable(t2_new, caption = "Table 2 (NEW): Demographics & Lab Values by WNV Positivity")
Table 2 (NEW): Demographics & Lab Values by WNV Positivity
level Overall Positive WNV No Positive Result p row_id
n 1304 26 1278 n
sex…. Male 703 (53.9) 15 (57.7) 688 (53.8) 0.848 sex….
X Female 601 (46.1) 11 (42.3) 590 (46.2) 0.848 X
csfageyr..median..IQR.. 63.00 [48.00, 73.00] 73.00 [62.00, 79.71] 63.00 [48.00, 73.00] 0.008 csfageyr..median..IQR..
race…. White 994 (76.2) 22 (84.6) 972 (76.1) 0.446 race….
X.1 Black 105 (8.1) 0 (0.0) 105 (8.2) 0.446 X.1
X.2 Other/Multiple 129 (9.9) 2 (7.7) 127 (9.9) 0.446 X.2
X.3 Unknown 76 (5.8) 2 (7.7) 74 (5.8) 0.446 X.3
nonwhite…. White 1070 (82.1) 24 (92.3) 1046 (81.8) 0.446 nonwhite….
X.4 Non-White 234 (17.9) 2 (7.7) 232 (18.2) 0.446 X.4
dead…. Not Reported Dead 915 (70.2) 20 (76.9) 895 (70.0) 0.587 dead….
X.5 Reported Dead 389 (29.8) 6 (23.1) 383 (30.0) 0.587 X.5
medicaid…. Other Insurance 933 (71.5) 20 (76.9) 913 (71.4) 0.694 medicaid….
X.6 Medicaid/Safety Net 371 (28.5) 6 (23.1) 365 (28.6) 0.694 X.6
site…. Mass General Hospital 706 (54.1) 21 (80.8) 685 (53.6) 0.011 site….
X.7 Brigham and Women’s Hospital 598 (45.9) 5 (19.2) 593 (46.4) 0.011 X.7
service…. Neurology 584 (44.8) 10 (38.5) 574 (44.9) 0.146 service….
X.8 Medicine/Subspecialties 456 (35.0) 14 (53.8) 442 (34.6) 0.146 X.8
X.9 Oncology 178 (13.7) 2 (7.7) 176 (13.8) 0.146 X.9
X.10 Other 86 (6.6) 0 (0.0) 86 (6.7) 0.146 X.10
immunosup…. Not Immunosuppressed 1114 (85.4) 25 (96.2) 1089 (85.2) 0.199 immunosup….
X.11 Immunosuppressed 190 (14.6) 1 (3.8) 189 (14.8) 0.199 X.11
transplant…. No Transplant History 1160 (89.0) 25 (96.2) 1135 (88.8) 0.386 transplant….
X.12 History of Transplant 144 (11.0) 1 (3.8) 143 (11.2) 0.386 X.12
bcellmed…. No B-cell Depleting Meds 1271 (97.5) 26 (100.0) 1245 (97.4) 0.842 bcellmed….
X.13 B-cell Depletion 33 (2.5) 0 (0.0) 33 (2.6) 0.842 X.13
csfadmit_day..median..IQR.. 1.00 [1.00, 4.00] 1.00 [0.25, 3.75] 1.00 [1.00, 4.00] 0.484 csfadmit_day..median..IQR..
inseasontest…. Test Sent Off-Season 479 (36.7) 0 (0.0) 479 (37.5) <0.001 inseasontest….
X.14 Test Sent June-Nov 825 (63.3) 26 (100.0) 799 (62.5) <0.001 X.14
serumwbc..median..IQR.. 8.17 [5.68, 11.40] 9.04 [7.88, 11.23] 8.13 [5.65, 11.40] 0.128 serumwbc..median..IQR..
csftp..median..IQR.. 47.50 [31.70, 78.05] 69.50 [54.00, 113.25] 47.00 [31.20, 77.80] 0.001 csftp..median..IQR..
csftp60…. CSF TP < 60 834 (64.0) 8 (30.8) 826 (64.7) 0.001 csftp60….
X.15 CSF TP ≥ 60 469 (36.0) 18 (69.2) 451 (35.3) 0.001 X.15
csfgluc..median..IQR.. 68.00 [58.00, 85.00] 60.50 [53.25, 70.00] 68.00 [58.00, 85.00] 0.025 csfgluc..median..IQR..
csftnc..median..IQR.. 3.00 [1.00, 21.00] 49.50 [12.25, 99.50] 3.00 [1.00, 18.00] <0.001 csftnc..median..IQR..
csftnc5…. CSF TNC < 5 769 (59.0) 4 (15.4) 765 (59.9) <0.001 csftnc5….
X.16 CSF TNC ≥ 5 535 (41.0) 22 (84.6) 513 (40.1) <0.001 X.16
csflymph..median..IQR.. 66.00 [25.00, 86.00] 56.50 [26.25, 75.25] 66.00 [25.00, 86.75] 0.598 csflymph..median..IQR..
csflymph50…. Normal CSF Cell Count (CSF TNC < 5) 769 (59.0) 4 (15.4) 765 (59.9) <0.001 csflymph50….
X.17 Pleocytosis (Lymph ≥ 50%) 350 (26.8) 12 (46.2) 338 (26.4) <0.001 X.17
X.18 Pleocytosis (Lymph < 50%) 185 (14.2) 10 (38.5) 175 (13.7) <0.001 X.18
# ── Delta table with highlighting ─────────────────────────────────────────────
delta_t2_result <- build_delta_gt(t2_old, t2_new, "Table 2 Delta: Demographics by WNV Positivity")
delta_t2 <- delta_t2_result$data
delta_t2_result$gt
Table 2 Delta: Demographics by WNV Positivity
OLD Dataset NEW Dataset
Overall (OLD) P (OLD) Overall (NEW) P (NEW)
1304 1304
Male 703 (53.9) 0.848 703 (53.9) 0.848
Female 601 (46.1) 0.848 601 (46.1) 0.848
63.00 [48.00, 73.00] 0.008 63.00 [48.00, 73.00] 0.008
White 994 (76.2) 0.446 994 (76.2) 0.446
Black 105 (8.1) 0.446 105 (8.1) 0.446
Other/Multiple 129 (9.9) 0.446 129 (9.9) 0.446
Unknown 76 (5.8) 0.446 76 (5.8) 0.446
White 1070 (82.1) 0.446 1070 (82.1) 0.446
Non-White 234 (17.9) 0.446 234 (17.9) 0.446
Not Reported Dead 915 (70.2) 0.587 915 (70.2) 0.587
Reported Dead 389 (29.8) 0.587 389 (29.8) 0.587
Other Insurance 933 (71.5) 0.694 933 (71.5) 0.694
Medicaid/Safety Net 371 (28.5) 0.694 371 (28.5) 0.694
Mass General Hospital 706 (54.1) 0.011 706 (54.1) 0.011
Brigham and Women's Hospital 598 (45.9) 0.011 598 (45.9) 0.011
Neurology 584 (44.8) 0.146 584 (44.8) 0.146
Medicine/Subspecialties 456 (35.0) 0.146 456 (35.0) 0.146
Oncology 178 (13.7) 0.146 178 (13.7) 0.146
Other 86 (6.6) 0.146 86 (6.6) 0.146
Not Immunosuppressed 1133 (86.9) 0.262 1114 (85.4) 0.199
Immunosuppressed 171 (13.1) 0.262 190 (14.6) 0.199
No Transplant History 1160 (89.0) 0.386 1160 (89.0) 0.386
History of Transplant 144 (11.0) 0.386 144 (11.0) 0.386
No B-cell Depleting Meds 1271 (97.5) 0.842 1271 (97.5) 0.842
B-cell Depletion 33 (2.5) 0.842 33 (2.5) 0.842
1.00 [1.00, 4.00] 0.484 1.00 [1.00, 4.00] 0.484
Test Sent Off-Season 479 (36.7) <0.001 479 (36.7) <0.001
Test Sent June-Nov 825 (63.3) <0.001 825 (63.3) <0.001
8.17 [5.68, 11.40] 0.128 8.17 [5.68, 11.40] 0.128
47.50 [31.70, 78.05] 0.001 47.50 [31.70, 78.05] 0.001
CSF TP < 60 834 (64.0) 0.001 834 (64.0) 0.001
CSF TP ≥ 60 469 (36.0) 0.001 469 (36.0) 0.001
68.00 [58.00, 85.00] 0.025 68.00 [58.00, 85.00] 0.025
3.00 [1.00, 21.00] <0.001 3.00 [1.00, 21.00] <0.001
CSF TNC < 5 769 (59.0) <0.001 769 (59.0) <0.001
CSF TNC ≥ 5 535 (41.0) <0.001 535 (41.0) <0.001
66.00 [25.00, 86.00] 0.598 66.00 [25.00, 86.00] 0.598
Normal CSF Cell Count (CSF TNC < 5) 769 (59.0) <0.001 769 (59.0) <0.001
Pleocytosis (Lymph ≥ 50%) 350 (26.8) <0.001 350 (26.8) <0.001
Pleocytosis (Lymph < 50%) 185 (14.2) <0.001 185 (14.2) <0.001

Table 3: WNV Testing by Guideline Adherence

# ── Table 3 variables ─────────────────────────────────────────────────────────
table3_vars <- c(
  "csfpcr_ordered", "csfpcr_rslt", "csfigm_ordered", "csfigm_rslt",
  "serumigm_ordered", "serumigm_rslt", "guideline"
)
factor_vars_t3 <- table3_vars

# ── Helper: build Table 3/4 style TableOne (all categorical) ──────────────────
build_tableone_cat <- function(data, vars, strata, fac_vars) {
  tobj <- tableone::CreateTableOne(
    vars = vars, strata = strata, data = data,
    factorVars = fac_vars, addOverall = TRUE
  )
  tmat <- print(tobj, showAllLevels = TRUE, printToggle = FALSE, noSpaces = TRUE)
  tdf <- as.data.frame(tmat, stringsAsFactors = FALSE)

  # Preserve unique rownames as row_id BEFORE any modifications
  tdf$row_id <- rownames(tdf)

  colnames(tdf)[1] <- "level"
  tdf$level <- trimws(tdf$level)

  fld <- lapply(fac_vars, function(x) levels(data[[x]]))
  names(fld) <- fac_vars
  tdf <- suppressMessages(copyPvalueToAllLevels(tdf, fld))

  # Relabel row headers
  row_label_dict <- c(
    "csfpcr_ordered...."   = "CSF PCR Ordered",
    "csfpcr_rslt...."      = "CSF PCR Result",
    "csfigm_ordered...."   = "CSF IgM Ordered",
    "csfigm_rslt...."      = "CSF IgM Result",
    "serumigm_ordered...." = "Serum IgM Ordered",
    "serumigm_rslt...."    = "Serum IgM Result",
    "guideline...."        = "Guideline Adherence"
  )
  for (old_nm in names(row_label_dict)) {
    new_nm <- row_label_dict[[old_nm]]
    tdf$level[rownames(tdf) == old_nm] <- new_nm
  }

  tdf <- tdf[-1, ]  # Remove n row
  if ("test" %in% colnames(tdf)) tdf <- dplyr::select(tdf, -test)
  return(tdf)
}

# ── Build Table 3 for OLD and NEW ────────────────────────────────────────────
t3_old <- build_tableone_cat(data_old, table3_vars, "guideline2", factor_vars_t3)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: csfpcr_ordered"
## [1] "  Factor levels for csfpcr_ordered : CSF PCR Not Ordered, CSF PCR Ordered"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of csfpcr_ordered : 2"
## [1] "  P-value found for csfpcr_ordered : <0.001"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: csfpcr_rslt"
## [1] "  Factor levels for csfpcr_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of csfpcr_rslt : 4, 10, 16"
## [1] "  P-value found for csfpcr_rslt : <0.001"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: csfigm_ordered"
## [1] "  Factor levels for csfigm_ordered : CSF IgM Not Ordered, CSF IgM Ordered"
## [1] "  Rows in df_tableone for these levels: 8, 9"
## [1] "  Rows with p-value in factor levels of csfigm_ordered : 8"
## [1] "  P-value found for csfigm_ordered : <0.001"
## [1] "  P-value copied to rows: 8, 9"
## [1] "Processing variable: csfigm_rslt"
## [1] "  Factor levels for csfigm_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of csfigm_rslt : 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  P-value found for csfigm_rslt : <0.001"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: serumigm_ordered"
## [1] "  Factor levels for serumigm_ordered : Serum IgM Not Ordered, Serum IgM Ordered"
## [1] "  Rows in df_tableone for these levels: 14, 15"
## [1] "  Rows with p-value in factor levels of serumigm_ordered : 14"
## [1] "  P-value found for serumigm_ordered : <0.001"
## [1] "  P-value copied to rows: 14, 15"
## [1] "Processing variable: serumigm_rslt"
## [1] "  Factor levels for serumigm_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of serumigm_rslt : 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  P-value found for serumigm_rslt : <0.001"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: guideline"
## [1] "  Factor levels for guideline : Does Not Follow, Follows, Follows but Over-Tested"
## [1] "  Rows in df_tableone for these levels: 20, 21, 22"
## [1] "  Rows with p-value in factor levels of guideline : 20"
## [1] "  P-value found for guideline : <0.001"
## [1] "  P-value copied to rows: 20, 21, 22"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
t3_new <- build_tableone_cat(data_new, table3_vars, "guideline2", factor_vars_t3)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: csfpcr_ordered"
## [1] "  Factor levels for csfpcr_ordered : CSF PCR Not Ordered, CSF PCR Ordered"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of csfpcr_ordered : 2"
## [1] "  P-value found for csfpcr_ordered : <0.001"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: csfpcr_rslt"
## [1] "  Factor levels for csfpcr_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of csfpcr_rslt : 4, 10, 16"
## [1] "  P-value found for csfpcr_rslt : <0.001"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: csfigm_ordered"
## [1] "  Factor levels for csfigm_ordered : CSF IgM Not Ordered, CSF IgM Ordered"
## [1] "  Rows in df_tableone for these levels: 8, 9"
## [1] "  Rows with p-value in factor levels of csfigm_ordered : 8"
## [1] "  P-value found for csfigm_ordered : <0.001"
## [1] "  P-value copied to rows: 8, 9"
## [1] "Processing variable: csfigm_rslt"
## [1] "  Factor levels for csfigm_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of csfigm_rslt : 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  P-value found for csfigm_rslt : <0.001"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: serumigm_ordered"
## [1] "  Factor levels for serumigm_ordered : Serum IgM Not Ordered, Serum IgM Ordered"
## [1] "  Rows in df_tableone for these levels: 14, 15"
## [1] "  Rows with p-value in factor levels of serumigm_ordered : 14"
## [1] "  P-value found for serumigm_ordered : <0.001"
## [1] "  P-value copied to rows: 14, 15"
## [1] "Processing variable: serumigm_rslt"
## [1] "  Factor levels for serumigm_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of serumigm_rslt : 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  P-value found for serumigm_rslt : <0.001"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: guideline"
## [1] "  Factor levels for guideline : Does Not Follow, Follows, Follows but Over-Tested"
## [1] "  Rows in df_tableone for these levels: 20, 21, 22"
## [1] "  Rows with p-value in factor levels of guideline : 20"
## [1] "  P-value found for guideline : <0.001"
## [1] "  P-value copied to rows: 20, 21, 22"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
cat("### Table 3 — OLD Dataset\n")
## ### Table 3 — OLD Dataset
knitr::kable(t3_old, caption = "Table 3 (OLD): WNV Testing by Guideline Adherence")
Table 3 (OLD): WNV Testing by Guideline Adherence
level Overall Adherent Nonadherent p row_id
csfpcr_ordered…. CSF PCR Ordered 171 (13.1) 153 (45.9) 18 (1.9) <0.001 csfpcr_ordered….
X CSF PCR Ordered 1133 (86.9) 180 (54.1) 953 (98.1) <0.001 X
csfpcr_rslt…. CSF PCR Result 38 (2.9) 12 (3.6) 26 (2.7) <0.001 csfpcr_rslt….
X.1 Positive 4 (0.3) 2 (0.6) 2 (0.2) <0.001 X.1
X.2 Negative 1091 (83.7) 166 (49.8) 925 (95.3) <0.001 X.2
X.3 Not Sent 171 (13.1) 153 (45.9) 18 (1.9) <0.001 X.3
csfigm_ordered…. CSF IgM Ordered 953 (73.1) 0 (0.0) 953 (98.1) <0.001 csfigm_ordered….
X.4 CSF IgM Ordered 351 (26.9) 333 (100.0) 18 (1.9) <0.001 X.4
csfigm_rslt…. CSF IgM Result 63 (4.8) 60 (18.0) 3 (0.3) <0.001 csfigm_rslt….
X.5 Positive 20 (1.5) 19 (5.7) 1 (0.1) <0.001 X.5
X.6 Negative 268 (20.6) 254 (76.3) 14 (1.4) <0.001 X.6
X.7 Not Sent 953 (73.1) 0 (0.0) 953 (98.1) <0.001 X.7
serumigm_ordered…. Serum IgM Ordered 1169 (89.6) 257 (77.2) 912 (93.9) <0.001 serumigm_ordered….
X.8 Serum IgM Ordered 135 (10.4) 76 (22.8) 59 (6.1) <0.001 X.8
serumigm_rslt…. Serum IgM Result 14 (1.1) 7 (2.1) 7 (0.7) <0.001 serumigm_rslt….
X.9 Positive 11 (0.8) 9 (2.7) 2 (0.2) <0.001 X.9
X.10 Negative 110 (8.4) 60 (18.0) 50 (5.1) <0.001 X.10
X.11 Not Sent 1169 (89.6) 257 (77.2) 912 (93.9) <0.001 X.11
guideline…. Guideline Adherence 971 (74.5) 0 (0.0) 971 (100.0) <0.001 guideline….
X.12 Follows 167 (12.8) 167 (50.2) 0 (0.0) <0.001 X.12
X.13 Follows but Over-Tested 166 (12.7) 166 (49.8) 0 (0.0) <0.001 X.13
cat("\n### Table 3 — NEW Dataset\n")
## 
## ### Table 3 — NEW Dataset
knitr::kable(t3_new, caption = "Table 3 (NEW): WNV Testing by Guideline Adherence")
Table 3 (NEW): WNV Testing by Guideline Adherence
level Overall Adherent Nonadherent p row_id
csfpcr_ordered…. CSF PCR Ordered 171 (13.1) 150 (45.5) 21 (2.2) <0.001 csfpcr_ordered….
X CSF PCR Ordered 1133 (86.9) 180 (54.5) 953 (97.8) <0.001 X
csfpcr_rslt…. CSF PCR Result 38 (2.9) 12 (3.6) 26 (2.7) <0.001 csfpcr_rslt….
X.1 Positive 4 (0.3) 2 (0.6) 2 (0.2) <0.001 X.1
X.2 Negative 1091 (83.7) 166 (50.3) 925 (95.0) <0.001 X.2
X.3 Not Sent 171 (13.1) 150 (45.5) 21 (2.2) <0.001 X.3
csfigm_ordered…. CSF IgM Ordered 953 (73.1) 0 (0.0) 953 (97.8) <0.001 csfigm_ordered….
X.4 CSF IgM Ordered 351 (26.9) 330 (100.0) 21 (2.2) <0.001 X.4
csfigm_rslt…. CSF IgM Result 63 (4.8) 59 (17.9) 4 (0.4) <0.001 csfigm_rslt….
X.5 Positive 20 (1.5) 19 (5.8) 1 (0.1) <0.001 X.5
X.6 Negative 268 (20.6) 252 (76.4) 16 (1.6) <0.001 X.6
X.7 Not Sent 953 (73.1) 0 (0.0) 953 (97.8) <0.001 X.7
serumigm_ordered…. Serum IgM Ordered 1169 (89.6) 255 (77.3) 914 (93.8) <0.001 serumigm_ordered….
X.8 Serum IgM Ordered 135 (10.4) 75 (22.7) 60 (6.2) <0.001 X.8
serumigm_rslt…. Serum IgM Result 14 (1.1) 6 (1.8) 8 (0.8) <0.001 serumigm_rslt….
X.9 Positive 11 (0.8) 9 (2.7) 2 (0.2) <0.001 X.9
X.10 Negative 110 (8.4) 60 (18.2) 50 (5.1) <0.001 X.10
X.11 Not Sent 1169 (89.6) 255 (77.3) 914 (93.8) <0.001 X.11
guideline…. Guideline Adherence 974 (74.7) 0 (0.0) 974 (100.0) <0.001 guideline….
X.12 Follows 164 (12.6) 164 (49.7) 0 (0.0) <0.001 X.12
X.13 Follows but Over-Tested 166 (12.7) 166 (50.3) 0 (0.0) <0.001 X.13
# ── Delta table with highlighting ─────────────────────────────────────────────
delta_t3_result <- build_delta_gt(t3_old, t3_new, "Table 3 Delta: WNV Testing by Guideline Adherence")
delta_t3 <- delta_t3_result$data
delta_t3_result$gt
Table 3 Delta: WNV Testing by Guideline Adherence
OLD Dataset NEW Dataset
Overall (OLD) P (OLD) Overall (NEW) P (NEW)
CSF PCR Ordered 171 (13.1) <0.001 171 (13.1) <0.001
CSF PCR Ordered 1133 (86.9) <0.001 1133 (86.9) <0.001
CSF PCR Result 38 (2.9) <0.001 38 (2.9) <0.001
Positive 4 (0.3) <0.001 4 (0.3) <0.001
Negative 1091 (83.7) <0.001 1091 (83.7) <0.001
Not Sent 171 (13.1) <0.001 171 (13.1) <0.001
CSF IgM Ordered 953 (73.1) <0.001 953 (73.1) <0.001
CSF IgM Ordered 351 (26.9) <0.001 351 (26.9) <0.001
CSF IgM Result 63 (4.8) <0.001 63 (4.8) <0.001
Positive 20 (1.5) <0.001 20 (1.5) <0.001
Negative 268 (20.6) <0.001 268 (20.6) <0.001
Not Sent 953 (73.1) <0.001 953 (73.1) <0.001
Serum IgM Ordered 1169 (89.6) <0.001 1169 (89.6) <0.001
Serum IgM Ordered 135 (10.4) <0.001 135 (10.4) <0.001
Serum IgM Result 14 (1.1) <0.001 14 (1.1) <0.001
Positive 11 (0.8) <0.001 11 (0.8) <0.001
Negative 110 (8.4) <0.001 110 (8.4) <0.001
Not Sent 1169 (89.6) <0.001 1169 (89.6) <0.001
Guideline Adherence 971 (74.5) <0.001 974 (74.7) <0.001
Follows 167 (12.8) <0.001 164 (12.6) <0.001
Follows but Over-Tested 166 (12.7) <0.001 166 (12.7) <0.001

Table 4: WNV Testing by Admitting Service

# ── Table 4 variables ─────────────────────────────────────────────────────────
table4_vars <- c(
  "csfpcr_ordered", "csfpcr_rslt", "csfigm_ordered", "csfigm_rslt",
  "serumigm_ordered", "serumigm_rslt"
)
factor_vars_t4 <- table4_vars

# ── Build Table 4 for OLD and NEW ────────────────────────────────────────────
build_tableone_cat_service <- function(data, vars, fac_vars) {
  tobj <- tableone::CreateTableOne(
    vars = vars, strata = "service", data = data,
    factorVars = fac_vars, addOverall = TRUE
  )
  tmat <- print(tobj, showAllLevels = TRUE, printToggle = FALSE, noSpaces = TRUE)
  tdf <- as.data.frame(tmat, stringsAsFactors = FALSE)

  # Preserve unique rownames as row_id BEFORE any modifications
  tdf$row_id <- rownames(tdf)

  colnames(tdf)[1] <- "level"
  tdf$level <- trimws(tdf$level)

  fld <- lapply(fac_vars, function(x) levels(data[[x]]))
  names(fld) <- fac_vars
  tdf <- suppressMessages(copyPvalueToAllLevels(tdf, fld))

  row_label_dict <- c(
    "csfpcr_ordered...."   = "CSF PCR Ordered",
    "csfpcr_rslt...."      = "CSF PCR Result",
    "csfigm_ordered...."   = "CSF IgM Ordered",
    "csfigm_rslt...."      = "CSF IgM Result",
    "serumigm_ordered...." = "Serum IgM Ordered",
    "serumigm_rslt...."    = "Serum IgM Result"
  )
  for (old_nm in names(row_label_dict)) {
    new_nm <- row_label_dict[[old_nm]]
    tdf$level[rownames(tdf) == old_nm] <- new_nm
  }

  tdf <- tdf[-1, ]
  if ("test" %in% colnames(tdf)) tdf <- dplyr::select(tdf, -test)
  return(tdf)
}

t4_old <- build_tableone_cat_service(data_old, table4_vars, factor_vars_t4)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: csfpcr_ordered"
## [1] "  Factor levels for csfpcr_ordered : CSF PCR Not Ordered, CSF PCR Ordered"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of csfpcr_ordered : 2"
## [1] "  P-value found for csfpcr_ordered : <0.001"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: csfpcr_rslt"
## [1] "  Factor levels for csfpcr_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of csfpcr_rslt : 4, 10, 16"
## [1] "  P-value found for csfpcr_rslt : 0.004"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: csfigm_ordered"
## [1] "  Factor levels for csfigm_ordered : CSF IgM Not Ordered, CSF IgM Ordered"
## [1] "  Rows in df_tableone for these levels: 8, 9"
## [1] "  Rows with p-value in factor levels of csfigm_ordered : 8"
## [1] "  P-value found for csfigm_ordered : <0.001"
## [1] "  P-value copied to rows: 8, 9"
## [1] "Processing variable: csfigm_rslt"
## [1] "  Factor levels for csfigm_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of csfigm_rslt : 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  P-value found for csfigm_rslt : 0.004"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: serumigm_ordered"
## [1] "  Factor levels for serumigm_ordered : Serum IgM Not Ordered, Serum IgM Ordered"
## [1] "  Rows in df_tableone for these levels: 14, 15"
## [1] "  Rows with p-value in factor levels of serumigm_ordered : 14"
## [1] "  P-value found for serumigm_ordered : 0.016"
## [1] "  P-value copied to rows: 14, 15"
## [1] "Processing variable: serumigm_rslt"
## [1] "  Factor levels for serumigm_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of serumigm_rslt : 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  P-value found for serumigm_rslt : 0.004"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
t4_new <- build_tableone_cat_service(data_new, table4_vars, factor_vars_t4)
## [1] "--- Entering copyPvalueToAllLevels function ---"
## [1] "Processing variable: csfpcr_ordered"
## [1] "  Factor levels for csfpcr_ordered : CSF PCR Not Ordered, CSF PCR Ordered"
## [1] "  Rows in df_tableone for these levels: 2, 3"
## [1] "  Rows with p-value in factor levels of csfpcr_ordered : 2"
## [1] "  P-value found for csfpcr_ordered : <0.001"
## [1] "  P-value copied to rows: 2, 3"
## [1] "Processing variable: csfpcr_rslt"
## [1] "  Factor levels for csfpcr_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of csfpcr_rslt : 4, 10, 16"
## [1] "  P-value found for csfpcr_rslt : 0.004"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: csfigm_ordered"
## [1] "  Factor levels for csfigm_ordered : CSF IgM Not Ordered, CSF IgM Ordered"
## [1] "  Rows in df_tableone for these levels: 8, 9"
## [1] "  Rows with p-value in factor levels of csfigm_ordered : 8"
## [1] "  P-value found for csfigm_ordered : <0.001"
## [1] "  P-value copied to rows: 8, 9"
## [1] "Processing variable: csfigm_rslt"
## [1] "  Factor levels for csfigm_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of csfigm_rslt : 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  P-value found for csfigm_rslt : 0.004"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "Processing variable: serumigm_ordered"
## [1] "  Factor levels for serumigm_ordered : Serum IgM Not Ordered, Serum IgM Ordered"
## [1] "  Rows in df_tableone for these levels: 14, 15"
## [1] "  Rows with p-value in factor levels of serumigm_ordered : 14"
## [1] "  P-value found for serumigm_ordered : 0.016"
## [1] "  P-value copied to rows: 14, 15"
## [1] "Processing variable: serumigm_rslt"
## [1] "  Factor levels for serumigm_rslt : Unresulted, Positive, Negative, Not Sent"
## [1] "  Rows in df_tableone for these levels: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  Rows with p-value in factor levels of serumigm_rslt : 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "  P-value found for serumigm_rslt : 0.004"
## [1] "  P-value copied to rows: 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 18, 19"
## [1] "--- Exiting copyPvalueToAllLevels function ---"
## [1] "--- End Debugging ---"
cat("### Table 4 — OLD Dataset\n")
## ### Table 4 — OLD Dataset
knitr::kable(t4_old, caption = "Table 4 (OLD): WNV Testing by Admitting Service")
Table 4 (OLD): WNV Testing by Admitting Service
level Overall Neurology Medicine/Subspecialties Oncology Other p row_id
csfpcr_ordered…. CSF PCR Ordered 171 (13.1) 101 (17.3) 52 (11.4) 10 (5.6) 8 (9.3) <0.001 csfpcr_ordered….
X CSF PCR Ordered 1133 (86.9) 483 (82.7) 404 (88.6) 168 (94.4) 78 (90.7) <0.001 X
csfpcr_rslt…. CSF PCR Result 38 (2.9) 20 (3.4) 13 (2.9) 3 (1.7) 2 (2.3) 0.004 csfpcr_rslt….
X.1 Positive 4 (0.3) 3 (0.5) 1 (0.2) 0 (0.0) 0 (0.0) 0.004 X.1
X.2 Negative 1091 (83.7) 460 (78.8) 390 (85.5) 165 (92.7) 76 (88.4) 0.004 X.2
X.3 Not Sent 171 (13.1) 101 (17.3) 52 (11.4) 10 (5.6) 8 (9.3) 0.004 X.3
csfigm_ordered…. CSF IgM Ordered 953 (73.1) 369 (63.2) 363 (79.6) 150 (84.3) 71 (82.6) <0.001 csfigm_ordered….
X.4 CSF IgM Ordered 351 (26.9) 215 (36.8) 93 (20.4) 28 (15.7) 15 (17.4) <0.001 X.4
csfigm_rslt…. CSF IgM Result 63 (4.8) 37 (6.3) 15 (3.3) 6 (3.4) 5 (5.8) 0.004 csfigm_rslt….
X.5 Positive 20 (1.5) 5 (0.9) 13 (2.9) 2 (1.1) 0 (0.0) 0.004 X.5
X.6 Negative 268 (20.6) 173 (29.6) 65 (14.3) 20 (11.2) 10 (11.6) 0.004 X.6
X.7 Not Sent 953 (73.1) 369 (63.2) 363 (79.6) 150 (84.3) 71 (82.6) 0.004 X.7
serumigm_ordered…. Serum IgM Ordered 1169 (89.6) 506 (86.6) 419 (91.9) 165 (92.7) 79 (91.9) 0.016 serumigm_ordered….
X.8 Serum IgM Ordered 135 (10.4) 78 (13.4) 37 (8.1) 13 (7.3) 7 (8.1) 0.016 X.8
serumigm_rslt…. Serum IgM Result 14 (1.1) 3 (0.5) 9 (2.0) 0 (0.0) 2 (2.3) 0.004 serumigm_rslt….
X.9 Positive 11 (0.8) 4 (0.7) 6 (1.3) 1 (0.6) 0 (0.0) 0.004 X.9
X.10 Negative 110 (8.4) 71 (12.2) 22 (4.8) 12 (6.7) 5 (5.8) 0.004 X.10
X.11 Not Sent 1169 (89.6) 506 (86.6) 419 (91.9) 165 (92.7) 79 (91.9) 0.004 X.11
cat("\n### Table 4 — NEW Dataset\n")
## 
## ### Table 4 — NEW Dataset
knitr::kable(t4_new, caption = "Table 4 (NEW): WNV Testing by Admitting Service")
Table 4 (NEW): WNV Testing by Admitting Service
level Overall Neurology Medicine/Subspecialties Oncology Other p row_id
csfpcr_ordered…. CSF PCR Ordered 171 (13.1) 101 (17.3) 52 (11.4) 10 (5.6) 8 (9.3) <0.001 csfpcr_ordered….
X CSF PCR Ordered 1133 (86.9) 483 (82.7) 404 (88.6) 168 (94.4) 78 (90.7) <0.001 X
csfpcr_rslt…. CSF PCR Result 38 (2.9) 20 (3.4) 13 (2.9) 3 (1.7) 2 (2.3) 0.004 csfpcr_rslt….
X.1 Positive 4 (0.3) 3 (0.5) 1 (0.2) 0 (0.0) 0 (0.0) 0.004 X.1
X.2 Negative 1091 (83.7) 460 (78.8) 390 (85.5) 165 (92.7) 76 (88.4) 0.004 X.2
X.3 Not Sent 171 (13.1) 101 (17.3) 52 (11.4) 10 (5.6) 8 (9.3) 0.004 X.3
csfigm_ordered…. CSF IgM Ordered 953 (73.1) 369 (63.2) 363 (79.6) 150 (84.3) 71 (82.6) <0.001 csfigm_ordered….
X.4 CSF IgM Ordered 351 (26.9) 215 (36.8) 93 (20.4) 28 (15.7) 15 (17.4) <0.001 X.4
csfigm_rslt…. CSF IgM Result 63 (4.8) 37 (6.3) 15 (3.3) 6 (3.4) 5 (5.8) 0.004 csfigm_rslt….
X.5 Positive 20 (1.5) 5 (0.9) 13 (2.9) 2 (1.1) 0 (0.0) 0.004 X.5
X.6 Negative 268 (20.6) 173 (29.6) 65 (14.3) 20 (11.2) 10 (11.6) 0.004 X.6
X.7 Not Sent 953 (73.1) 369 (63.2) 363 (79.6) 150 (84.3) 71 (82.6) 0.004 X.7
serumigm_ordered…. Serum IgM Ordered 1169 (89.6) 506 (86.6) 419 (91.9) 165 (92.7) 79 (91.9) 0.016 serumigm_ordered….
X.8 Serum IgM Ordered 135 (10.4) 78 (13.4) 37 (8.1) 13 (7.3) 7 (8.1) 0.016 X.8
serumigm_rslt…. Serum IgM Result 14 (1.1) 3 (0.5) 9 (2.0) 0 (0.0) 2 (2.3) 0.004 serumigm_rslt….
X.9 Positive 11 (0.8) 4 (0.7) 6 (1.3) 1 (0.6) 0 (0.0) 0.004 X.9
X.10 Negative 110 (8.4) 71 (12.2) 22 (4.8) 12 (6.7) 5 (5.8) 0.004 X.10
X.11 Not Sent 1169 (89.6) 506 (86.6) 419 (91.9) 165 (92.7) 79 (91.9) 0.004 X.11
# ── Delta table with highlighting ─────────────────────────────────────────────
delta_t4_result <- build_delta_gt(t4_old, t4_new, "Table 4 Delta: WNV Testing by Admitting Service")
delta_t4 <- delta_t4_result$data
delta_t4_result$gt
Table 4 Delta: WNV Testing by Admitting Service
OLD Dataset NEW Dataset
Overall (OLD) P (OLD) Overall (NEW) P (NEW)
CSF PCR Ordered 171 (13.1) <0.001 171 (13.1) <0.001
CSF PCR Ordered 1133 (86.9) <0.001 1133 (86.9) <0.001
CSF PCR Result 38 (2.9) 0.004 38 (2.9) 0.004
Positive 4 (0.3) 0.004 4 (0.3) 0.004
Negative 1091 (83.7) 0.004 1091 (83.7) 0.004
Not Sent 171 (13.1) 0.004 171 (13.1) 0.004
CSF IgM Ordered 953 (73.1) <0.001 953 (73.1) <0.001
CSF IgM Ordered 351 (26.9) <0.001 351 (26.9) <0.001
CSF IgM Result 63 (4.8) 0.004 63 (4.8) 0.004
Positive 20 (1.5) 0.004 20 (1.5) 0.004
Negative 268 (20.6) 0.004 268 (20.6) 0.004
Not Sent 953 (73.1) 0.004 953 (73.1) 0.004
Serum IgM Ordered 1169 (89.6) 0.016 1169 (89.6) 0.016
Serum IgM Ordered 135 (10.4) 0.016 135 (10.4) 0.016
Serum IgM Result 14 (1.1) 0.004 14 (1.1) 0.004
Positive 11 (0.8) 0.004 11 (0.8) 0.004
Negative 110 (8.4) 0.004 110 (8.4) 0.004
Not Sent 1169 (89.6) 0.004 1169 (89.6) 0.004

Figure 1: Yearly Adherence vs WNV Cases

# ── Helper: compute yearly summary ───────────────────────────────────────────
compute_yearly_summary <- function(data) {
  data %>%
    dplyr::filter(!is.na(csfdate)) %>%
    dplyr::mutate(
      year = format(as.Date(csfdate), "%Y"),
      is_adherent = (guideline2 == "Adherent"),
      is_wnv_positive = (wnvpos == "Positive WNV")
    ) %>%
    dplyr::group_by(year) %>%
    dplyr::summarise(
      adherence_rate   = mean(is_adherent, na.rm = TRUE) * 100,
      cohort_wnv_cases = sum(is_wnv_positive, na.rm = TRUE),
      .groups = "drop"
    ) %>%
    dplyr::filter(!is.na(year) & !is.na(adherence_rate) & !is.na(cohort_wnv_cases))
}

yearly_old <- compute_yearly_summary(data_old)
yearly_new <- compute_yearly_summary(data_new)

# ── Generate plots using helper function ──────────────────────────────────────
fig1_old <- plot_adherence_vs_cases(yearly_old) +
  ggplot2::ggtitle("OLD Dataset: Adherence vs WNV Cases")
fig1_new <- plot_adherence_vs_cases(yearly_new) +
  ggplot2::ggtitle("NEW Dataset: Adherence vs WNV Cases")

# ── Side-by-side with gridExtra ───────────────────────────────────────────────
fig1_combined <- gridExtra::arrangeGrob(
  fig1_old, fig1_new, ncol = 2,
  top = grid::textGrob("Figure 1 Comparison: Yearly Adherence vs WNV Cases",
                        gp = grid::gpar(fontsize = 16, fontface = "bold"))
)
grid::grid.draw(fig1_combined)

# ── Save ──────────────────────────────────────────────────────────────────────
ggplot2::ggsave(
  filename = fs::path(params$export_dir, "Figure1_Comparison_Adherence_vs_Cases.png"),
  plot = fig1_combined, width = 14, height = 6, dpi = 300, bg = "white"
)
message("Figure 1 comparison saved.")

# ── Yearly summary delta table ────────────────────────────────────────────────
yearly_delta <- dplyr::full_join(
  yearly_old %>% dplyr::rename(adherence_old = adherence_rate, cases_old = cohort_wnv_cases),
  yearly_new %>% dplyr::rename(adherence_new = adherence_rate, cases_new = cohort_wnv_cases),
  by = "year"
) %>% dplyr::mutate(
  delta_adherence = round(adherence_new - adherence_old, 2),
  delta_cases     = cases_new - cases_old
)
knitr::kable(yearly_delta, caption = "Yearly Summary Delta: OLD vs NEW")
Yearly Summary Delta: OLD vs NEW
year adherence_old cases_old adherence_new cases_new delta_adherence delta_cases
2016 33.33333 4 33.33333 4 0.00 0
2017 21.78218 2 21.28713 2 -0.50 0
2018 21.64948 11 21.64948 11 0.00 0
2019 22.63158 1 22.63158 1 0.00 0
2020 26.76056 0 26.05634 0 -0.70 0
2021 25.00000 3 25.00000 3 0.00 0
2022 24.26471 3 24.26471 3 0.00 0
2023 31.81818 2 31.25000 2 -0.57 0

Figure 2: Forest Plot (Logistic Regression)

# ── Helper: prepare model data ────────────────────────────────────────────────
prepare_model_data <- function(data) {
  data %>%
    dplyr::mutate(
      adherent_bin = ifelse(guideline2 == "Adherent", 1, 0),
      site = forcats::fct_relevel(site, "Brigham and Women's Hospital"),
      service2 = forcats::fct_collapse(service,
        "Neurology" = "Neurology",
        "Medicine/Other" = c("Medicine/Subspecialties", "Oncology", "Other")
      ) %>% forcats::fct_relevel("Medicine/Other"),
      immunosup = forcats::fct_relevel(immunosup, "Immunosuppressed"),
      csflymph_bin = forcats::fct_collapse(csflymph50,
        "Pleocytosis (Lymph >= 50%)" = "Pleocytosis (Lymph \u2265 50%)",
        "No pleocytosis / normal" = c("Normal CSF Cell Count (CSF TNC < 5)", "Pleocytosis (Lymph < 50%)")
      ) %>% forcats::fct_relevel("No pleocytosis / normal"),
      csftp60 = forcats::fct_relevel(csftp60, "CSF TP < 60")
    )
}

predictor_labels <- c(
  "Admission at MGH (vs BWH)",
  "Admission to Neurology (vs Medicine/Other)",
  "Immunocompetent (vs Immunosuppressed)",
  "Presence of CSF lymphocytic pleocytosis",
  "CSF protein elevated >60 mg/dL"
)

model_old <- prepare_model_data(data_old)
model_new <- prepare_model_data(data_new)

# ── Generate forest plots ─────────────────────────────────────────────────────
forest_old <- make_forest_plot_adherence(
  model_data = model_old,
  predictors = c("site", "service2", "immunosup", "csflymph_bin", "csftp60"),
  predictor_labels = predictor_labels
)
forest_new <- make_forest_plot_adherence(
  model_data = model_new,
  predictors = c("site", "service2", "immunosup", "csflymph_bin", "csftp60"),
  predictor_labels = predictor_labels
)

fig2_old <- forest_old$plot + ggplot2::ggtitle("OLD Dataset")
fig2_new <- forest_new$plot + ggplot2::ggtitle("NEW Dataset")

# ── Side-by-side with gridExtra ───────────────────────────────────────────────
fig2_combined <- gridExtra::arrangeGrob(
  fig2_old, fig2_new, ncol = 2,
  top = grid::textGrob("Figure 2 Comparison: Factors Associated with Guideline Adherence",
                        gp = grid::gpar(fontsize = 16, fontface = "bold"))
)
grid::grid.draw(fig2_combined)

# ── Save ──────────────────────────────────────────────────────────────────────
ggplot2::ggsave(
  filename = fs::path(params$export_dir, "Figure2_Comparison_Forest_Plot.png"),
  plot = fig2_combined, width = 14, height = 6, dpi = 300, bg = "white"
)
message("Figure 2 comparison saved.")

Regression Model Comparison

# ── Extract tidied OR tables from forest plot results ─────────────────────────
or_old <- forest_old$table %>%
  dplyr::select(predictor_display, estimate, conf.low, conf.high, p.value) %>%
  dplyr::rename(
    Predictor = predictor_display,
    OR_old = estimate, CI_low_old = conf.low, CI_high_old = conf.high, p_old = p.value
  )

or_new <- forest_new$table %>%
  dplyr::select(predictor_display, estimate, conf.low, conf.high, p.value) %>%
  dplyr::rename(
    Predictor = predictor_display,
    OR_new = estimate, CI_low_new = conf.low, CI_high_new = conf.high, p_new = p.value
  )

# ── Merge into comparison table ───────────────────────────────────────────────
or_compare <- dplyr::inner_join(or_old, or_new, by = "Predictor") %>%
  dplyr::mutate(
    OR_old_fmt  = sprintf("%.2f (%.2f - %.2f)", OR_old, CI_low_old, CI_high_old),
    OR_new_fmt  = sprintf("%.2f (%.2f - %.2f)", OR_new, CI_low_new, CI_high_new),
    Delta_OR    = round(OR_new - OR_old, 3),
    p_old_fmt   = ifelse(p_old < 0.001, "<0.001", sprintf("%.3f", p_old)),
    p_new_fmt   = ifelse(p_new < 0.001, "<0.001", sprintf("%.3f", p_new)),
    Sig_Change  = dplyr::case_when(
      p_old < 0.05 & p_new >= 0.05 ~ "Lost significance",
      p_old >= 0.05 & p_new < 0.05 ~ "Gained significance",
      TRUE ~ "No change"
    )
  ) %>%
  dplyr::select(Predictor, OR_old_fmt, p_old_fmt, OR_new_fmt, p_new_fmt, Delta_OR, Sig_Change)

# ── Display as gt table ──────────────────────────────────────────────────────
gt_regression <- or_compare %>%
  gt::gt() %>%
  gt::tab_header(
    title = gt::md("**Regression Model Comparison: OLD vs NEW**"),
    subtitle = "Logistic regression predicting guideline adherence"
  ) %>%
  gt::cols_label(
    Predictor   = "Predictor",
    OR_old_fmt  = "OR (95% CI) — OLD",
    p_old_fmt   = "P-value — OLD",
    OR_new_fmt  = "OR (95% CI) — NEW",
    p_new_fmt   = "P-value — NEW",
    Delta_OR    = gt::md("&Delta; OR"),
    Sig_Change  = "Significance Change"
  ) %>%
  gt::tab_style(
    style = gt::cell_fill(color = "lightyellow"),
    locations = gt::cells_body(rows = Sig_Change != "No change")
  ) %>%
  gt::cols_align(align = "center") %>%
  gt::cols_align(align = "left", columns = Predictor) %>%
  gt::tab_options(table.width = gt::pct(100), table.font.size = gt::px(12))

gt_regression
Regression Model Comparison: OLD vs NEW
Logistic regression predicting guideline adherence
Predictor OR (95% CI) — OLD P-value — OLD OR (95% CI) — NEW P-value — NEW Δ OR Significance Change
Admission at MGH (vs BWH) 1.92 (1.45 - 2.55) <0.001 1.93 (1.46 - 2.56) <0.001 0.010 No change
Admission to Neurology (vs Medicine/Other) 2.07 (1.58 - 2.73) <0.001 2.02 (1.54 - 2.66) <0.001 -0.057 No change
Immunocompetent (vs Immunosuppressed) 3.21 (1.81 - 6.17) <0.001 3.98 (2.26 - 7.60) <0.001 0.765 No change
Presence of CSF lymphocytic pleocytosis 2.66 (1.98 - 3.57) <0.001 2.65 (1.97 - 3.57) <0.001 -0.005 No change
CSF protein elevated >60 mg/dL 1.44 (1.08 - 1.91) 0.012 1.42 (1.06 - 1.89) 0.017 -0.022 No change

Executive Summary

# ── Auto-generated summary of key changes ─────────────────────────────────────
n_old <- nrow(data_old)
n_new <- nrow(data_new)

adherence_old <- mean(data_old$guideline2 == "Adherent", na.rm = TRUE) * 100
adherence_new <- mean(data_new$guideline2 == "Adherent", na.rm = TRUE) * 100

wnv_pos_old <- sum(data_old$wnvpos == "Positive WNV", na.rm = TRUE)
wnv_pos_new <- sum(data_new$wnvpos == "Positive WNV", na.rm = TRUE)

# Count significance changes in regression
sig_changes <- sum(or_compare$Sig_Change != "No change")

summary_df <- tibble(
  Metric = c(
    "Sample Size (N)",
    "Overall Adherence Rate (%)",
    "WNV Positive Cases (n)",
    "Regression: Predictors with Significance Change"
  ),
  OLD = c(
    as.character(n_old),
    sprintf("%.1f%%", adherence_old),
    as.character(wnv_pos_old),
    ""
  ),
  NEW = c(
    as.character(n_new),
    sprintf("%.1f%%", adherence_new),
    as.character(wnv_pos_new),
    ""
  ),
  Delta = c(
    as.character(n_new - n_old),
    sprintf("%+.1f pp", adherence_new - adherence_old),
    as.character(wnv_pos_new - wnv_pos_old),
    as.character(sig_changes)
  )
)

gt_summary <- summary_df %>%
  gt::gt() %>%
  gt::tab_header(title = gt::md("**Executive Summary: Key Changes Between Datasets**")) %>%
  gt::cols_align(align = "center") %>%
  gt::cols_align(align = "left", columns = Metric) %>%
  gt::tab_style(
    style = gt::cell_text(weight = "bold"),
    locations = gt::cells_column_labels()
  ) %>%
  gt::tab_options(table.width = gt::pct(80), table.font.size = gt::px(13))

gt_summary
Executive Summary: Key Changes Between Datasets
Metric OLD NEW Delta
Sample Size (N) 1304 1304 0
Overall Adherence Rate (%) 25.5% 25.3% -0.2 pp
WNV Positive Cases (n) 26 26 0
Regression: Predictors with Significance Change 0

Word Export

# ── Flextable helper ──────────────────────────────────────────────────────────
make_ft <- function(df, caption_text) {
  flextable::flextable(df) %>%
    flextable::bold(part = "header") %>%
    flextable::align(align = "center", part = "all") %>%
    flextable::align(align = "left", j = 1, part = "all") %>%
    flextable::border_remove() %>%
    flextable::border_outer(border = officer::fp_border(width = 1)) %>%
    flextable::border_inner_h(border = officer::fp_border(width = 1)) %>%
    flextable::border_inner_v(border = officer::fp_border(width = 1)) %>%
    flextable::autofit() %>%
    flextable::padding(padding = 2, part = "all") %>%
    flextable::set_caption(caption = caption_text)
}

# ── Build Word document ───────────────────────────────────────────────────────
doc <- officer::read_docx()

# Executive Summary
doc <- officer::body_add_par(doc, "Executive Summary: Key Changes Between Datasets", style = "heading 1")
doc <- flextable::body_add_flextable(doc, value = make_ft(summary_df, "Executive Summary"))
doc <- officer::body_add_break(doc)

# Helper: strip internal boolean columns before making flextable
strip_delta_cols <- function(df) {
  df %>% dplyr::select(-dplyr::any_of(c("overall_changed", "p_changed")))
}

# Table 1 Delta
doc <- officer::body_add_par(doc, "Table 1 Delta: Demographics by Guideline Adherence", style = "heading 1")
doc <- flextable::body_add_flextable(doc, value = make_ft(strip_delta_cols(delta_t1), "Table 1 Delta"))
doc <- officer::body_add_break(doc)

# Table New Delta
doc <- officer::body_add_par(doc, "Table New Delta: Demographics by Immune Status", style = "heading 1")
doc <- flextable::body_add_flextable(doc, value = make_ft(strip_delta_cols(delta_tn), "Table New Delta"))
doc <- officer::body_add_break(doc)

# Table 2 Delta
doc <- officer::body_add_par(doc, "Table 2 Delta: Demographics by WNV Positivity", style = "heading 1")
doc <- flextable::body_add_flextable(doc, value = make_ft(strip_delta_cols(delta_t2), "Table 2 Delta"))
doc <- officer::body_add_break(doc)

# Table 3 Delta
doc <- officer::body_add_par(doc, "Table 3 Delta: WNV Testing by Guideline Adherence", style = "heading 1")
doc <- flextable::body_add_flextable(doc, value = make_ft(strip_delta_cols(delta_t3), "Table 3 Delta"))
doc <- officer::body_add_break(doc)

# Table 4 Delta
doc <- officer::body_add_par(doc, "Table 4 Delta: WNV Testing by Admitting Service", style = "heading 1")
doc <- flextable::body_add_flextable(doc, value = make_ft(strip_delta_cols(delta_t4), "Table 4 Delta"))
doc <- officer::body_add_break(doc)

# Regression Comparison
doc <- officer::body_add_par(doc, "Regression Model Comparison", style = "heading 1")
doc <- flextable::body_add_flextable(doc, value = make_ft(or_compare, "Regression Comparison: OLD vs NEW"))
doc <- officer::body_add_break(doc)

# Figure 1
doc <- officer::body_add_par(doc, "Figure 1: Yearly Adherence vs WNV Cases", style = "heading 1")
fig1_path <- fs::path(params$export_dir, "Figure1_Comparison_Adherence_vs_Cases.png")
if (file.exists(fig1_path)) {
  doc <- officer::body_add_img(doc, src = fig1_path, width = 7, height = 3, style = "centered")
}
doc <- officer::body_add_break(doc)

# Figure 2
doc <- officer::body_add_par(doc, "Figure 2: Factors Associated with Guideline Adherence", style = "heading 1")
fig2_path <- fs::path(params$export_dir, "Figure2_Comparison_Forest_Plot.png")
if (file.exists(fig2_path)) {
  doc <- officer::body_add_img(doc, src = fig2_path, width = 7, height = 3, style = "centered")
}

# ── Save Word document ───────────────────────────────────────────────────────
report_path <- fs::path(params$export_dir, "Comparison_Report_Feb2026.docx")
print(doc, target = report_path)
message(glue("Word report saved to: {report_path}"))