Add OTTERS pipeline, check_ld(), and fix pval_acat()#462
Merged
Conversation
Add check_ld(R, method) with three modes: - "check": diagnostic only (eigenvalues, PD status, condition number) - "shrink": (1-s)*R + s*I regularization - "eigenfix": set negative eigenvalues to 0, reconstruct (susieR approach) Integrate into otters_weights() via check_ld_method parameter (default "eigenfix"), matching OTTERS which forces PD via SVD before PRS-CS. The check runs once at the top and the repaired LD is used for all methods. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implement the OTTERS framework (Zhang et al. 2024) for omnibus TWAS, plus LD quality checking and a bug fix in
pval_acat().New functions
otters_weights(sumstats, LD, n, methods, p_thresholds, check_ld_method)— Stage I: train eQTL weights via P+T + any*_weights()learner. Defaults match original OTTERS exactly (phi=1e-4, thin=1, lambda from 1e-4, s grid search). Extensible viado.calldispatch.otters_association(weights, gwas_z, LD, combine_method)— Stage II: per-method TWAS z-scores + ACAT/HMP combination. Includes dimension validation.check_ld(R, method, r_tol, shrinkage)— LD matrix QC with three modes:"check"(diagnostic),"shrink"(regularization),"eigenfix"(set negative eigenvalues to 0). Integrated intootters_weights()by default.lassosum_rss_weights()now searches overs = c(0.2, 0.5, 0.9, 1.0)grid (was fixed s=0.9).lassosum_rss()lambda range extended to 1e-4 (was 1e-3), matching OTTERS.Bug fix
pval_acat()had a sign error:qcauchy(p) = tan(π(p-0.5))but ACAT needsT = mean(tan(π(0.5-p))). Combined p-values were near 1.0 instead of near 0.Audit results
All 17 OTTERS default parameters verified matching. Systematic comparison of every formula, default, and edge case against the original Python/R pipeline. Key fixes: PRS-CS phi, SDPR thin, lassosum lambda/s, cor>=1 safeguard, P+T weight clamping.
Validation
Test plan
otters_weights(),otters_association(),check_ld()devtools::test(filter="otters")anddevtools::test(filter="ld")R CMD check🤖 Generated with Claude Code