umxGSEM: Fit genomic Structural Equation Models

View source: R/umxGSEM.R

umxGSEMR Documentation

Fit genomic Structural Equation Models

Description

umxGSEM is a wrapper around umxRAM() and OpenMx WLS to fit genomic structural equation models (genomic SEM) using genetic covariance matrices (S) and sampling covariance matrices (V) estimated from LD Score Regression (LDSC).

Usage

umxGSEM(
  model,
  covstruc = NULL,
  S = NULL,
  V = NULL,
  estimation = c("DWLS", "WLS", "ULS"),
  name = "gsem",
  numObs = 1,
  smooth = TRUE,
  autoRun = getOption("umx_auto_run"),
  tryHard = c("yes", "no", "ordinal", "search"),
  std.lv = TRUE,
  ...
)

Arguments

model

A lavaan-style model string (also accepts umx ⁠~=⁠ loadings), or an existing OpenMx::mxModel() / umxRAM() RAM model whose manifestVars name traits in S. For SNP GWAS, use umxGSEM_GWAS() instead of passing SNPs here.

covstruc

LDSC list with genetic covariance S and sampling covariance V (and typically I, N, m) as from GenomicSEM's ldsc / umxGSEM_ldsc() - see e.g. Psych_LDSC. If provided, S and V are extracted from it.

S

Genetic covariance matrix (if covstruc not provided).

V

Sampling covariance matrix (asymptotic covariance of S). If covstruc not provided.

estimation

Method for estimation. One of "DWLS", "WLS", or "ULS" (defaults to "DWLS").

name

The model name (defaults to "gsem").

numObs

Sample size passed to OpenMx for WLS bookkeeping. With LDSC V already on the sampling-covariance scale, the GSEM \chi^2 is r'Wr; use numObs = 1 (default) so OpenMx reports that quantity directly. Larger dummy N rescales the displayed fit without changing point estimates.

smooth

Whether to smooth non-positive definite matrices using Matrix::nearPD() (defaults to TRUE).

autoRun

Whether to run the model (defaults to getOption("umx_auto_run")).

tryHard

Method for fitting the model ("no", "yes", "ordinal", "search"). Defaults to "yes" because DWLS on LDSC V often has multiple local minima.

std.lv

If TRUE (default), free the first factor loading and fix latent variances to 1 (unit-variance identification). Preferred for genetic covariance scale where unit-loading ID often produces Heywood cases. Passed to umxRAM() / lavaan.

...

Additional arguments passed to umxRAM().

Details

Data Triage and Matrix Smoothing

Genomic SEM relies on asymptotic covariance matrices (V) generated by LDSC. These matrices are frequently non-positive definite due to sampling variation or minor missingness across GWAS cohorts. umxGSEM implements an automatic triage system:

  1. Level 1 (Clean): Matrices are strictly positive definite and pass directly to the optimizer.

  2. Level 2 (Smoothed): Negative eigenvalues are detected. The matrices are smoothed using Matrix::nearPD to restore positive definiteness before estimation.

Fiduciary Warning: Models estimated using smoothed matrices are tagged with a gsem_triage attribute. Downstream functions like umxCompare will read this attribute and warn the user that Satorra-Bentler difference tests may report artificial precision.

Engine Integration umxGSEM automatically configures the C++ backend to cache the implied Jacobian matrix. This is a structural requirement for computing Satorra-Bentler (2010) scaled difference tests in umxCompare.

Tutorial files (1k-SNP sumstats, HapMap3 list, EUR LD scores) are fetched with umxGSEM_dl_tutorial_files(). Production HapMap3 / Alkes LD scores / 1000G plink are documented there; this helper does not download them. For a real model prefer Psych_LDSC rather than ldsc on the tutorial SNP list.

OpenMx WLS data (modern only)

Genomic SEM needs precomputed summary matrices S (genetic cov) and V (sampling cov of vech(S)). OpenMx WLS consumes these via the modern mxData interface only:

mxData(numObs = 1, type = "summary",
       observedStats = list(cov = S, useWeight = W, asymCov = V))

with W = diag(1/diag(V)) for DWLS. umxGSEM also reorders V into OpenMx residual order (all variances, then free covariances) and sets dimnames ⁠var_*⁠ / ⁠poly_*_*⁠.

umx hard-refuses forever the removed OpenMx WLS data interface (type = "acov" / "none", MxDataLegacyWLS, top-level ⁠acov=⁠/⁠fullWeight=⁠, or observedStats$acov/⁠$fullWeight⁠ - historical name trap: acov meant useWeight). Use observedStats as above or raw data + type = "DWLS".

Value

An OpenMx::mxModel() object of class MxModelGSEM.

References

Grotzinger, A. D., Rhemtulla, M., de Vlaming, R., Ritchie, G. R., Mallard, T. T., Hill, W. D., ... & Tucker-Drob, E. M. (2019). Genomic structural equation modeling. Nature Human Behaviour, 3, 513-525. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1038/s41562-019-0566-x")}

See Also

Other GSEM: Anthro_LDSC, Psych_LDSC, plot.umx_GWAS(), umxGSEM_GWAS(), umxGSEM_dl_tutorial_files(), umxGSEM_label_ldsc(), umxGSEM_ldsc(), umxGSEM_munge(), umxGSEM_std(), umxGSEM_sumstats(), umxSummary.MxDataStatic(), umxSummary.list()

Examples

## Not run: 
data(Psych_LDSC)
# umx path style (~=) or lavaan (=~); unit-variance ID is the default
m1 = umxGSEM(model = "g ~= SCZ + BIP + MDD + EA + INSOM",
             covstruc = Psych_LDSC, estimation = "DWLS")
umxSummary(m1)

# Explicit lavaan (same model)
m2 = umxGSEM(model = "g =~ NA*SCZ + BIP + MDD + EA + INSOM\ng ~~ 1*g",
             covstruc = Psych_LDSC, estimation = "DWLS")

# Existing umxRAM structure (manifest names must match S)
m0 = umxRAM("tmp", data = mxData(Psych_LDSC$S[1:3, 1:3], type = "cov", numObs = 2),
  type = "cov", autoRun = FALSE, std.lv = TRUE,
  umxPath("g", to = c("SCZ", "BIP", "MDD")),
  umxPath(var = c("SCZ", "BIP", "MDD")),
  umxPath(var = "g", fixedAt = 1)
)
m3 = umxGSEM(m0, covstruc = Psych_LDSC, estimation = "DWLS")

## End(Not run)

umx documentation built on Oct. 11, 2026, 5:07 p.m.