Skip to content

fix(nomogram): build survival models on the full cohort (unblocks main deploy) - #429

Merged
ShixiangWang merged 4 commits into
mainfrom
codex/fix-nomogram-survival
Nov 2, 2026
Merged

ShixiangWang merged 4 commits into
mainfrom
codex/fix-nomogram-survival

Conversation

@ShixiangWang

Copy link
Copy Markdown
Member

Summary

main's quarto-publish has been failing since #417 (renv refresh) at Clinics/Nomogram.qmd:

Error in `model.frame.default()`: ! factor stage has new levels Stage IVA
Quitting from Nomogram.qmd:168-185 [fig-2.2BeautifyNomogram]

Root cause: the tutorial's time column used only days_to_death, so every censored patient (Alive, time = NA) was silently dropped by coxph/psm. The single Stage IVA patient is censored, so that level vanished from the fitted model's xlevels; when regplot re-evaluates model.frame against the full LIHC frame, the stricter survival check rejects the unseen level.

Fix: derive analysis time properly — days_to_death for dead patients, days_to_last_follow_up for censored ones — and drop rows without a positive time. This:

  • restores all 259 censored patients to the Cox/AFT fits (previously fit on the 172 dead patients only — a silent statistical defect),
  • keeps every stage level in the model, so regplot renders again,
  • leaves the rendered figures' teaching content unchanged.

Verification

  • All 8 R chunks of the patched Nomogram.qmd executed end-to-end locally (R 4.5.2, survival 3.8.6, regplot master), including the previously failing fig-2.2BeautifyNomogram.
  • Cohort after the fix: 431 patients (259 censored / 172 dead), 1 row without any usable time dropped.

Why this PR first

This same failure aborts the full site render for any PR touching .qmd files, including #426/#428. Merging this first unblocks main's deployments and those PRs.

Main's quarto-publish has been failing since the #417 renv refresh:
regplot's model.frame re-evaluation on Clinics/Nomogram.qmd errored with
"factor stage has new levels Stage IVA" under newer survival releases.

Root cause: the cohort's time column used only days_to_death, so every
censored patient (Alive, time = NA) was silently dropped by
coxph/psm. The single Stage IVA patient is censored, so the level
disappeared from the fitted model's xlevels; when regplot re-evaluates
model.frame against the full LIHC frame, the stricter survival check
rejects the unseen level.

Fix the data preparation instead of the symptom: analysis time is
days_to_death for dead patients and days_to_last_follow_up for censored
patients, then drop rows without a usable positive time. This restores
all 259 censored patients to the Cox/AFT fits (the models were
previously fit on the 172 dead patients only), keeps every stage level
in the model, and makes regplot render again. Verified end-to-end
locally: all 8 chunks of the patched tutorial execute under R 4.5.2 /
survival 3.8.6 / regplot master.
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

✅ QMD Format Check

✅ All 1 checked QMD file(s) pass format validation!

Automated check by the PR Review workflow.
See contribution guidance for the expected tutorial format.
⚠️ The workflow finished with failures; some checks may be incomplete. See the workflow run.

regplot's added.obs() calls model.frame(fit, data=app). Newer survival
(>=3.8.x in renv.lock) evaluates the coxph call in environment(fit$terms)
— set by rms::datadist — where the appended data frame does not exist,
raising "object 'app' not found". Storing the model frame via
model=TRUE lets model.frame.coxph short-circuit on fit$model.
survival 3.8's model.frame.coxph evaluates the rebuilt model.frame call
in environment(fit$terms) whose parent is the global env, so the data
symbol it receives must exist there verbatim. regplot's added.obs() only
creates app inside its own scope, hence 'object app not found'.
Pre-binding app <- rbind(observation, LIHC) in the chunk works around it.
Verified locally with survival 3.8-12 + regplot@3ee4817.
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

✅ QMD Format Check

✅ All 1 checked QMD file(s) pass format validation!

Automated check by the PR Review workflow.
See contribution guidance for the expected tutorial format.

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

📊 Quarto Render Preview

The new or modified Quarto files have been rendered and are available as artifacts.

🔗 View and Download Rendered Files

Click the link above, scroll to the "Artifacts" section at the bottom of the page, and download quarto-rendered-files to preview the rendered HTML files.

Modified files:

Clinics/Nomogram.qmd
Clinics/Nomogram.zh.qmd

@ShixiangWang
ShixiangWang merged commit 08b6484 into main Nov 2, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant