R/ancestry_smmat.R
ancestry_smmat.RdWraps GMMAT::SMMAT() across all ancestry-split GDS files (as
produced by write_ancestry_gds), computes per-gene
ancestry weights from Step 1's ancestry_counts (this replaces the
retired src/step3_weight_finding.R script), and combines the per-gene p-values
across populations with cauchy_combine. This is the
package's Step 3 entry point; it does not run Step 1/2 for you (SMMAT
runs can take hours, so this is always an explicit, separate call).
Named list/vector of GDS file paths, one per ancestry
population, e.g. c(AFR = "afr.gds", EUR = "eur.gds") – as
returned by write_ancestry_gds. Any K >= 1 populations
are supported; add an extra named entry (e.g. OBSERVED = ...)
to include an additional (e.g. non-ancestry-split) GDS in the same
SMMAT + Cauchy combination run.
data.frame with an id_col column plus the response
and covariates referenced in formula.
Model formula for the null model, e.g. y ~ age + sex.
Numeric matrix (or object coercible via as.matrix)
with row/column names equal to sample IDs.
Either a path to the gene_group file passed to
GMMAT::SMMAT() (no header; columns gene, chr, pos, ref, alt,
weight), or a data.frame/matrix with those same six columns. Either way,
it is read, has any leading "chr" stripped from the chr column
(matching SeqArray::seqVCF2GDS()'s convention – see the "chr
column" note below), and written to a fresh temporary file that is
deleted with unlink() when ancestry_smmat() returns; the
caller's own path/data.frame is never read-modified or deleted, and can
safely be reused across repeated calls (e.g. one call per phenotype).
chr column: pass either "19" or "chr19" –
normalized automatically. Without this, a mismatch between the group
file's chr convention and the GDS's (always bare, no "chr"
prefix) would silently drop every affected variant, and the whole gene
if all its variants are affected, since GMMAT::SMMAT() matches
variants by exact chr:pos:ref:alt string equality with no
fuzzy/positional alignment.
Optional: pass
ancestry_split()$ancestry_counts / $variant_info
straight through to compute per-gene ancestry weights for the Cauchy
combination. If omitted, equal weights are used.
Name of the sample ID column in pheno and
formula's id argument to glmmkin (default "id").
A family object for GMMAT::glmmkin() (default
gaussian()).
Name of the gene/group ID column in SMMAT()'s
output (default "group", matching GMMAT::SMMAT()).
Name of the p-value column in SMMAT()'s output to
combine (default "E.pval", matching GMMAT::SMMAT()'s
default tests = "E"; use "O.pval"/"S.pval"/
"B.pval" if you pass a different tests via ...).
Passed straight through to
GMMAT::SMMAT() – same names, same meaning as in a direct
SMMAT() call.
Print this function's own step-by-step progress messages
(Steps 1-6 below). Distinct from GMMAT::SMMAT()'s own internal
verbose (its per-call progress bar), which is not exposed
separately and stays at SMMAT's default (FALSE); every other
SMMAT() argument is available via ....
Any other GMMAT::SMMAT() argument, forwarded as-is –
for example tests ("B", "S", "O", or the
default "E"), rho, MAF.weights.beta,
missing.method, use.minor.allele, auto.flip,
Garbage.Collection, group.file.sep, or
meta.file.prefix. null.obj, geno.file,
group.file, and is.dosage are always supplied internally
by ancestry_smmat() and cannot be overridden this way. See
?GMMAT::SMMAT for the full list and defaults.
A list with two elements:
data.frame with one row per gene: gene, one
p_<POP> column per population, one w_<POP> weight
column per population (only if ancestry_counts/
variant_info were supplied), and p_cauchy.
Named list (one entry per population, same names
as gds_paths) of the raw GMMAT::SMMAT() result
data.frames.
if (requireNamespace("GMMAT", quietly = TRUE) &&
requireNamespace("SeqVarTools", quietly = TRUE)) {
ext <- system.file("extdata", package = "lantern")
split <- ancestry_split(file.path(ext, "toy.vcf.gz"),
file.path(ext, "toy.msp.tsv"),
mode = "dosage", chrom = "chr19", verbose = FALSE)
out_dir <- tempfile()
gds <- write_ancestry_gds(split, out_dir, verbose = FALSE)
pheno <- read.delim(file.path(ext, "toy_pheno.tsv"))
kinship <- diag(nrow(pheno)) # unrelated samples
dimnames(kinship) <- list(pheno$id, pheno$id)
# gene_group_file: a path, or a data.frame with the same six columns
out <- ancestry_smmat(gds, pheno, y ~ age + sex, kinship,
file.path(ext, "toy_genes.tsv"),
ancestry_counts = split$ancestry_counts,
variant_info = split$variant_info,
verbose = FALSE)
out$results # per-gene p-values + Cauchy combination
head(out$smmat_results$AFR) # raw GMMAT::SMMAT() output for AFR
unlink(out_dir, recursive = TRUE)
}