Figure 1 - Hazard Ratio Analysis of Fiber Intake

This figure is largely concerned with fiber analysis in the Genito-urinary survey cohort.

The data we are visualizing here has the following structure:

Panel A

We start with some summaries of the cohorts used here:

Genito-Urinary Survey Cohort:
86
Mixed Solid Tumor Cohort:
147
External Melanoma Cohort:
157
External RCC Cohort:
28

Panel B

Mortality Hazard for PFS by daily average fiber intake, visualized via partial smoothing spline. Ticks along the x axis represent individual patients.

cox_pfs_allMet_uv <-coxph(Surv(pfs_mo,
                               pod_status)~  fiber_5g_increment,
                          gu_cohort_data)

cat(paste(
  "-----------------------------------------------\n\np value fiber in 5g increments, PFS:",
  round(summary(cox_pfs_allMet_uv)$coefficients["fiber_5g_increment", "Pr(>|z|)"],digits = 3),
  "\n\n-----------------------------------------------\n\n"
))
-----------------------------------------------

p value fiber in 5g increments, PFS: 0.045 

-----------------------------------------------
summary(cox_pfs_allMet_uv)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_5g_increment, 
    data = gu_cohort_data)

  n= 86, number of events= 55 

                       coef exp(coef) se(coef)      z Pr(>|z|)  
fiber_5g_increment -0.16721   0.84602  0.08357 -2.001   0.0454 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

                   exp(coef) exp(-coef) lower .95 upper .95
fiber_5g_increment     0.846      1.182    0.7182    0.9966

Concordance= 0.597  (se = 0.039 )
Likelihood ratio test= 4.46  on 1 df,   p=0.03
Wald test            = 4  on 1 df,   p=0.05
Score (logrank) test = 4.04  on 1 df,   p=0.04

Panel C

Mortality Hazard for OS by daily average fiber intake, visualized via partial smoothing spline. Ticks along the x axis represent individual patients.

cox_os_allMet_uv <-coxph(Surv(os_mo,
                              os_status)~  fiber_5g_increment,
                         gu_cohort_data)

cat(paste(
  "-----------------------------------------------\n\np value fiber in 5g increments, OS:",
  round(summary(cox_os_allMet_uv)$coefficients["fiber_5g_increment", "Pr(>|z|)"],digits = 3),
  "\n\n-----------------------------------------------\n\n"
))
-----------------------------------------------

p value fiber in 5g increments, OS: 0.048 

-----------------------------------------------
summary(cox_os_allMet_uv)
Call:
coxph(formula = Surv(os_mo, os_status) ~ fiber_5g_increment, 
    data = gu_cohort_data)

  n= 86, number of events= 26 

                      coef exp(coef) se(coef)      z Pr(>|z|)  
fiber_5g_increment -0.2626    0.7690   0.1327 -1.979   0.0478 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

                   exp(coef) exp(-coef) lower .95 upper .95
fiber_5g_increment     0.769        1.3    0.5929    0.9974

Concordance= 0.65  (se = 0.049 )
Likelihood ratio test= 4.59  on 1 df,   p=0.03
Wald test            = 3.92  on 1 df,   p=0.05
Score (logrank) test = 3.98  on 1 df,   p=0.05

Panel D

Kaplan-Meier PFS by fiber intake tertiles.

cox_pfs_allMet_mv <-coxph(Surv(pfs_mo,
                               pod_status)~ fiber_tertile_factor + 
                            strata(age_cat) + 
                            ecog_1to5_final +
                            cancer_RCCvsUC_NAME +
                            stage.simplified.factor,
                          gu_cohort_data
)

cat(paste(
  "-----------------------------------------------\n\nWald p value top vs bottom tertile, PFS:",
  round(summary(cox_pfs_allMet_mv)$coefficients["fiber_tertile_factorT3 (highest)", "Pr(>|z|)"],digits = 3),
  "\n\n-----------------------------------------------\n\n"
))
-----------------------------------------------

