knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
options("optmatch_max_problem_size" = Inf)
library(nsqipPancreatectomy)

We will start by applying some exclusion criteria. The following inclusion criteria apply:

df <- df %>% dplyr::filter(
  inout,
  transt == 2,
  !is.na(age),
  !is.na(height),
  !is.na(weight),
  (surgspec == 2 | is.na(surgspec)),
  (electsurg | is.na(electsurg)),
  (!ventilat | is.na(ventilat)),
  (!discancr | is.na(discancr)),
  (!wndinf | is.na(wndinf)),
  (!prsepis | is.na(prsepis)),
  (!emergncy | is.na(emergncy)),
  asaclas < 5, 
  optime > 20,
  (is.na(pan_gastduo) | pan_gastduo == 3),
  (pan_mstage != 2 | is.na(pan_mstage)),
  (pan_reconstruction == 4 | is.na(pan_reconstruction)),
  !(is.na(pan_malig_histologic) & is.na(pan_benign_histologic)),
  ((pan_malig_histologic != 1 & pan_malig_histologic != 3 & 
      pan_malig_histologic != 4) | is.na(pan_malig_histologic))
)

I will repeat the analysis I completed previously.

df$pan_approach <- factor(df$pan_approach, levels = c(1,2,3,4,5,6,7,8), 
                          labels = c("Hybrid","Laparoscopic","NOTES","Open (planned)",
                                     "Other","Other MIS","Robotic","SILS"))

df <- df %>% 
  dplyr::filter(pan_approach %in% c("Laparoscopic","Robotic","Open (planned)"),
                !pan_open_assist) %>%
  dplyr::mutate(group = pan_approach %in% c("Robotic", "Laparoscopic")) %>%
  dplyr::mutate(subgroup = ((pan_approach %in% c("Robotic", "Laparoscopic")) + pan_unplanned_conversion))

Next, we will assign a variable to each patient indicating if they have an additional CPT coding for splenectomy:

spleen_vec <- df %>% 
  dplyr::rename(othercpt0 = cpt) %>%
  dplyr::mutate(dplyr::across(c(dplyr::starts_with("othercpt"), dplyr::starts_with("concpt")), as.character)) %>%
  tidyr::pivot_longer(cols = c(dplyr::starts_with("othercpt"), dplyr::starts_with("concpt")), values_to = c("cpt"), names_repair = "unique") %>% 
  dplyr::filter(cpt %in% c("38129","38100","38101","38102")) %>%
  dplyr::pull(caseid) %>%
  unique()

df <- df %>% 
  dplyr::mutate(spleen = dplyr::if_else(caseid %in% spleen_vec, TRUE, FALSE))
df <- df %>%
  dplyr::mutate(bmi = bmi(height, weight),
                pan_benign_histologic = !is.na(pan_benign_histologic))
df <- df %>%
  dplyr::mutate(fnstatus2 = factor(.$fnstatus2, levels = c(1, 2, 3), labels = c("Independent","Partially dependent","Totally dependent")),
                pan_ductsize = factor(.$pan_ductsize, levels = c(1, 2, 3), labels = c("<3 mm","3-6 mm",">6 mm")),
                wndclas = factor(wndclas),
                asaclas = factor(asaclas),
                pan_glandtext = factor(.$pan_glandtext, levels = c(1, 2, 3), labels = c("Soft","Intermediate","Hard")),
                pan_malig_histologic = factor(.$pan_malig_histologic, levels = c(2, 5:9), labels = c("Cystadenocarcinoma", "IPMN-invasive", "Neuroendocrine-functioning", "Neuroendocrine-nonfunctioning", "Pancreatic adenocarcinoma", "Other type")),
                pan_malig_histologic = forcats::fct_explicit_na(pan_malig_histologic, "No malignancy"),
                pan_tstage = factor(.$pan_tstage, levels = c(1:7), labels = c("T0","T1","T2","T3","T4","Tis","Tx")),
                pan_tstage = forcats::fct_explicit_na(pan_tstage, "No T stage"),
                pan_nstage = factor(.$pan_nstage, levels = c(1:3), labels = c("N0","N1","Nx")),
                pan_nstage = forcats::fct_explicit_na(pan_nstage, "No N stage"),
                death = !is.na(yrdeath)
  ) %>% dplyr::mutate(dplyr::across(c("diabetes","smoke","hxcopd","ascites","hxchf","hypermed","dialysis","steroid","wtloss","bleeddis","pan_chemo","pan_radio", "pan_drains"), ~tidyr::replace_na(.x, FALSE)))

