Association of epigenetic age acceleration with MRI biomarkers of aging and Alzheimer's disease neurodegeneration.
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
R · 120 lines · 7.5 KB · GPL-3.0
- #' Generate the Dunedin Methylation Pace of Aging Scores!
- #'
- #' \code{PACEProjector} returns the Dunedin Pace of Aging Methylation Scores
- #'
- #' @param betas A numeric matrix containing the percent-methylation for each probe. Missing data should be 'NA's. The rows should be probes, with the probe ID as the row name, and the columns should be samples, with sample names as the column name.
- #' @param proportionOfProbesRequired (default: 0.8). This value specificies the threshold for missing data (see description for more details on how missing data is handled). Note: that if the function detects EPICv2 data based on rownames that contain the replicate suffix, the proportion of probes required will automatically be lowered to 0.7.
- #' @return A list of mPACE values. There will be one element in the list for each mPACE model. Each element will consist of a numeric vector with mPACE values. The names of the values in the vector will be the sample names from the 'betas' matrix. The output is equivalent to the pace of aging (in years) expected over a 1-year period.
- #' @details This function returns the Dunedin Methylation Pace of Aging scores for methylation data generated from either the Illumina 450K array or the Illumina EPIC array. The Age45 score is one that has been trained on data based on 3 waves of collection (26, 38, and 45). The manuscript is currently in preparation, but has been shown to be more accurate than the Age38 score.
- #' Missing data handled in two different ways (and the threshold for both is set by the 'proportionOfProbesRequired' parameter). First, if a sample is missing data for more probes than the threshold, the sample will get an NA back for a score. If a particular probe is missing fewer samples than the threshold, then missing data is set to the mean in the provided 'betas' matrix. If a probe is missing more samples than the threshold, then all samples in the 'betas' matrix have their value replaced with the mean of the training data for that particular model.
- #' Because of how we handle missing data, it is recommended that entire cohorts be run at once as a large 'betas' matrix.
- #' @examples
- #' PACEProjector(betas)
- PACEProjector = function( betas, proportionOfProbesRequired=0.8 ) {
- requireNamespace("preprocessCore")
- if( any(grepl("TC|BC", rownames(betas))) )
- {
- # Print message to user
- print("This looks like EPICv2 array data. If EPICv2, DunedinPACE will lower the proportionOfProbesRequired to 0.7 and proceed with missing probes present on 450k and EPICv1. Averaging the opposite strand replicates may take a bit more time.")
- # Proceed with averaging: Code taken from ENmix package.
- cgid = sapply(strsplit(rownames(betas), split = "_"), unlist)[1, ]
- dupcg = unique(cgid[duplicated(cgid)])
- betas2 = betas[cgid %in% dupcg, ]
- cid = sapply(strsplit(rownames(betas2), split = "_"), unlist)[1, ]
- betas2 = aggregate(betas2, by = list(cid), FUN = function(x) mean(x, na.rm = TRUE))
- rownames(betas2) = betas2[, 1]
- betas2 = as.matrix(betas2[, -1])
- betas = betas[!(cgid %in% dupcg), ]
- rownames(betas) = sapply(strsplit(rownames(betas), split = "_"), unlist)[1, ]
- betas <-rbind(betas, betas2)
- # Set proportionOfProbesRequired to 0.7 if condition is TRUE
- proportionOfProbesRequired <- 0.7
- }
- # loop through models
- model_results <- lapply(mPACE_Models$model_names, function(model_name) {
- # make sure it has been converted to a matrix
- if( !is.numeric(as.matrix(betas)) ) { stop("betas matrix/data.frame is not numeric!") }
- probeOverlap <- length(which(rownames(betas) %in% mPACE_Models$model_probes[[model_name]])) / length(mPACE_Models$model_probes[[model_name]])
- probeOverlap_background <- length(which(rownames(betas) %in% mPACE_Models$gold_standard_probes[[model_name]])) / length(mPACE_Models$gold_standard_probes[[model_name]])
- # make sure enough of the probes are present in the data file
- if( probeOverlap < proportionOfProbesRequired | probeOverlap_background < proportionOfProbesRequired ) {
- result <- rep(NA, ncol(betas))
- names(result) <- colnames(betas)
- result
- } else {
- # Work with a numeric matrix of betas
- betas.mat <- as.matrix(betas[which(rownames(betas) %in% mPACE_Models$gold_standard_probes[[model_name]]),])
- # If probes don't exist, we'll add them as rows of values based on their mean in the gold standard dataset
- probesNotInMatrix <- mPACE_Models$gold_standard_probes[[model_name]][which(mPACE_Models$gold_standard_probes[[model_name]] %in% rownames(betas.mat) == F)]
- if( length(probesNotInMatrix) > 0 ) {
- for( probe in probesNotInMatrix ) {
- tmp.mat <- matrix(0, nrow=1, ncol=ncol(betas.mat))
- rownames(tmp.mat) <- probe
- colnames(tmp.mat) <- colnames(betas.mat)
- tmp.mat[probe,] <- rep(mPACE_Models$gold_standard_means[[model_name]][probe], ncol(tmp.mat))
- betas.mat <- rbind(betas.mat, tmp.mat)
- }
- }
- # Identify samples with too many missing probes and remove them from the matrix
- samplesToRemove <- colnames(betas.mat)[which(apply(betas.mat, 2, function(x) { 1 - ( length(which(is.na(x))) / length(x) ) < proportionOfProbesRequired}))]
- if( length(samplesToRemove) > 0 ) {
- betas.mat <- betas.mat[,-which(colnames(betas.mat) %in% samplesToRemove)]
- }
- if(ncol(betas.mat) > 0) {
- # Identify missingness on a probe level
- pctValuesPresent <- apply( betas.mat, 1, function(x) { 1 - (length(which(is.na(x))) / length(x)) } )
- # If they're missing values, but less than the proportion required, we impute to the cohort mean
- probesToAdjust <- which(pctValuesPresent < 1 & pctValuesPresent >= proportionOfProbesRequired)
- if( length(probesToAdjust) > 0 ) {
- if( length(probesToAdjust) > 1 ) {
- betas.mat[probesToAdjust,] <- t(apply( betas.mat[probesToAdjust,], 1 , function(x) {
- x[is.na(x)] = mean( x, na.rm = TRUE )
- x
- }))
- } else {
- betas.mat[probesToAdjust,which(is.na(betas.mat[probesToAdjust,]))] <- mean(betas.mat[probesToAdjust,], na.rm=T)
- }
- }
- # If they're missing too many values, everyones value gets replaced with the mean from the Dunedin cohort
- if( length(which(pctValuesPresent < proportionOfProbesRequired)) > 0 ) {
- probesToReplaceWithMean <- rownames(betas.mat)[which(pctValuesPresent < proportionOfProbesRequired)]
- for( probe in probesToReplaceWithMean ) {
- betas.mat[probe,] <- rep(mPACE_Models$model_means[[model_name]][probe], ncol(betas.mat))
- }
- }
- # Normalize the matrix to the gold standard dataset
- betas.norm <- preprocessCore::normalize.quantiles.use.target(betas.mat, target=mPACE_Models$gold_standard_means[[model_name]])
- rownames(betas.norm) <- rownames(betas.mat)
- colnames(betas.norm) <- colnames(betas.mat)
- # Calculate score:
- score = mPACE_Models$model_intercept[[model_name]] + rowSums(t(betas.norm[mPACE_Models$model_probes[[model_name]],]) %*% diag(mPACE_Models$model_weights[[model_name]]))
- names(score) <- colnames(betas.norm)
- if( length(samplesToRemove) > 0 ) {
- score.tmp <- rep(NA, length(samplesToRemove))
- names(score.tmp) <- samplesToRemove
- score <- c(score, score.tmp)
- }
- score <- score[colnames(betas)]
- score
- } else {
- result <- rep(NA, ncol(betas.mat))
- names(result) <- colnames(betas.mat)
- result
- }
- }
- })
- names(model_results) <- mPACE_Models$model_names
- model_results
- }
PACEProjector.R at commit 4b56998, under GPL-3.0 · at the source
Overview
14 affiliations
- Kaiser Permanente Washington Health Research Institute, Seattle, WA 98101, USA
- Herbert Wertheim School of Public Health and Human Longevity Science, University of California San Diego, La Jolla, CA 92037, USA
- Department of Psychiatry, School of Medicine, University of California San Diego, La Jolla, CA 92093, USA
- Veterans Affairs San Diego Healthcare System, Research Service, San Diego, CA 92161, USA
- Department of Biostatistics and Data Science, Wake Forest University School of Medicine, Winston-Salem, NC 27101, USA
- Altos Labs Cambridge Institute of Science, Cambridge, UK
- Altos Labs, San Diego, CA 92121, USA
- Department of Radiology, University of Pennsylvania School of Medicine, Philadelphia, PA 19104, USA
- Laboratory of Behavioral Neuroscience, National Institute on Aging, National Institutes of Health, Baltimore, MD 21224, USA
- Division of Gerontology and Geriatric Medicine, School of Medicine, Wake Forest University School of Medicine, Winston-Salem, NC 27101, USA
- Department of Psychiatry and Behavioral Medicine, Wake Forest University School of Medicine, Winston-Salem, NC 27103, USA
- Genomics Center, University of Minnesota, Minneapolis, MN 55455, USA
- Longitudinal Studies Section, Translational Gerontology Branch, National Institute on Aging, Baltimore, MD 21225, USA
- Division of Geriatrics, Gerontology, and Palliative Care, Department of Medicine, University of California San Diego, La Jolla, CA 92093, USA
Abstract
Epigenetic clocks of biological aging have been associated with cognitive impairment and dementia. Less is known about whether they are associated with an older-appearing brain or with an atrophy pattern associated with dementia. We examined associations of five epigenetic clocks measured at baseline with the Spatial Pattern of Atrophy for Recognition of Brain Aging (SPARE-BA) and the Alzheimer’s Disease Pattern Similarity Score (AD-PS) derived from structural MRIs obtained an average of 8 years later among 1,196 older women. Using linear regression models adjusting for relevant covariates, we observed no associations between any epigenetic clock and accelerated brain aging based on SPARE-BA. We observed a significant association between AgeAccelGrim2 and AD-PS (β = 0.015; 95% CI 0.004 to 0.027; p = 0.01). This association appeared to be primarily driven by the association of a DNA methylation marker of smoking pack years with frontal and temporal lobe volumes. AgeAccelGrim2 was not associated with volumes in regions implicated in early AD (hippocampus and entorhinal cortex). Taken together with prior findings, these results suggest that measures of epigenetic and brain age acceleration capture different aspects of biological aging, and that AgeAccelGrim2 is predictive of neurodegenerative changes associated with smoking that increase risk of dementia.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repository
Its files are read in the Code ↔ Paper reader above.
danbelsky/DunedinPACE
4b569983543e51d1022aecec9a25e694bb3a336a, 6 June 2025Availability: 1 check, the latest on 29 September 2026: the link answers
- 29 September 2026: the link answers
7 files
- R/
PACEProjector.R — R, 120 lines - R/
PoAmProjector.R — R, 17 lines - R/
getRequiredProbes.R — R, 21 lines - vignettes/
DunedinPACE.Rmd — R, 95 lines - vignettes/
DunedinPACE_files/ — JavaScript, 19 linesMathJax.js - LICENSE — License, 674 lines
- README.md — Text, 132 lines
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 5 scripts, each with its path and the digest of its content;
- no match between paragraphs and code yet;
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 29 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 17 authors, 5 keywords, 1 funder, 47 references.
Cite
This paper
McEvoy, L. K., Zhang, B., Nguyen, S., Maihofer, A. X., Nievergelt, C. M., Casanova, R., Horvath, S., Lu, A. T., Davatzikos, C., Erus, G., Resnick, S. M., Espeland, M. A., Rapp, S., Beckman, K., Ferrucci, L., LaCroix, A. Z., & Shadyab, A. H. (2026). Association of epigenetic age acceleration with MRI biomarkers of aging and Alzheimer's disease neurodegeneration. Aging, 18(1), 303-326. https://
BibTeX
@article{mcevoy2026assoc
author = {McEvoy, Linda K and Zhang, Bowei and Nguyen, Steve and Maihofer, Adam X and Nievergelt, Caroline M and Casanova, Ramon and Horvath, Steve and Lu, Ake T and Davatzikos, Christos and Erus, Guray and Resnick, Susan M and Espeland, Mark A and Rapp, Steve and Beckman, Kenneth and Ferrucci, Luigi and LaCroix, Andrea Z and Shadyab, Aladdin H},
title = {{Association of epigenetic age acceleration with MRI biomarkers of aging and Alzheimer's disease neurodegeneration}},
journal = {Aging},
year = {2026},
month = apr,
volume = {18},
number = {1},
pages = {303--326},
publisher = {Impact Journals, LLC},
issn = {1945-4589},
doi = {10.18632/
url = {https://
pmid = {41949889},
pmcid = {PMC13285947}
}
RIS
TY - JOUR
AU - McEvoy, Linda K
AU - Zhang, Bowei
AU - Nguyen, Steve
AU - Maihofer, Adam X
AU - Nievergelt, Caroline M
AU - Casanova, Ramon
AU - Horvath, Steve
AU - Lu, Ake T
AU - Davatzikos, Christos
AU - Erus, Guray
AU - Resnick, Susan M
AU - Espeland, Mark A
AU - Rapp, Steve
AU - Beckman, Kenneth
AU - Ferrucci, Luigi
AU - LaCroix, Andrea Z
AU - Shadyab, Aladdin H
TI - Association of epigenetic age acceleration with MRI biomarkers of aging and Alzheimer's disease neurodegeneration
T2 - Aging
J2 - Aging (Albany NY)
PY - 2026
DA - 2026/
VL - 18
IS - 1
SP - 303
EP - 326
SN - 1945-4589
PB - Impact Journals, LLC
DO - 10.18632/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.18632/
"type": "article-journal",
"title": "Association of epigenetic age acceleration with MRI biomarkers of aging and Alzheimer's disease neurodegeneration",
"container-title": "Aging",
"author": [
{
"family": "McEvoy",
"given": "Linda K"
},
{
"family": "Zhang",
"given": "Bowei"
},
{
"family": "Nguyen",
"given": "Steve"
},
{
"family": "Maihofer",
"given": "Adam X"
},
{
"family": "Nievergelt",
"given": "Caroline M"
},
{
"family": "Casanova",
"given": "Ramon"
},
{
"family": "Horvath",
"given": "Steve"
},
{
"family": "Lu",
"given": "Ake T"
},
{
"family": "Davatzikos",
"given": "Christos"
},
{
"family": "Erus",
"given": "Guray"
},
{
"family": "Resnick",
"given": "Susan M"
},
{
"family": "Espeland",
"given": "Mark A"
},
{
"family": "Rapp",
"given": "Steve"
},
{
"family": "Beckman",
"given": "Kenneth"
},
{
"family": "Ferrucci",
"given": "Luigi"
},
{
"family": "LaCroix",
"given": "Andrea Z"
},
{
"family": "Shadyab",
"given": "Aladdin H"
}
],
"container-title-short":
"volume": "18",
"issue": "1",
"page": "303-326",
"DOI": "10.18632/
"PMID": "41949889",
"PMCID": "PMC13285947",
"ISSN": "1945-4589",
"publisher": "Impact Journals, LLC",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
7
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1016/j.bbih.2026.101316
- Peripheral blood DNA methylation partially reports on immune cell type composition in the frontal brain.Journal: Brain, behavior, & immunity - healthIn common: 4 references
- [2] doi:10.1038/s41467-026-71271-9 [code]
- Exposome-wide patterns predict brain health in aging.Journal: Nature communicationsIn common: clinical / translational, 4 references
- [3] doi:10.1038/s41598-026-48613-0 [code]
- An snRNA-seq aging clock for the fruit fly head sheds light on sex-biased aging.Journal: Scientific reportsIn common: 4 references
- [4] doi:10.1162/imag.a.1242 [code]
- Stable individual differences dominate adult brain volume variation until later life.Journal: Imaging neuroscience (Cambridge, Mass.)In common: structural MRI / diffusion, 4 references
- [5] doi:10.1016/j.isci.2026.116439 [code]
- Decoding the role of transcriptomic clocks in the human prefrontal cortex.Journal: iScienceIn common: 4 references
- [6] doi:10.1038/s41467-026-74515-w [code]
- Advancing fair and explainable machine learning for neuroimaging dementia pattern classification in multi-racial and multi-ethnic populations.Journal: Nature communicationsIn common: Alzheimer's / dementia, structural MRI / diffusion, 3 references
- [7] doi:10.1038/s41467-026-73071-7 [code]
- Brain maintenance biomarkers from structural and functional interactions in aging and neurodegeneration.Journal: Nature communicationsIn common: Alzheimer's / dementia, structural MRI / diffusion, clinical / translational, 1 other category, 2 references
- [8] doi:10.1007/s11357-026-02195-x [code]
- The aging epigenome: integrative analyses reveal intersection with Alzheimer's disease.Journal: GeroScienceIn common: Alzheimer's / dementia, 3 references
- [9] doi:10.1186/s40708-026-00316-y [code]
- Generalizable and explainable deep learning for brain MRI: a multi-cohort evaluation of 3D architectures for age and sex prediction.Journal: Brain informaticsIn common: structural MRI / diffusion, 3 references
- [10] doi:10.3389/fnagi.2026.1789408 [code]
- Biological brain aging, cognitive-motor decline and vascular risk: a multivariate imaging analysis of 40,579 individuals.Journal: Frontiers in aging neuroscienceIn common: structural MRI / diffusion, 3 references
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 1 repository of the authors' code, each at its verified commit and with its license, 5 scripts, and 0 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:846eb757d34d63b9…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