Wald p value top vs bottom tertile, PFS: 0.042 

-----------------------------------------------

Panel E

Kaplan-Meier OS by fiber tertile.

cox_os_allMet_mv <-coxph(Surv(os_mo,
                               os_status)~ fiber_tertile_factor + 
                            strata(age_cat) + 
                            ecog_1to5_final +
                            cancer_RCCvsUC_NAME +
                            stage.simplified.factor,
                          gu_cohort_data
)

cat(paste(
  "-----------------------------------------------\n\nWald p value top vs bottom tertile, PFS:",
  round(summary(cox_os_allMet_mv)$coefficients["fiber_tertile_factorT3 (highest)", "Pr(>|z|)"],digits = 3),
  "\n\n-----------------------------------------------\n\n"
))
-----------------------------------------------

Wald p value top vs bottom tertile, PFS: 0.051 

-----------------------------------------------

Panel F

Univariate HRs for PFS among clinically relevant subgroups in the highest versus lowest tertile of fiber consumption.

# Prep cohorts:
mUCdataFiber=filter(gu_cohort_data,cancer_type!=4)
dataUCavelumabFiber=filter(mUCdataFiber,io_regimen==5)
dataUC_NOTavelumabFiber=filter(mUCdataFiber,io_regimen!=5)

mRCdataFiber=filter(gu_cohort_data,cancer_type==4)
dataRCIpiNivoFiber=filter(mRCdataFiber,io_regimen==9 | io_regimen==17)
dataRCioTKIFiber=filter(mRCdataFiber,io_regimen==8 | io_regimen==18 | io_regimen==10 | io_regimen==11 | io_regimen==16 | io_regimen==12)

# Get pvalues:

cox_pfs_all_uv <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor,
                       gu_cohort_data)
summary(cox_pfs_all_uv)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor, 
    data = gu_cohort_data)

  n= 86, number of events= 55 

                                    coef exp(coef) se(coef)      z Pr(>|z|)  
fiber_tertile_factorT2 (middle)  -0.6252    0.5351   0.3251 -1.923   0.0545 .
fiber_tertile_factorT3 (highest) -0.8431    0.4304   0.3370 -2.502   0.0123 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)     0.5351      1.869    0.2830     1.012
fiber_tertile_factorT3 (highest)    0.4304      2.324    0.2223     0.833

Concordance= 0.606  (se = 0.036 )
Likelihood ratio test= 6.85  on 2 df,   p=0.03
Wald test            = 7.15  on 2 df,   p=0.03
Score (logrank) test = 7.49  on 2 df,   p=0.02
cox_pfs_RC <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor,
                   mRCdataFiber)
summary(cox_pfs_RC)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor, 
    data = mRCdataFiber)

  n= 48, number of events= 28 

                                    coef exp(coef) se(coef)      z Pr(>|z|)  
fiber_tertile_factorT2 (middle)  -1.0867    0.3373   0.4679 -2.323   0.0202 *
fiber_tertile_factorT3 (highest) -1.0208    0.3603   0.4666 -2.188   0.0287 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)     0.3373      2.965    0.1348    0.8439
fiber_tertile_factorT3 (highest)    0.3603      2.775    0.1444    0.8992

Concordance= 0.659  (se = 0.05 )
Likelihood ratio test= 6.48  on 2 df,   p=0.04
Wald test            = 7.15  on 2 df,   p=0.03
Score (logrank) test = 7.82  on 2 df,   p=0.02
cox_pfs_RC_IpiNivo <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor,
                           dataRCIpiNivoFiber)
summary(cox_pfs_RC_IpiNivo)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor, 
    data = dataRCIpiNivoFiber)

  n= 15, number of events= 8 

                                    coef exp(coef) se(coef)      z Pr(>|z|)
