Identifies outliers in GWAS training data using statistical (Cook's distance) and/or biological (implausible MAF-effect combinations) criteria. This function helps identify potentially problematic data points that may unduly influence the B estimation model.

detect_B_outliers(
  MAF,
  values,
  method = "both",
  cook_threshold = 4,
  biological_rules = NULL,
  verbose = 1
)

Arguments

MAF

Numeric vector of minor allele frequencies (0 < MAF <= 0.5)

values

Numeric vector of effect measures (BETA or h-squared values)

method

Character string specifying detection method: "statistical" (Cook's distance only), "biological" (biological rules only), or "both" (default, applies both methods)

cook_threshold

Numeric value for Cook's distance threshold multiplier. Outliers are defined as points with Cook's D > cook_threshold / n, where n is the number of observations. Default is 4.

biological_rules

List of biological outlier rules. If NULL (default), uses default rule: common variants (MAF > 0.05) with large effects (|value| > 10). Custom rules can be provided as a list with elements containing 'maf_min' and 'effect_max' thresholds.

verbose

Integer controlling verbosity level: 0 = silent, 1 = warnings only, 2 = informational messages, 3 = detailed debug

Value

An S3 object of class "glow_outliers" containing:

indices

Integer vector of all outlier indices (combined from both methods)

statistical

Integer vector of statistical outlier indices (Cook's distance)

biological

Integer vector of biological outlier indices

reasons

Named list of descriptions for each outlier

outlier_MAF

MAF values for detected outliers only (memory efficient)

outlier_values

Effect values for detected outliers only (memory efficient)

n_total

Total number of variants analyzed

method_used

Character string indicating which detection method was used

Details

Statistical Outliers: Uses Cook's distance from a simple linear regression (values ~ MAF) to identify high-influence points. Cook's distance measures how much the fitted values change when an observation is removed. The threshold is typically 4/n, where n is the sample size.

Biological Outliers: Identifies variants with effect sizes that are biologically implausible given their allele frequency. The default rule flags common variants (MAF > 0.05) with very large effects (|value| > 10), as such combinations are rare in complex traits and may indicate genotyping errors, population stratification, or other artifacts.

Computational Complexity: O(n) for biological detection, O(n) for Cook's distance calculation via leverages and residuals. Overall complexity is O(n) where n is the number of variants.

References

Cook, R. D. (1977). Detection of Influential Observations in Linear Regression. Technometrics, 19(1), 15-22.

Examples

# Simulate training data with one clear outlier
set.seed(123)
MAF <- c(0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.45)
values <- c(0.5, 0.3, 0.2, 0.15, 0.1, 15, 0.05)  # value[6] is outlier

# Detect outliers using both methods
outliers <- detect_B_outliers(MAF, values, method = "both", verbose = 2)
#> Computing statistical outliers using Cook's distance...
#>   Found 2 statistical outlier(s) (Cook's D > 0.5714)
#> Detecting biological outliers...
#>   Found 1 biological outlier(s) from rule 'common_large' (MAF > 0.05, |effect| > 10.0)
#> Total of 2 outlier(s) detected
print(outliers)
#> GLOW Outlier Detection Results
#> ==============================
#> 
#> Method used: both
#> Total variants: 7
#> Total outliers: 2 (28.6%)
#>   Statistical outliers: 2
#>   Biological outliers: 1
#> 
#> Detailed Outlier Information:
#> -----------------------------
#> [6] Statistical & Biological outlier: MAF=0.4000, value=15.0000 (high influence and implausible effect) 
#> [7] Statistical outlier: MAF=0.4500, value=0.0500 (high influence) 

# Use only statistical outlier detection
outliers_stat <- detect_B_outliers(MAF, values, method = "statistical")
#> Total of 2 outlier(s) detected

# Use custom biological rules
custom_rules <- list(
  common_large = list(maf_min = 0.1, effect_max = 5)
)
outliers_custom <- detect_B_outliers(MAF, values,
                                     method = "biological",
                                     biological_rules = custom_rules)
#> Total of 1 outlier(s) detected