1 Introduction

This vignette shows the roles, inputs, processing stages, and outputs of the main dnaEPICO functions.

Use the diagrams to choose a function and follow outputs between stages. See the local-use and pipeline-use vignettes for arguments and executable examples.

Read each overview as follows:

  • The arrows show the expected flow from inputs to derived objects and files.
  • The grouped regions show the main analysis tasks performed inside a function.
  • The final nodes show the outputs that are returned to R or written to disk.
  • The same function can be used interactively or as part of a file-based pipeline, depending on the value of saveOutputs.

2 Required knowledge

dnaEPICO is built on core Bioconductor infrastructure for high-dimensional genomic data, with a focus on Illumina DNA methylation arrays. This vignette assumes familiarity with a general DNA methylation workflow. For an introduction, see this tutorial: https://paulyrp.github.io/2025-cpgpneurogenomics-workshop/tutorial.html. It covers the main concepts and analysis steps.

Preprocessing and quality control are performed using established Bioconductor tools, including minfi, ENmix, and wateRmelon. Downstream statistical modelling relies on base R and CRAN frameworks, including generalised linear models and linear mixed-effects models. Users are expected to have basic familiarity with R, Bioconductor pipelines, command-line execution, and Illumina IDAT file structures.

For an introduction to Bioconductor, see the installation guide.

2.1 Probe-exclusion reference files

The lists of excluded probes depend on the Illumina methylation-array platform.

  • For Illumina HumanMethylationEPIC v2.0, use the cross-reactive probe-exclusion file from Peters et al. (2024).

  • For Illumina MethylationEPIC, also known as the 850k array, use the probe-exclusion resources from Pidsley et al. (2016). The supporting files commonly used together are 13059_2016_1066_MOESM1_ESM.csv, 13059_2016_1066_MOESM4_ESM.csv, 13059_2016_1066_MOESM5_ESM.csv, and 13059_2016_1066_MOESM6_ESM.csv.

  • For Illumina HumanMethylation450k, use the cross-reactive and polymorphic probe resources from Chen et al. (2013).

  • Multiple probe-exclusion files can be supplied as a semicolon-separated value in probeExclusionPath. dnaEPICO reads probe IDs from each file, uses probeExclusionIdColumn when supplied, or otherwise auto-detects common probe-ID columns such as ProbeID, TargetID, IlmnID, and Name. The unique union of all probe IDs is then used to filter the normalised object.

  • For EPICv2, setting useEpicV2Manifest = TRUE also retrieves the expanded Peters et al. manifest from AnnotationHub resource AH116484. Probes flagged in selected manifest columns are added to the same exclusion set. By default, probes flagged by CH_WGBS_evidence, CH_BLAT, or MissingPos are removed, while MismatchPos is retained unless explicitly enabled.

3 Functions

The main functions follow the analysis path from preprocessing and surrogate-variable estimation through phenotype preparation, modelling, and report generation.

3.1 preprocessingMinfiEwasWater()

preprocessingMinfiEwasWater() reads the phenotype table and IDAT files, builds the methylation objects, performs quality control and normalisation, filters probes, and estimates cell composition.

Its role in the package is to create analysis-ready methylation data:

  • Inputs: phenotype metadata, IDAT files, array annotation, and filtering settings.
  • Processing tasks: import, quality control, normalisation, probe filtering, metric extraction, and cell-composition estimation. When removeSexMismatch = TRUE, samples are removed only when both reported and predicted sex are available and disagree; samples with missing or unknown sex information remain because their mismatch status cannot be determined.
  • Outputs: filtered phenotype data, RGSet, beta values, M-values, copy-number values, quality-control figures, and phenoLC. The log reports the observed finite minimum and maximum for each methylation matrix without modifying its values.

100%

preprocessingMinfiEwasWater() overview

3.2 svaEnmix()