fiber_tertile_factorT2 (middle)  -0.7914    0.4532   0.9182 -0.862    0.389
fiber_tertile_factorT3 (highest) -0.7831    0.4570   0.8260 -0.948    0.343

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)     0.4532      2.207   0.07494     2.741
fiber_tertile_factorT3 (highest)    0.4570      2.188   0.09054     2.307

Concordance= 0.658  (se = 0.098 )
Likelihood ratio test= 1.04  on 2 df,   p=0.6
Wald test            = 1.13  on 2 df,   p=0.6
Score (logrank) test = 1.19  on 2 df,   p=0.6
cox_pfs_RC_TKI_IO <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor,
                          dataRCioTKIFiber)
summary(cox_pfs_RC_TKI_IO)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor, 
    data = dataRCioTKIFiber)

  n= 24, number of events= 12 

                                    coef exp(coef) se(coef)      z Pr(>|z|)  
fiber_tertile_factorT2 (middle)  -1.2070    0.2991   0.7127 -1.693   0.0904 .
fiber_tertile_factorT3 (highest) -1.1779    0.3079   0.7124 -1.653   0.0983 .
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)     0.2991      3.343   0.07398     1.209
fiber_tertile_factorT3 (highest)    0.3079      3.248   0.07621     1.244

Concordance= 0.637  (se = 0.089 )
Likelihood ratio test= 3.16  on 2 df,   p=0.2
Wald test            = 3.72  on 2 df,   p=0.2
Score (logrank) test = 4.17  on 2 df,   p=0.1
cox_pfs_UC <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor,
                   mUCdataFiber)
summary(cox_pfs_UC)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor, 
    data = mUCdataFiber)

  n= 38, number of events= 27 

                                    coef exp(coef) se(coef)      z Pr(>|z|)
fiber_tertile_factorT2 (middle)   0.2154    1.2404   0.4513  0.477    0.633
fiber_tertile_factorT3 (highest) -0.5447    0.5800   0.4891 -1.114    0.265

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)       1.24     0.8062    0.5122     3.004
fiber_tertile_factorT3 (highest)      0.58     1.7240    0.2224     1.513

Concordance= 0.606  (se = 0.06 )
Likelihood ratio test= 2.47  on 2 df,   p=0.3
Wald test            = 2.32  on 2 df,   p=0.3
Score (logrank) test = 2.41  on 2 df,   p=0.3
cox_pfs_UC_NOTavelumab <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor,
                               dataUC_NOTavelumabFiber)
summary(cox_pfs_UC_NOTavelumab)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor, 
    data = dataUC_NOTavelumabFiber)

  n= 24, number of events= 19 

                                    coef exp(coef) se(coef)      z Pr(>|z|)
fiber_tertile_factorT2 (middle)   0.5038    1.6550   0.5669  0.889    0.374
fiber_tertile_factorT3 (highest) -0.1227    0.8845   0.5620 -0.218    0.827

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)     1.6550     0.6042    0.5448     5.027
fiber_tertile_factorT3 (highest)    0.8845     1.1306    0.2940     2.661

Concordance= 0.6  (se = 0.086 )
Likelihood ratio test= 1.03  on 2 df,   p=0.6
Wald test            = 1.11  on 2 df,   p=0.6
Score (logrank) test = 1.13  on 2 df,   p=0.6
cox_pfs_UC_avelumab <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor,
                            dataUCavelumabFiber)
summary(cox_pfs_UC_avelumab)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor, 
    data = dataUCavelumabFiber)

  n= 14, number of events= 8 

                                    coef exp(coef) se(coef)      z Pr(>|z|)
fiber_tertile_factorT2 (middle)   0.4244    1.5286   0.8708  0.487    0.626
fiber_tertile_factorT3 (highest) -0.7228    0.4854   1.0090 -0.716    0.474

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)     1.5286     0.6542   0.27737     8.424
fiber_tertile_factorT3 (highest)    0.4854     2.0602   0.06718     3.507

