Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Add surv.finegray_coxph Learner (Fine-Gray Competing Risks with CoxPH) #416

Open
5 tasks done
agalecki opened this issue Mar 15, 2025 · 3 comments
Open
5 tasks done
Labels
Learner Status: Request For requesting a new learner

Comments

@agalecki
Copy link

agalecki commented Mar 15, 2025

Algorithm

Fine-Gray Competing Risks Model using survival::coxph() in combination with `survival::finegray()

Package

survival

Supported types

  • surv

I have checked that this is not already implemented in

  • mlr3
  • mlr3learners
  • mlr3extralearners
  • Other core packages (e.g. mlr3proba, mlr3keras)

Why do I think this is a useful learner?

This learner implements a Fine-Gray competing risks model using survival::finegray() and survival::coxph()
It estimates subdistribution hazards for a specified event, supporting observation weights and providing crank, lp, and distr predict types. While mlr3proba includes some survival learners, none currently offer Fine-Gray modeling with CoxPH. The learner is fully implemented and tested in my custom package, leveraging the survival package’s robust functionality.

Further Optional Comments

The learner supports customizable parameters like ties (e.g., "efron", "breslow"), iter.max, and target_event, and handles weights via the task’s weights role. Here’s a brief snippet:

LearnerSurvFineGrayCoxPH <- R6::R6Class("LearnerSurvFineGrayCoxPH",
  inherit = mlr3proba::LearnerSurv,
  public = list(
    initialize = function() {
      ps <- paradox::ps(
        ties = p_fct(default = "efron", levels = c("efron", "breslow", "exact"), tags = "train"),
        target_event = p_uty(default = NULL, tags = "train"),
        # ... other params ...
      )
      super$initialize(
        id = "surv.finegray_coxph",
        param_set = ps,
        predict_types = c("crank", "lp", "distr"),
        properties = "weights",
        packages = "survival"
      )
    }
  )
)
@agalecki agalecki added the Learner Status: Request For requesting a new learner label Mar 15, 2025
@bblodfon
Copy link
Collaborator

bblodfon commented Mar 17, 2025

Hi @agalecki,

Thanks for your request! We have recently actually decided to not include the Fine-Gray model in mlr3proba competing risks update, please see this discuss thread - one of the main reasons is that the cumulative incidence functions (CIFs) you get when you model each cause independently (CIF is one of the main predict_types in the competing risks setting) can be summing to more than 1 which is incorrect (see citation in the thread).

Using the FG model for only a specific competing event only and getting single-event prediction types as you demonstrate in your code is very interesting but I don't think comparison with other survival mlr3 learners will make so much sense then? (it implies that you did some task preprocessing changing the tasks target columns, etc.).

Having said that, if you see that you can map the new mlr3proba (link) LearnerCompRisks and CIF predict_types to the Fine-Gray model (as teh code doesn't check that sum(CIFs) <= 1), you can update your implementation in #417 and I will check it!

@agalecki
Copy link
Author

From the vignette:

"The primary idea of the Fine-Gray approach is to turn the multi-state problem into a collection of two-state ones.
...
An interesting aspect of this is that the fit can be done as a two stage process: the first stage creates a special data set while the second fits a weighted coxph or survfit model to the data"

In the proposed approach, as you pointed out we are getting single-event prediction. More specifically, we designate one event as an event of primary interest. The remaining events are considered to be a nuisance.

In the first stage, we use coxph::finegray to generate a dataset that uses a counting process (long) format with (start, stop] intervals. In the second stage, the standard weighted Cox model is fitted. By doing so, we are dealing with one CIF only and consequently less worried about sum(CIFs) <= 1 requirement.

We effectively are using standard Cox model to emulate a FG submodel for the primary event. Given that, do you still feel that comparison with other mlr3 survival learners would be questionable?

The bottom line is that given sum(CIFs) <= 1 requirement I do not think it is possible to map the proposed learner to the new LearnerCompRisks. Instead, I would like to explore the possibility of including the proposed approach as a survival learner that uses TaskSurv with type="counting" option (currently not available in TaskSurv).

Thank you

@bblodfon
Copy link
Collaborator

Hi,

Even though the FG submodel for the primary event (fitted as you described, procedure from the survival vignette) has predictions for a single-event (distr, lp, etc.) and thus seems comparable with other single-event survival learners in mlr3, I think that practically these shouldn't be compared. FG solves a competing risks problem/task. Other single-event learners solve a single-event problem/task. These are different problems/datasets/tasks. The competing risk learners should predict a CIF per competing event. In the survival vignette, FG is compared with AJ and figures show CIFs a bit later.

I definitely think that FG should be a LearnerCompRisks. Also having sum(CIFs) <= 1 is not a strict requirement in mlr3proba (no checks are done) as I don't think it will affect evaluation measures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Learner Status: Request For requesting a new learner
Projects
None yet
Development

No branches or pull requests

2 participants