svaEnmix() estimates surrogate variables from control-probe information and adds them to the phenotype table. This step helps represent technical variation that may otherwise influence downstream association models.

Its role is to prepare covariates for batch and technical adjustment:

  • Inputs: the phenotype table from preprocessing and the saved RGSet.
  • Processing tasks: control-probe extraction, surrogate-variable estimation, association checks with array-position metadata, and phenotype merging.
  • Outputs: surrogate-variable matrices, an updated phenotype table, and diagnostic summaries.

100%

svaEnmix() overview

3.3 preprocessingPheno()

preprocessingPheno() aligns phenotype information with methylation metrics. It prepares timepoint-specific data, combines longitudinal records, and creates export-ready files for external methylation-age tools.

Its role is to organise samples and methylation matrices for modelling:

  • Inputs: phenotype data, beta values, M-values, copy-number values, and timepoint settings.
  • Processing tasks: sample alignment, timepoint splitting, longitudinal merging, and Clock Foundation export preparation.
  • Outputs: timepoint-specific phenotype-methylation tables, combined longitudinal tables, and Clock Foundation input files.

100%

preprocessingPheno() overview

3.4 methylationGLM()

methylationGLM() fits cross-sectional methylation association models. It is designed for analyses where one phenotype is tested against CpG-level methylation while adjusting for selected covariates.

Its role is to run single-timepoint association testing:

  • Inputs: a phenotype-methylation table, phenotype variables, covariates, categorical and scaled-variable selections, optional PRS mappings, and annotation settings.
  • Processing tasks: model preparation, CpG-GLM fitting, coefficient and optional omnibus testing, diagnostic plotting, multiple-testing adjustment, summarisation, and annotation.
  • Outputs: compact phenotype summaries, summary tables, diagnostic figures, significant-CpG exports, and annotated workbooks. Native glm2 conditions are stored in <Phenotype>_Model.Message; CpGs without a returned p-value remain in the compact summary and are counted in workbook metadata. GRCh38 analyses can optionally append release-aware GENCODE gene-body and nearest-TSS annotations through AnnotationHub.

100%

methylationGLM() overview

3.5 methylationLME()

methylationLME() fits longitudinal mixed-effects models. It supports repeated-measures designs with a participant-level random intercept and timepoint-related fixed effects. For lmerTest/lme4 models, an optional omnibus F test jointly evaluates all estimable coefficients for a phenotype main effect or phenotype-by-interaction term. If the participant column is absent, the configured SampleID column can be used to derive it from identifiers ending in the supported A/B visit code.

Its role is to model methylation change across repeated observations:

  • Inputs: combined longitudinal phenotype-methylation data, participant identifiers, timepoint variables, phenotypes, covariates, categorical and scaled-variable selections, and annotation settings.
  • Processing tasks: longitudinal model preparation, CpG-LME model fitting, coefficient and optional omnibus testing, diagnostic plotting, summarisation, multiple-testing adjustment, and annotation.
  • Outputs: compact phenotype summaries, interaction summaries, diagnostic figures, significant-interaction exports, and annotated longitudinal workbooks. Native lmerTest/lme4 or nlme conditions are stored in <Phenotype>_Model.Message; CpGs without a returned coefficient or omnibus p-value remain in the compact summary and are counted in workbook metadata. The same optional AnnotationHub annotation is supported by both the lmerTest/lme4 and nlme engines for GRCh38 results.

100%

methylationLME() overview

3.6 dnamReport()

dnamReport() assembles the main tables, figures, logs, and model summaries into a report website. It can be run after preprocessing and modelling outputs have been written to disk.

Its role is to make the package outputs easier to inspect and share:

  • Inputs: phenotype tables, QC figures, ENmix figures, SVA figures, metric figures, model annotation tables, detection P-value data, and logs.
  • Processing tasks: input validation, report file preparation, Quarto rendering, and post-processing.
  • Outputs: a responsive dark report site with persistent navigation, a wide central table or figure panel, contextual notes and controls, and organised tabs for data, preprocessing, modelling, logs, and supporting diagnostics.