Concordance= 0.662  (se = 0.081 )
Likelihood ratio test= 1.89  on 2 df,   p=0.4
Wald test            = 1.74  on 2 df,   p=0.4
Score (logrank) test = 1.89  on 2 df,   p=0.4
forestplot_data <- tibble::tibble(mean  = c(0.4304,0.3603, 0.4570, 0.3079, 0.5800, 0.8845, 0.4854),
                                  lower = c(0.2223, 0.1444, 0.09054, 0.07621, 0.2224, 0.2940, 0.06718),
                                  upper = c(0.833, 0.8992, 2.307, 1.244, 1.513, 2.661, 3.507),
                                  study = c("All","RCC", "RCC ipi-nivo", "RCC TKI-ICB",
                                            "UC", "UC non-maintenance ICB", "UC maintenance ICB"),
                                  n = c("86","48","15","24","38","24","14"),
                                  events = c("55","28","8","12","27","19","8"),
                                  HR = c("0.43","0.36", "0.46", "0.31", "0.58", "0.88", "0.49"))

forestplot_data |>
  forestplot(labeltext = c(study, n, events, HR),
             clip = c(0.09, 2.5),
             xlog = TRUE,
             xlab = "Hazard ratio for PFS (95% CI)",
             xticks = c(0.1, 0.25, 0.5, 1.0, 2.5),
             title = "Univariable HRs for PFS comparing highest vs. lowest tertile of fiber intake",
             txt_gp = fpTxtGp(xlab = grid::gpar(fontsize = 25),
                              ticks = grid::gpar(fontsize = 25))) |>
  fp_set_style(box = "royalblue",
               line = "darkblue",
               summary = "royalblue") |> 
  fp_add_header(study = c("Subgroup"),
                n = c("n"),
                events = c("Events"),
                HR = c("HR"))

Panel G

Multivariate HR for PFS adjusted for age, diagnosis, and performance status.

cox_pfs_all <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor + strata(age_cat) + 
                      ecog_1to5_final + cancer_RCCvsUC_NAME + stage.simplified.factor,
                    gu_cohort_data)
summary(cox_pfs_all)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor + 
    strata(age_cat) + ecog_1to5_final + cancer_RCCvsUC_NAME + 
    stage.simplified.factor, data = gu_cohort_data)

  n= 86, number of events= 55 

                                    coef exp(coef) se(coef)      z Pr(>|z|)  
fiber_tertile_factorT2 (middle)  -0.5635    0.5692   0.3459 -1.629   0.1033  
fiber_tertile_factorT3 (highest) -0.7061    0.4936   0.3464 -2.038   0.0415 *
ecog_1to5_final                   0.3754    1.4556   0.3405  1.102   0.2703  
cancer_RCCvsUC_NAMEUC             0.5439    1.7228   0.3003  1.811   0.0701 .
stage.simplified.factorStage IV   0.5465    1.7272   1.0429  0.524   0.6003  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)     0.5692     1.7568    0.2890    1.1213
fiber_tertile_factorT3 (highest)    0.4936     2.0260    0.2503    0.9733
ecog_1to5_final                     1.4556     0.6870    0.7468    2.8370
cancer_RCCvsUC_NAMEUC               1.7228     0.5805    0.9563    3.1037
stage.simplified.factorStage IV     1.7272     0.5790    0.2237   13.3374

Concordance= 0.673  (se = 0.037 )
Likelihood ratio test= 13.69  on 5 df,   p=0.02
Wald test            = 13.66  on 5 df,   p=0.02
Score (logrank) test = 14.5  on 5 df,   p=0.01
cox_pfs_RC <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor + ageby10 + ecog_1to5_final,
                   mRCdataFiber) #could not adjust for stage because all patients with RCC were stage IV
