Skip to contents

Fits the elastic net on the RSS objective – the lasso penalty mixed with a ridge term, as glmnet mixes them – searching over a shrinkage grid s and a lambda path. Model selection uses held-out summary statistics by default (see lassosumRssWeights).

Usage

enetRssWeights(
  stat,
  ldReference,
  alpha = 0.5,
  s = c(0.2, 0.5, 0.9, 1),
  selection = c("heldOut", "ldQuadratic", "minFbeta"),
  fitRetention = c("none", "slim", "full"),
  methodArgs = PenalizedRssOptions()
)

Arguments

stat

A list of summary statistics: n (per-variant sample sizes) and the marginal effects as cor (standardized), z, b with seb, or b alone, taken as already standardized. The engine receives the standardized effects z / sqrt(n), with n the median of n.

ldReference

The LD reference the statistics' variants are matched to by stat$variantNames: a genotype panel (see readGenotypes), a GenotypeMixture or an LdMatrix. A genotype reference's LD is used through its standardized genotypes, never formed as a matrix.

alpha

Elastic-net mixing in [0, 1]: the L1 share of the penalty. Default 0.5.

s

Numeric vector of LD shrinkage parameters. Default: c(0.2, 0.5, 0.9, 1.0).

selection

How the returned candidate is chosen (see Details of lassosumRssWeights). "heldOut" (default) scores every candidate on held-out summary statistics and needs the reference's sample size, so an LdMatrix must record nSamples. "ldQuadratic" is lassosum's pseudovalidation and needs the fdrtool package. "minFbeta" picks the smallest objective, for debugging.

fitRetention

How much of the search is kept as the "fit" attribute of the returned weights. "none" (default) attaches nothing. "slim" keeps path, a table with one row per candidate (s, lambda) giving the solver's objective fbeta, loss, convergence flag conv and number of non-zero coefficients nparams, with selected marking the candidate returned. "full" also keeps beta, the candidates' coefficients (variants x candidates, in the rows' order).

methodArgs

Options forwarded to the solver, penalizedRss, built with PenalizedRssOptions. A bare list is refused: it cannot be checked against the engine, so a misspelled option would be silently ignored.

Value

A numeric vector of SNP coefficient weights. Unless fitRetention = "none", the search is attached as attribute "fit".

Details

alpha is the L1 share of the penalty: with \(l_1 = \lambda \alpha\) and \(l_2 = \lambda (1 - \alpha)\) the penalty is \(2 l_1 \|\beta\|_1 + l_2 \beta^T \beta\), so alpha = 1 is the lasso and alpha = 0 ridge (ridgeRssWeights). The default lambda path is divided by max(alpha, 0.001), as glmnet sizes its own, so the L1 share spans the same range at any alpha.

The LD shrinkage adds a ridge term of its own, since \(\beta^T R_s \beta = (1 - s) \beta^T R \beta + s \beta^T \beta\): every RSS lasso is already partly a ridge, and alpha adds a second ridge term that grows with \(\lambda\). Expect the lasso and the elastic net to differ less on summary statistics than glmnet's do on genotypes.

Examples

data(eqtlRegionExample)
X <- eqtlRegionExample$X[, 1:30]
y <- eqtlRegionExample$yRes
ss <- lapply(
  seq_len(ncol(X)), function(j) coef(summary(lm(y ~ X[, j])))[2, 1:2])
stat <- list(
  b = vapply(ss, `[`, numeric(1), 1L),
  seb = vapply(ss, `[`, numeric(1), 2L),
  n = rep(nrow(X), ncol(X)),
  variantNames = colnames(X)
)
enetRssWeights(stat, LdMatrix(cor(X), nSamples = nrow(X)))
#>  [1] -0.002058524 -0.001879849  0.000000000  0.000000000  0.000000000
#>  [6]  0.000000000  0.000000000  0.000000000  0.000000000  0.000000000
#> [11]  0.000000000  0.000000000  0.000000000  0.000000000  0.000000000
#> [16]  0.000000000  0.000000000  0.000000000  0.000000000  0.000000000
#> [21]  0.000000000  0.000000000  0.000000000  0.000000000  0.000000000
#> [26]  0.000000000 -0.013245825  0.000000000  0.000000000  0.000000000
#> attr(,"penalized_rss_selection")
#>                mode               index             penalty               alpha 
#>           "heldOut"                "19"             "lasso"               "0.5" 
#>                   s              lambda 
#>               "0.2" "0.139038559235512" 
# A larger ridge share:
enetRssWeights(stat, LdMatrix(cor(X), nSamples = nrow(X)), alpha = 0.2)
#>  [1] -0.061077196 -0.061195694  0.009576417  0.000000000  0.000000000
#>  [6] -0.020096568  0.000000000  0.030475781  0.014036772  0.014388095
#> [11] -0.010724064 -0.063247431 -0.026604383  0.013768442 -0.010681996
#> [16]  0.030397575 -0.002185448  0.000000000  0.028643612  0.000000000
#> [21]  0.000000000 -0.020331176  0.000000000 -0.012882048 -0.026839489
#> [26] -0.020270889 -0.081349760  0.000000000  0.061121129  0.005942112
#> attr(,"penalized_rss_selection")
#>                 mode                index              penalty 
#>            "heldOut"                 "11"              "lasso" 
#>                alpha                    s               lambda 
#>                "0.2"                "0.2" "0.0189634509536613"