100%

dnamReport() overview

4 Summary

The preprocessing functions create quality-controlled methylation data and analysis-ready phenotype tables. The modelling functions fit cross-sectional and longitudinal association models. The report function gathers the resulting tables, figures, and logs into a browsable output.

The main workflow is:

  • run preprocessingMinfiEwasWater() to prepare methylation objects and QC outputs,
  • run svaEnmix() when control-probe surrogate variables are needed,
  • run preprocessingPheno() to prepare modelling tables,
  • run methylationGLM() or methylationLME() for association testing, and
  • run dnamReport() to review the completed outputs.

5 Basics

Date the vignette was generated.

#> [1] "2026-08-18 17:31:30 EDT"

Wallclock time spent generating the vignette.

#> Time difference of 0.256 secs

R session information.

#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.04.4 LTS
#> 
#> Matrix products: default
#> BLAS:   /home/biocbuild/bbs-3.24-bioc/R/lib/libRblas.so 
#> LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0  LAPACK version 3.12.0
#> 
#> locale:
#>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
#>  [3] LC_TIME=en_GB              LC_COLLATE=C              
#>  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
#>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
#>  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
#> 
#> time zone: America/New_York
#> tzcode source: system (glibc)
#> 
#> attached base packages:
#> [1] parallel  stats4    stats     graphics  grDevices utils     datasets 
#> [8] methods   base     
#> 
#> other attached packages:
#>  [1] IlluminaHumanMethylation450kanno.ilmn12.hg19_0.6.1
#>  [2] IlluminaHumanMethylation450kmanifest_0.4.0        
#>  [3] minfi_1.59.1                                      
#>  [4] bumphunter_1.55.1                                 
#>  [5] locfit_1.5-9.12                                   
#>  [6] iterators_1.0.14                                  
#>  [7] foreach_1.5.2                                     
#>  [8] Biostrings_2.81.6                                 
#>  [9] XVector_0.53.0                                    
#> [10] SummarizedExperiment_1.43.0                       
#> [11] Biobase_2.73.2                                    
#> [12] MatrixGenerics_1.25.0                             
#> [13] matrixStats_1.5.0                                 
#> [14] GenomicRanges_1.65.1                              
#> [15] Seqinfo_1.3.0                                     
#> [16] IRanges_2.47.2                                    
#> [17] S4Vectors_0.51.6                                  
#> [18] BiocGenerics_0.59.12                              
#> [19] generics_0.1.4                                    
#> [20] dnaEPICO_0.99.38                                  
#> [21] BiocStyle_2.41.0                                  
#> 
#> loaded via a namespace (and not attached):
#>   [1] splines_4.6.1             BiocIO_1.23.3            
#>   [3] bitops_1.1-0              filelock_1.0.3           
#>   [5] tibble_3.3.1              preprocessCore_1.75.0    
#>   [7] XML_3.99-0.23             lifecycle_1.0.5          
#>   [9] httr2_1.3.0               doParallel_1.0.17        
#>  [11] lattice_0.23-1            MASS_7.3-66              
#>  [13] base64_2.0.2              scrime_1.3.7             
#>  [15] magrittr_2.0.5            limma_3.69.4             
#>  [17] sass_0.4.10               rmarkdown_2.31           
#>  [19] jquerylib_0.1.4           yaml_2.3.12              
#>  [21] otel_0.2.0                doRNG_1.8.6.3            
#>  [23] askpass_1.2.1             DBI_1.3.0                
#>  [25] RColorBrewer_1.1-3        abind_1.4-8              
#>  [27] quadprog_1.5-8            purrr_1.2.2              
#>  [29] RCurl_1.98-1.19           rappdirs_0.3.4           
#>  [31] ggrepel_0.9.8             irlba_2.3.7              
#>  [33] rentrez_1.2.4             genefilter_1.95.0        
#>  [35] annotate_1.91.0           DelayedMatrixStats_1.35.0
#>  [37] codetools_0.2-20          DelayedArray_0.39.5      
#>  [39] xml2_1.6.0                tidyselect_1.2.1         
#>  [41] farver_2.1.2              beanplot_1.3.1           
#>  [43] BiocFileCache_3.3.0       dynamicTreeCut_1.63-1    
#>  [45] illuminaio_0.55.0         GenomicAlignments_1.49.1 
#>  [47] jsonlite_2.0.0            multtest_2.69.0          
#>  [49] survival_3.8-9            tools_4.6.1              
#>  [51] Rcpp_1.1.2                glue_1.8.1               
#>  [53] SparseArray_1.13.2        BiocBaseUtils_1.15.1     
#>  [55] xfun_0.60                 dplyr_1.2.1              
#>  [57] HDF5Array_1.41.2          BiocManager_1.30.27      
#>  [59] fastmap_1.2.0             rhdf5filters_1.25.4      
#>  [61] openssl_2.4.2             caTools_1.18.4           
#>  [63] digest_0.6.39             R6_2.6.1                 
#>  [65] RPMM_1.25                 gtools_3.9.5             
#>  [67] dichromat_2.0-1           RSQLite_3.53.3           
#>  [69] cigarillo_1.3.1           h5mread_1.5.0            
#>  [71] minfiData_0.59.0          tidyr_1.3.2              
#>  [73] data.table_1.18.4         rtracklayer_1.73.0       
#>  [75] httr_1.4.8                S4Arrays_1.13.0          
#>  [77] pkgconfig_2.0.3           gtable_0.3.6             
#>  [79] blob_1.3.0                S7_0.2.2                 
#>  [81] siggenes_1.87.0           impute_1.87.0            
#>  [83] htmltools_0.5.9           bookdown_0.47            
#>  [85] geneplotter_1.91.0        scales_1.4.0             
#>  [87] png_0.1-9                 knitr_1.51               
#>  [89] tzdb_0.5.0                rjson_0.2.23             
#>  [91] nlme_3.1-170              curl_7.1.0               
#>  [93] cachem_1.1.0              rhdf5_2.57.10            
#>  [95] KernSmooth_2.23-27        BiocVersion_3.24.0       
#>  [97] AnnotationDbi_1.75.2      restfulr_0.0.17          
#>  [99] GEOquery_2.81.28          pillar_1.11.1            
#> [101] grid_4.6.1                reshape_0.8.10           
#> [103] vctrs_0.7.3               gplots_3.3.0             
#> [105] ENmix_1.49.3              dbplyr_2.6.0             
#> [107] xtable_1.8-8              cluster_2.1.8.3          
#> [109] evaluate_1.0.5            readr_2.2.0              
#> [111] GenomicFeatures_1.65.0    cli_3.6.6                
#> [113] compiler_4.6.1            Rsamtools_2.29.0         
#> [115] rlang_1.3.0               crayon_1.5.3             
#> [117] rngtools_1.5.2            nor1mix_1.3-3            
#> [119] mclust_6.1.3              plyr_1.8.9               
#> [121] BiocParallel_1.47.0       Matrix_1.7-6             
#> [123] ExperimentHub_3.3.2       hms_1.1.4                
#> [125] sparseMatrixStats_1.25.0  bit64_4.8.2              
#> [127] ggplot2_4.0.3             Rhdf5lib_2.1.0           
#> [129] KEGGREST_1.53.6           statmod_1.5.2            
#> [131] AnnotationHub_4.3.2       memoise_2.0.1            
#> [133] bslib_0.12.0              bit_4.6.0

5.1 Asking for help

Use the Bioconductor support site for package questions. Add the dnaEPICO tag, review previous posts, and include a small reproducible example with session information.