summary(cox_pfs_RC)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor + 
    ageby10 + ecog_1to5_final, data = mRCdataFiber)

  n= 48, number of events= 28 

                                    coef exp(coef) se(coef)      z Pr(>|z|)   
fiber_tertile_factorT2 (middle)  -1.4607    0.2321   0.5419 -2.695  0.00703 **
fiber_tertile_factorT3 (highest) -0.8362    0.4334   0.5012 -1.669  0.09521 . 
ageby10                           0.6172    1.8538   0.2150  2.871  0.00409 **
ecog_1to5_final                   0.5548    1.7416   0.4812  1.153  0.24890   
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)     0.2321     4.3090   0.08023    0.6713
fiber_tertile_factorT3 (highest)    0.4334     2.3076   0.16228    1.1572
ageby10                             1.8538     0.5394   1.21634    2.8253
ecog_1to5_final                     1.7416     0.5742   0.67822    4.4724

Concordance= 0.735  (se = 0.046 )
Likelihood ratio test= 16.38  on 4 df,   p=0.003
Wald test            = 16.52  on 4 df,   p=0.002
Score (logrank) test = 18.19  on 4 df,   p=0.001
cox_pfs_UC <-coxph(Surv(pfs_mo,pod_status)~ fiber_tertile_factor + strata(age_cat) + ecog_1to5_final + stage.simplified.factor,
                   mUCdataFiber)
summary(cox_pfs_UC)
Call:
coxph(formula = Surv(pfs_mo, pod_status) ~ fiber_tertile_factor + 
    strata(age_cat) + ecog_1to5_final + stage.simplified.factor, 
    data = mUCdataFiber)

  n= 38, number of events= 27 

                                     coef exp(coef) se(coef)      z Pr(>|z|)
fiber_tertile_factorT2 (middle)   0.32429   1.38305  0.51477  0.630    0.529
fiber_tertile_factorT3 (highest) -0.35545   0.70086  0.50416 -0.705    0.481
ecog_1to5_final                   0.03936   1.04014  0.56864  0.069    0.945
stage.simplified.factorStage IV   0.51706   1.67709  1.08210  0.478    0.633

                                 exp(coef) exp(-coef) lower .95 upper .95
fiber_tertile_factorT2 (middle)     1.3830     0.7230    0.5043     3.793
fiber_tertile_factorT3 (highest)    0.7009     1.4268    0.2609     1.883
ecog_1to5_final                     1.0401     0.9614    0.3412     3.170
stage.simplified.factorStage IV     1.6771     0.5963    0.2011    13.984

Concordance= 0.581  (se = 0.067 )
Likelihood ratio test= 2.44  on 4 df,   p=0.7
Wald test            = 2.24  on 4 df,   p=0.7
Score (logrank) test = 2.35  on 4 df,   p=0.7
forestplot_data <- tibble::tibble(mean  = c(0.4936, 0.4334, 0.70086),
                                  lower = c(0.2503, 0.16228, 0.2609),
                                  upper = c(0.9733, 1.1572, 1.883),
                                  study = c("All", "RCC", "UC"),
                                  n = c("86","48","38"),
                                  events = c("55","28","27"),
                                  HR = c("0.49","0.43","0.70"))

forestplot_data |>
  forestplot(labeltext = c(study, n, events, HR),
             clip = c(0.09, 2.5),
             xlog = TRUE,
             xlab = "Hazard ratio for PFS (95% CI)",
             xticks = c(0.1,0.25,0.5,1.0,2.5),
             title = "Multivariable HRs for PFS comparing highest vs. lowest tertile of fiber intake",
             txt_gp = fpTxtGp(xlab = grid::gpar(fontsize = 25),
                              ticks = grid::gpar(fontsize = 25))) |>
  fp_set_style(box = "royalblue",
               line = "darkblue",
               summary = "royalblue") |> 
  fp_add_header(study = c("Subgroup"),
                n = c("n"),
                events = c("Events"),
                HR = c("HR"))