Internals
These types are not exported, but are documented here for contributors and for users who want to work with expand_geno's return value directly.
Dynema.ExpandedGeno — Type
ExpandedGenoStores genotype data at the sample level. Allows storage of SNP names and single-cell ids.
Arguments
mat::AbstractMatrix: donor × SNP genotype matrix (e.g.,Matrix{Float64}orSparseMatrixCSC).rows::AbstractVector: mapping from single-cell to donor rows.rownames::Union{Nothing,String,AbstractVector}=nothing: optional cell idscolnames::Union{Nothing,String,AbstractVector}=nothing: optional SNP names.
Dynema.ExpandedGenoView — Type
ExpandedGenoView(mat::AbstractMatrix, rows::AbstractVector,
cols::AbstractVector;
rownames=nothing, colnames=nothing)A lazy view of an ExpandedGeno, representing a submatrix without copying data.
Arguments
mat::AbstractMatrix: underlying donor × SNP matrix.rows::AbstractVector: row indices of the view.cols::AbstractVector: column indices of the view.rownames::Union{Nothing,AbstractVector}=nothing: optional subset of row names.colnames::Union{Nothing,AbstractVector}=nothing: optional subset of column names.
Indexing
- 2D indexing only:
V[i, j],V[i, :],V[:, j],V[I, J]. - Materializes single rows or single columns only.
- Supports
names(view, 1)andnames(view, 2).
Examples
# Create a lazy submatrix
view = E[1:100, 5:10] # returns ExpandedGenoView
# Materialize a single row from the view
row = view[1, :] # Vector{Float64}
# Materialize a single column from the view
col = view[:, 1] # Vector{Float64}
# Access row and column names from the view
rnames = names(view, 1)
cnames = names(view, 2)The CRVE score test itself, and the per-context 1-df decomposition reported by multi-context interaction tests (the p_<context> columns; see map_locus's percontext keyword):
Dynema.smallsample_factors — Function
smallsample_factors(small, G, nobs) -> (clusteradj, smallsample, dof_r)Small-sample factors of the cluster-robust score test, replicating WildBootTests.jl's ML (score) mode with one-way clustering and small = true (init.jl: clusteradj = small, smallsample = _dof / (Nobs - robust), dof_r = G - 1), which is how Dynema invokes it:
clusteradj = G / (G - 1)multiplies the cluster-robust denominator (the "meat"), whereGis the number of clusters (donors);smallsample = nobs / (nobs - 1)rescales the statistic (its square root for 1 df). WildBootTests derives_dof = nobs - k, but in ML mode Dynema supplies nopredexog, so itskis 0. For single-cell data (nobs= number of cells) the factor is essentially 1; it is kept so the direct implementation reproduces the library to numerical precision;dof_r = G - 1is the residual degrees of freedom of the reference t (1 df) or F (qdf) distribution.
With small = false all three are neutral: (1, 1, 0), and the reference distributions are N(0,1) (1 df) and χ² (q df).
Dynema.crvetest_direct — Function
crvetest_direct(R, A, Sg, clustshare; small = false, nobs = 0)Direct implementation of the analytical CRVE score test for the shared-null fast path, replicating WildBootTests.scoretest's ml-mode statistic (reps = 0, imposenull = true, scorebs = true, one-way clustering) without the library's per-call setup:
numer = (A R')' S, withSthe total score sum;- cluster-level
K = Sg * (A R'), recentered by each cluster's share of observations, sodenom = K'Kis the CRVE meat transformed byA R'; small = false(default): q = 1:z = numer / sqrt(denom),p = ccdf(Chisq(1), z²)(two-tailed); q > 1:χ² = numer' denom⁻¹ numer,p = ccdf(Chisq(q), χ²);small = true: with(cm, ss, dof_r) = smallsample_factors(true, G, nobs)(G = size(Sg, 1)clusters), the denominator becomescm * denom, q = 1:t = sqrt(ss) * numer / sqrt(cm * denom),p = 2 * ccdf(TDist(G - 1), |t|); q > 1:F = (ss / q) * numer' (cm * denom)⁻¹ numer,p = ccdf(FDist(q, G - 1), F).
Sg is the G × k matrix of per-cluster score sums; clustshare[g] is cluster g's share of observations; nobs (number of observations/cells) is required when small = true.
Returns (stat, p, stattype, beta, se, dof_r) in the same shape crvetest results are consumed (plus pk for q > 1). beta = numer is the one-step (score-based) estimate of each tested coefficient from the null fit and se = sqrt(cm * diag(denom) / ss) its cluster-robust standard error, so that beta ./ se reproduces the reported z/t statistic of each tested term (for q = 1, exactly stat). stattype is "z"/"t" for q = 1 and "χ²"/"F" for q > 1.
Dynema.crve_percomponent — Function
crve_percomponent(R, A, Sg, clustshare; small = false, nobs = 0) -> Vector{Float64}
crve_percomponent(R, A; scores, clustid, small = false) -> Vector{Float64}Per-component 1-df CRVE score p-values for each tested row of R, computed from the same restricted (null) fit as the joint test: with numer and denom = K'K exactly as in crvetest_direct, and se_k = sqrt(cm * denom[k,k] / ss) (factors from smallsample_factors; both 1 when small = false),
p_k = 2 * ccdf(Normal(), |numer[k] / se_k|) (small = false)
p_k = 2 * ccdf(TDist(G - 1), |numer[k] / se_k|) (small = true)These are tests of each coefficient under the joint null (all tested coefficients zero) – exact size under that null, but under partial alternatives with correlated contexts, a true effect in one context can project onto another's score. They decompose the joint statistic; the joint test remains the primary inference.
The keyword method builds per-cluster score sums from row-level scores and one-way integer cluster ids (used by the generic, non-workspace path).
The cluster-robust standard errors of the unrestricted coefficients (the se_wald_<term> columns that accompany the effect-size estimates; see map_locus's betas keyword). These are Wald-type SEs at the unrestricted fit, distinct from the null-fit score test above:
Dynema.crve_se — Function
crve_se(X, y, β, groups; small = false) -> Vector{Float64}One-way cluster-robust (CRVE) standard errors of the unrestricted Poisson/log-link coefficients β (the se_wald_<term> output columns, reported alongside the unrestricted estimates selected with betas).
Sandwich estimator V = (cm / ss) A (Σ_g s_g s_g') A, where
A = (X'diag(μ̂)X)⁻¹is the model-based bread,s_gis the sum of the scores(y - μ̂) .* Xover the cells of cluster (donor)g,- everything is evaluated at the unrestricted fit
μ̂ = exp.(Xβ), cm = ss = 1whensmall = false; withsmall = truethey are the same small-sample factors as the score test (smallsample_factors:cm = G/(G-1),ss = nobs/(nobs-1)), so that SEs are on the same footing as the reported t statistics.
The SE of coefficient j is sqrt(V[j, j]), on the same (natural-log) scale as β[j]. β[j] / se[j] is therefore a Wald z-statistic (small = false) or a Wald t-statistic on G - 1 degrees of freedom (small = true).
These SEs are not the quantities behind Dynema's p-values. The z/t and p columns come from a score test at the restricted (null) fit, with recentered scores (see crvetest_direct); this SE comes from the unrestricted fit, so |β| / se will generally differ from |z| (they agree asymptotically, and closely for small effects). With small = false no small-sample correction is applied, matching the score test, so SEs are optimistic with few donors. The score-test p (or p_boot) remains the primary inference; use se_wald_<term> for effect-size uncertainty and meta-analysis.
Returns NaNs under multiway clustering (size(groups, 2) != 1), which is not implemented here.
Dynema.DynemaModel, the struct returned by map_locus, is intentionally accessed only through its get_*/set_* accessors (see the API Reference) rather than by touching its fields directly, so that the internal layout can change without breaking user code.