Hmisc::label(df$sex) = "Male"
Hmisc::label(df$age) = "Age"
Hmisc::label(df$bmi) = "BMI"
Hmisc::label(df$diabetes) = "Diabetes"
Hmisc::label(df$smoke) = "Smoking"
Hmisc::label(df$fnstatus2) = "Functional Status"
Hmisc::label(df$hxcopd) = "COPD"
Hmisc::label(df$ascites) = "Ascites"
Hmisc::label(df$hxchf) = "CHF"
Hmisc::label(df$hypermed) = "Hypertension medication"
Hmisc::label(df$dialysis) = "Dialysis"
Hmisc::label(df$steroid) = "Steroids"
Hmisc::label(df$wtloss) = "Weight loss"
Hmisc::label(df$bleeddis) = "Bleeding disorder"
Hmisc::label(df$spleen) = "Splenectomy"
Hmisc::label(df$wndclas) = "Wound class"
Hmisc::label(df$asaclas) = "ASA class"
Hmisc::label(df$pan_chemo) = "Chemotherapy"
Hmisc::label(df$pan_radio) = "Radiotherapy"
Hmisc::label(df$pan_ductsize) = "Duct size"
Hmisc::label(df$pan_glandtext) = "Gland texture"
Hmisc::label(df$pan_drains) = "Drains"
Hmisc::label(df$pan_malig_histologic) = "Malignant histology"
Hmisc::label(df$pan_benign_histologic) = "Benign histology"
Hmisc::label(df$pan_tstage) = "T stage"
Hmisc::label(df$pan_nstage) = "N stage"
Hmisc::label(df$supinfec) = "Superficial SSI"
Hmisc::label(df$wndinfd) = "Deep SSI"
Hmisc::label(df$orgspcssi) = "Organ Space SSI"
Hmisc::label(df$pulembol) = "Pulmonary embolism"
Hmisc::label(df$reintub) = "Reintubation"
Hmisc::label(df$failwean) = "Failure to wean"
Hmisc::label(df$renainsf) = "Renal insufficiency"
Hmisc::label(df$oprenafl) = "Renal failure"
Hmisc::label(df$death) = "Death"

We can now perform a match on the following variables:

I will make the assumption for the following variables that missing data is equivalent to FALSE:

This is a big assumption and may be something you want to change.

With duct size and gland texture

matchdf <- df %>% 
  dplyr::select(caseid, group, sex, age, bmi, diabetes, smoke, fnstatus2, hxcopd, ascites, hxchf, hypermed, dialysis, steroid, wtloss, bleeddis, spleen, wndclas, asaclas, pan_chemo, pan_radio,
                         pan_ductsize, pan_glandtext, pan_drains, pan_malig_histologic, pan_benign_histologic, pan_tstage, pan_nstage)

Many of the patients are missing data in the duct size and gland texture. Unfortunately, matching requires complete data, so I will first run a match using duct size and gland texture then a larger match without those variables.

match1 <- matchdf %>% dplyr::filter(complete.cases(.))
m1.data <- MatchIt::matchit(group ~ sex + age + bmi + diabetes + smoke + fnstatus2 + hxcopd + ascites + hxchf + hypermed + dialysis + steroid + wtloss + bleeddis + spleen + wndclas + asaclas + pan_chemo + pan_radio + pan_ductsize + pan_glandtext + pan_drains + pan_malig_histologic + pan_benign_histologic + pan_tstage + pan_nstage, data = match1) %>% MatchIt::match.data()

Note that for the tables below, "group" refers to MIS or open. "Yes" refers to the MIS group, "No" refers to the open group. I can format this better for the final document of course.

suppressWarnings(nsqipBileSpill::tableone(m1.data, sex, age, bmi, diabetes, smoke, fnstatus2, hxcopd, ascites, hxchf, hypermed, dialysis, steroid, wtloss, bleeddis, spleen, wndclas, asaclas, pan_chemo, pan_radio, pan_ductsize, pan_glandtext, pan_drains, pan_malig_histologic, pan_benign_histologic, pan_tstage, pan_nstage, group = group))
m1.data <- dplyr::left_join(m1.data, df)

And we can now compare the outcomes:

suppressWarnings(nsqipBileSpill::tableone(m1.data, supinfec, wndinfd, orgspcssi, pulembol, reintub, failwean, renainsf, oprenafl, death, group = group))

Without duct size and gland texture

matchdf2 <- df %>% 
  dplyr::select(caseid, group, sex, age, bmi, diabetes, smoke, fnstatus2, hxcopd, ascites, hxchf, hypermed, dialysis, steroid, wtloss, bleeddis, spleen, wndclas, asaclas, pan_chemo, pan_radio,
                         pan_drains, pan_malig_histologic, pan_benign_histologic, pan_tstage, pan_nstage)
match2 <- matchdf2 %>% dplyr::filter(complete.cases(.))
m2.data <- MatchIt::matchit(group ~ sex + age + bmi + diabetes + smoke + fnstatus2 + hxcopd + ascites + hxchf + hypermed + dialysis + steroid + wtloss + bleeddis + spleen + wndclas + asaclas + pan_chemo + pan_radio + pan_drains + pan_malig_histologic + pan_benign_histologic + pan_tstage + pan_nstage, data = match2, method = "full") %>% MatchIt::match.data()
suppressWarnings(nsqipBileSpill::tableone(m2.data, sex, age, bmi, diabetes, smoke, fnstatus2, hxcopd, ascites, hxchf, hypermed, dialysis, steroid, wtloss, bleeddis, spleen, wndclas, asaclas, pan_chemo, pan_radio, pan_drains, pan_malig_histologic, pan_benign_histologic, pan_tstage, pan_nstage, group = group))
m2.data <- dplyr::left_join(m2.data, df)

And we can now compare the outcomes:

suppressWarnings(nsqipBileSpill::tableone(m2.data, supinfec, wndinfd, orgspcssi, pulembol, reintub, failwean, renainsf, oprenafl, death, group = group))


dylanrussellmd/nsqipPancreatectomy documentation built on Sept. 16, 2020, 12:46 a.m.