Time-to-event analysis
Example 7: Cox model under linearity and additivity
The Qgcomp.jl module utilizes the Cox proportional hazards models as the underlying model for time-to-event analysis. The interpretation of a qgcomp_glm_noboot fit parameter is a conditional (on confounders) hazard ratio for increasing all exposures at once. The qc.survfit1 object demonstrates a time-to- event analysis with qgcompcox.noboot. The default plot is similar to that of qgcomp_cox_noboot, in that it yields weights and an overall mixture effect
First, let's return to the data example
using RData
tf = tempname() * ".RData"
download("https://github.com/alexpkeil1/qgcomp/raw/refs/heads/main/data/metals.RData", tf)
metals = load(tf)["metals"]
println(metals[1:10,:])
# we save the names of the mixture variables in the variable "Xnm"
Xnm = [
"arsenic","barium","cadmium","calcium","chromium","copper",
"iron","lead","magnesium","manganese","mercury","selenium","silver",
"sodium","zinc"
];
covars = ["nitrate","nitrite","sulfate","ph", "total_alkalinity","total_hardness"];6-element Vector{String}:
"nitrate"
"nitrite"
"sulfate"
"ph"
"total_alkalinity"
"total_hardness"using LSurvival
wu = coxph(@formula(Surv(disease_time, disease_state) ~ iron + lead + arsenic + magnesium + manganese + mercury + selenium + silver + sodium + zinc + mage35), metals);
startvals = vcat(coef(wu)[1:2], 0.0, coef(wu)[3:end])
# fails without some starting values, cadmium is problematic
wu = coxph(@formula(Surv(disease_time, disease_state) ~ iron + lead + cadmium + arsenic + magnesium + manganese + mercury + selenium + silver + sodium + zinc + mage35), metals, start=startvals)
Maximum partial likelihood estimates (alpha=0.05):
StatsBase.CoefTable(Any[[-0.05644671276653607, 0.4407353925827869, 0.023325126788560895, -0.0038124433337263387, 0.09939935237242296, -0.014065071781021773, -0.060830157780859415, -0.23162596645480948, 0.04316903191385716, 0.057927742393580575, 0.05716918032141562, -0.45869629896958647], [0.15617791342324666, 0.20326380825113824, 0.10550162382325406, 0.08889669797227931, 0.06472992839982279, 0.06419746979251749, 0.07291764615104665, 0.17365489664562844, 0.07029060898544912, 0.06388296133764167, 0.04787513490508947, 0.2383701777735209], [-0.36254979825671474, 0.04234564905009974, -0.18345425621551043, -0.17804676970392896, -0.027468976013086358, -0.13988980047295435, -0.20374611807434678, -0.5719833096192672, -0.09459803014901086, -0.06728056105396203, -0.03666435984755632, -0.9258932623940983], [0.2496563727236426, 0.839125136115474, 0.2301045097926322, 0.17042188303647626, 0.2262676807579323, 0.11175965691091079, 0.08208580251262797, 0.10873137670964833, 0.18093609397672517, 0.1831360458411232, 0.15100272049038757, 0.008500664454925422], [-0.3614257069343976, 2.1682925080211315, 0.22108784626516528, -0.042886219856165794, 1.535601148180709, -0.21909074962734937, -0.8342309576868625, -1.3338291688225792, 0.6141507740072873, 0.9067792284614692, 1.1941309499127517, -1.9243023739546845], [0.7177812336016852, 0.030136438103240293, 0.8250240333944815, 0.9657922336063082, 0.12463623242333455, 0.8265793564618922, 0.404150849305446, 0.1822598491784364, 0.5391156988881018, 0.364523556309727, 0.23242674819194198, 0.0543166932009459]], ["ln(HR)", "StdErr", "LCI", "UCI", "Z", "P(>|Z|)"], ["iron", "lead", "cadmium", "arsenic", "magnesium", "manganese", "mercury", "selenium", "silver", "sodium", "zinc", "mage35"], 6, 5)
Partial log-likelihood (null): -1186.13
Partial log-likelihood (fitted): -1186.11
LRT p-value (χ²=0.05, df=12): 1
Newton-Raphson iterations: 2
using Qgcomp
qc_survfit1 = qgcomp_cox_noboot(@formula(Surv(disease_time, disease_state) ~ iron + lead + cadmium + arsenic + magnesium + manganese + mercury + selenium + silver + sodium + zinc + mage35), metals, Xnm, 4)
qc_survfit1Scaled effect size (negative direction)
7×4 DataFrame
Row │ exposure coef weight ψ_partial
│ String Float64 Float64 Float64
─────┼────────────────────────────────────────────────
1 │ iron -0.000663209 0.00210784 -0.314639
2 │ cadmium -0.0091144 0.0289678 -0.314639
3 │ lead -0.0236289 0.0750983 -0.314639
4 │ mercury -0.0407258 0.129437 -0.314639
5 │ arsenic -0.0438804 0.139463 -0.314639
6 │ manganese -0.0600305 0.190792 -0.314639
7 │ selenium -0.136596 0.434135 -0.314639
Scaled effect size (positive direction)
4×4 DataFrame
Row │ exposure coef weight ψ_partial
│ String Float64 Float64 Float64
─────┼───────────────────────────────────────────
1 │ silver 0.02682 0.180446 0.148632
2 │ magnesium 0.0335549 0.225758 0.148632
3 │ sodium 0.0390298 0.262594 0.148632
4 │ zinc 0.0492273 0.331203 0.148632
StatsBase.CoefTable(Any[Any[-0.16600717356076572, -0.3641833198739394], Any[0.21369721534717157, 0.2314041878192279], Any[-0.7768335834000981, -1.5737974463903743], Any[0.43725696020305493, 0.11553428461927058], Any[-0.5848460192377228, -0.8177271938713692], Any[0.2528316721161914, 0.08936055412349031]], ["Coef.", "Std. Error", "z", "Pr(>|z|)", "Lower 95%", "Upper 95%"], Any["mixture", "mage35"], 4, 3)
using Plots
weightplot(qc_survfit1)