Applies a single QC pass to a QtlSumStats or GwasSumStats
collection: per-row sanity checks via .applySanityChecks (drop rows
with out-of-range / zero P, BETA == 0, SE <= 0, NA in vital columns; clamp
tiny P; normalize CHR; coerce signed columns to numeric), variant-content
filters (MAF / INFO / N) via .applyContentFilters, optional
skipRegion drop, optional PIP screen, panel-vs-sumstats allele
harmonization against the ldReference via harmonizeAlleles
(which handles indels, strand-ambiguous variants, sign / strand flips, and
duplicate drops in a single sweep), optional SLALOM/DENTIST LD-mismatch QC,
and optional RAISS imputation. No Bioconductor genome / dbSNP packages
required.
Usage
summaryStatsQc(
sumstats,
sumstatsFilterParam = SumstatsFilterParam(),
panelFilterParam = PanelFilterParam(),
keepVariants = NULL,
skipRegion = NULL,
signalScreenParam = SignalScreenParam(),
ldMismatchQcMethod = c("none", "slalom", "dentist"),
alleleFlipKriging = FALSE,
effectiveN = TRUE,
impute = FALSE,
raissParam = RaissParam(),
matchMinProp = 0,
sumstatsCleaningParam = SumstatsCleaningParam()
)Arguments
- sumstats
A
QtlSumStatsorGwasSumStatscollection.- sumstatsFilterParam
Row filters applied to the summary statistics themselves, built with
SumstatsFilterParam:removeIndelsdrops indels during panel harmonization,removeStrandAmbiguousdrops A/T and C/G variants,infoCutoffis an INFO-score floor (requiring anINFOcolumn when non-zero), andnCutoffdrops variants whoseNis more than that many median-absolute-deviations from the median (0 disables it).- panelFilterParam
LD-reference-panel filters, built with
PanelFilterParam.macCutoffis converted to a MAF equivalent usingmacCutoff / (2 * nSamples)and the stricter of it andmafCutoffapplies;nSamplescounts the panel's real samples, which for a stochastic LD sketch are those its.afreqrecords rather than its pseudo-samples.imissCutoffis a per-variant missingness ceiling. See the panel-filters section below.mafCutoffis the one setting that reaches past the panel: it is measured wherever it can be, against the summary statistics' ownAF/MAF/FRQcolumn when one is present and against the panel. It has always been a single knob, so it lives here rather than being split into two that could disagree.- keepVariants
Optional character vector of variant IDs (SNP column) to retain prior to harmonization.
- skipRegion
Optional character vector of
"chr:start-end"strings, or aGRanges, of regions to drop.- signalScreenParam
Whether to skip an entry before fitting it, built with
SignalScreenParam— the same bundlefineMappingPipelineandcolocboostPipelinetake.pipruns an LD-independent single-effect SER screen and skips the entry if no PIP exceeds the cutoff (< 0resolves to3 / nVariants);absZskips whenmax(abs(Z))does not exceed the cutoff, with no model fit;bfandlogBfscreen the largest per-variant single-effect Bayes factor from that samesusie_serfit, on the raw and log scales respectively. One metric at a time — the constructor rejects a conflicting pair. Unset (the default) screens nothing.- ldMismatchQcMethod
Which LD-mismatch check to run:
"none"(default),"slalom"or"dentist", or the matching constructor –SlalomParam/DentistParam– to configure it at the same time. Exactly one engine is selected either way, since the constructor carries the choice.- alleleFlipKriging
Logical (length 1). Opt-in kriging LD-consistency prefilter run before SLALOM/DENTIST. Default
FALSE.- effectiveN
Logical (length 1). When
TRUE(default) and the input carries case/control counts — per-variantN_CASE/N_CONTROLmcols, else the study-levelnCase/nControlscalars — the working per-variantNis set to the effective sample sizeeffectiveN(nCase, nControl)BEFORE the N-cutoff filter, so the filter, kriging, and the downstream fit all useN_eff. When both counts and anNcolumn are present the counts win:Nis overridden and the override is logged. Inputs with no counts (quantitative traits) are unchanged. The escape hatcheffectiveN = FALSErestores the rawNcolumn (or, when there is noN, the raw totalnCase + nControl) with no override.qcInfo$options$effectiveNrecords the setting and each entry'snSourceis one of"effective","column","total", orNA.- impute
Logical (length 1). Run RAISS imputation against the
ldReference's genotype panel as the last QC step, adding z-scores for panel variants the input lacks (seeraissParam). The audit records how many variants were imputed. DefaultFALSE.- raissParam
RAISS settings, built with
RaissParam. A bare list is refused, since it cannot be checked.RAISS imputation scopes its reference panel to the analysis-region window (so a per-chromosome / genome-wide
ldReferencedoes not materialize its full dosage);flankwidens that window by the given number of base pairs on each side to retain LD context for edge variants.mafCutoff,macCutoffandimissCutoffbound which panel variants RAISS will attempt to impute. Without them every rare variant in the window of a large LD sketch becomes an imputation target, which is slow and of little value when the study is far smaller than the panel. The stricter ofmafCutoffandmacCutoff / (2 * nSamples)applies, matchingQtlDataset.These are a further tightening applied to imputation targets only, on top of the panel filter the top-level cutoffs already applied: the panel handed to RAISS holds nothing below those. Use them to impute only common variants from a panel deliberately kept wider than that — e.g.
mafCutoff = 0.001withraissParam = RaissParam(mafCutoff = 0.01). A variant present in the sumstats is never dropped here: RAISS derives its LD basis from those same panel rows.lamb,svdTol,r2ThresholdandminimumLdare forwarded toraissitself.- matchMinProp
Minimum proportion of LD panel variants that must be matched by the sumstats; default 0.
- sumstatsCleaningParam
What makes a row a well-formed record, built with
SumstatsCleaningParam:coerceNumeric,normalizeChr/dropNonstandardChr,dropMissData,dropPOutOfRange,clampSmallP/smallPFloor,dropZeroEffectanddropNonpositiveSe. Applied before any filter or screen. Distinct fromsumstatsFilterParam, which applies quality thresholds to rows that are already well formed.
Details
The returned collection has its qcInfo slot populated with a per-entry
audit record (variant counts, drop counts at each step, which filters fired,
etc.). Fine-mapping and TWAS-weights pipelines reject SumStats inputs where
length(qcInfo(x)) == 0L.
Column-availability error contract: a non-zero infoCutoff requires
every entry to carry an INFO column, and a non-zero nCutoff
requires N; a missing column with a non-zero cutoff is a hard error.
mafCutoff is exempt — a study with no frequency column is still
filtered against the reference panel (see below).
Panel filters
mafCutoff / macCutoff /
imissCutoff are measured against the LD reference panel,
the same way fineMappingPipeline and
twasWeightsPipeline measure them on the RSS path, so one
number means the same thing wherever it is set. MAC is converted to a MAF
equivalent and the stricter of the two applies, matching
QtlDataset. Defaults (0, 0, 1) filter
nothing.
The panel is filtered once, before any entry is harmonized, so a variant the panel cannot support is absent from the LD used by kriging, SLALOM/DENTIST and RAISS, and is never an imputation target. Because harmonization drops summary-statistic variants the panel does not cover, this also discards observed variants — the intended behaviour: a variant whose LD cannot be estimated is not usable downstream.
mafCutoff additionally filters the summary statistics' own
AF / MAF / FRQ column when one is present, so a
variant common in the panel but rare in the study is dropped as well.
Examples
data(gwasSumStatsS4Example)
summaryStatsQc(gwasSumStatsS4Example)
#> [trait1] QC track: harmonization kept 200 of 200 variant(s) (corrected: sign-flipped 0, strand-flipped 0; dropped 0).
#> [trait1] QC summary: 200 in -> 200 out | corrected: sign-flip 0, strand-flip 0
#> GwasSumStats: 1 studies, genome build hg19
#> LD reference: plink1 @ pecotmr://extdata/toy_canonical