Skip to content

replacing vip::vi() call with internal functionality - #31

Merged
eboyer221 merged 2 commits into
mainfrom
vip-replace
Aug 12, 2026
Merged

replacing vip::vi() call with internal functionality#31
eboyer221 merged 2 commits into
mainfrom
vip-replace

Conversation

@amcim

@amcim amcim commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

The vip package was removed from CRAN and that is problematic for Bioconductor submission. We made the decision to replace the use of the package with our own functionality.

The relevant call to vip was vip::vi() in extractTopFeats(), which returns the features a model found most important for predicting AMR phenotype. Its output is what gets written to the *_top_features.tsv files and plotted by plotTopFeatsVI(). As such, this was replaced with with an internal .viGlmnet().

That call goes through a few functions in vip:

  • vi(): wrapper; computes importance, drops NAs, sorts by decreasing importance
  • vi_model(): S3 generic that picks the extraction method for the model type
  • vi_model.model_fit(): unwraps the parsnip fit to the underlying engine object
  • vi_model.glmnet(): pulls the coefficients out of the glmnet fit and returns them as Variable, Importance (absolute coefficient), and Sign (POS/NEG)

This implemntation takes the fitted glmnet engine, drops the intercept, and returns a tibble of Variable, Importance (|coefficient|), and Sign, sorted by decreasing importance.

I also added some tests which check that .viGlmnet() returns what vip::vi() did(the three columns, sorted by decreasing importance, with Importance equal to the absolute coefficient at the minimum lambda), and that multi-class fits return per-class columns instead of erroring.

One thing about this approach is that this currently only works for glmnet, which is the only engine we use currently. If we want to add more models later we will need to expand this functionality.

@eboyer221 eboyer221 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving - verified .viGlmnet() against vip's actual source and the math checked out.

@eboyer221
eboyer221 merged commit 08014e7 into main Aug 12, 2026

@jananiravi jananiravi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @eboyer221, could you check these out -- I was going to post these from earlier this afternoon, but it got merged in the meantime.

  1. workflowsets and extract...parsnip calls: These two @importFrom workflowsets lines are now likely orphaned — nothing calls extract_fit_parsnip or extract_spec_parsnip after vip::vi() was removed. Will produce R CMD check NOTEs; safe to delete.
  2. min(glmnet_fit$lambda): This does not use the tuned penalty. The old vip::vi() used the penalty selected by cross-validation (fit$fit$fit$spec$args$penalty). The multi-class branch does use the tuned penalty, so the two paths are inconsistent. Intentional? (@AbhirupaGhosh)
  3. Sign = ifelse(coefs > 0, "POS", "NEG"): Zero coefficients (common with LASSO/elastic net) get labeled "NEG". Suggest ifelse(coefs > 0, "POS", ifelse(coefs < 0, "NEG", NA_character_)) to avoid mislabeling features that were zeroed out. @AbhirupaGhosh may also be important for feature filtering in your other PR.
  4. filter(cum_imp < cum_vi_upper ...): Check strict upper inequality; excludes the last feature when prop_vi_top_feats = c(0, 1) (the default), because the final cumsum equals the total. Change < to <= so the full range is inclusive on the right. (if correct, this is a good catch by C!)

@eboyer221

eboyer221 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Thank you for flagging those issues, @jananiravi.
I have opened another PR to address them: #40
@AbhirupaGhosh and I are reviewing your second question together to reach a conclusion about how to resolve that discrepancy with the tuned penalty.

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.

3 participants