OSCR

Association of epigenetic age acceleration with MRI biomarkers of aging and Alzheimer's disease neurodegeneration.

Code ↔ Paper

The paper beside its authors' code: matches between them have not been computed for this paper yet.

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

  1. #' Generate the Dunedin Methylation Pace of Aging Scores!
  2. #'
  3. #' \code{PACEProjector} returns the Dunedin Pace of Aging Methylation Scores
  4. #'
  5. #' @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.
  6. #' @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.
  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.
  8. #' @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.
  9. #' 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.
  10. #' Because of how we handle missing data, it is recommended that entire cohorts be run at once as a large 'betas' matrix.
  11. #' @examples
  12. #' PACEProjector(betas)
  13. PACEProjector = function( betas, proportionOfProbesRequired=0.8 ) {
  14. requireNamespace("preprocessCore")
  15. if( any(grepl("TC|BC", rownames(betas))) )
  16. {
  17. # Print message to user
  18. 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.")
  19. # Proceed with averaging: Code taken from ENmix package.
  20. cgid = sapply(strsplit(rownames(betas), split = "_"), unlist)[1, ]
  21. dupcg = unique(cgid[duplicated(cgid)])
  22. betas2 = betas[cgid %in% dupcg, ]
  23. cid = sapply(strsplit(rownames(betas2), split = "_"), unlist)[1, ]
  24. betas2 = aggregate(betas2, by = list(cid), FUN = function(x) mean(x, na.rm = TRUE))
  25. rownames(betas2) = betas2[, 1]
  26. betas2 = as.matrix(betas2[, -1])
  27. betas = betas[!(cgid %in% dupcg), ]
  28. rownames(betas) = sapply(strsplit(rownames(betas), split = "_"), unlist)[1, ]
  29. betas <-rbind(betas, betas2)
  30. # Set proportionOfProbesRequired to 0.7 if condition is TRUE
  31. proportionOfProbesRequired <- 0.7
  32. }
  33. # loop through models
  34. model_results <- lapply(mPACE_Models$model_names, function(model_name) {
  35. # make sure it has been converted to a matrix
  36. if( !is.numeric(as.matrix(betas)) ) { stop("betas matrix/data.frame is not numeric!") }
  37. probeOverlap <- length(which(rownames(betas) %in% mPACE_Models$model_probes[[model_name]])) / length(mPACE_Models$model_probes[[model_name]])
  38. probeOverlap_background <- length(which(rownames(betas) %in% mPACE_Models$gold_standard_probes[[model_name]])) / length(mPACE_Models$gold_standard_probes[[model_name]])
  39. # make sure enough of the probes are present in the data file
  40. if( probeOverlap < proportionOfProbesRequired | probeOverlap_background < proportionOfProbesRequired ) {
  41. result <- rep(NA, ncol(betas))
  42. names(result) <- colnames(betas)
  43. result
  44. } else {
  45. # Work with a numeric matrix of betas
  46. betas.mat <- as.matrix(betas[which(rownames(betas) %in% mPACE_Models$gold_standard_probes[[model_name]]),])
  47. # If probes don't exist, we'll add them as rows of values based on their mean in the gold standard dataset
  48. probesNotInMatrix <- mPACE_Models$gold_standard_probes[[model_name]][which(mPACE_Models$gold_standard_probes[[model_name]] %in% rownames(betas.mat) == F)]
  49. if( length(probesNotInMatrix) > 0 ) {
  50. for( probe in probesNotInMatrix ) {
  51. tmp.mat <- matrix(0, nrow=1, ncol=ncol(betas.mat))
  52. rownames(tmp.mat) <- probe
  53. colnames(tmp.mat) <- colnames(betas.mat)
  54. tmp.mat[probe,] <- rep(mPACE_Models$gold_standard_means[[model_name]][probe], ncol(tmp.mat))
  55. betas.mat <- rbind(betas.mat, tmp.mat)
  56. }
  57. }
  58. # Identify samples with too many missing probes and remove them from the matrix
  59. samplesToRemove <- colnames(betas.mat)[which(apply(betas.mat, 2, function(x) { 1 - ( length(which(is.na(x))) / length(x) ) < proportionOfProbesRequired}))]
  60. if( length(samplesToRemove) > 0 ) {
  61. betas.mat <- betas.mat[,-which(colnames(betas.mat) %in% samplesToRemove)]
  62. }
  63. if(ncol(betas.mat) > 0) {
  64. # Identify missingness on a probe level
  65. pctValuesPresent <- apply( betas.mat, 1, function(x) { 1 - (length(which(is.na(x))) / length(x)) } )
  66. # If they're missing values, but less than the proportion required, we impute to the cohort mean
  67. probesToAdjust <- which(pctValuesPresent < 1 & pctValuesPresent >= proportionOfProbesRequired)
  68. if( length(probesToAdjust) > 0 ) {
  69. if( length(probesToAdjust) > 1 ) {
  70. betas.mat[probesToAdjust,] <- t(apply( betas.mat[probesToAdjust,], 1 , function(x) {
  71. x[is.na(x)] = mean( x, na.rm = TRUE )
  72. x
  73. }))
  74. } else {
  75. betas.mat[probesToAdjust,which(is.na(betas.mat[probesToAdjust,]))] <- mean(betas.mat[probesToAdjust,], na.rm=T)
  76. }
  77. }
  78. # If they're missing too many values, everyones value gets replaced with the mean from the Dunedin cohort
  79. if( length(which(pctValuesPresent < proportionOfProbesRequired)) > 0 ) {
  80. probesToReplaceWithMean <- rownames(betas.mat)[which(pctValuesPresent < proportionOfProbesRequired)]
  81. for( probe in probesToReplaceWithMean ) {
  82. betas.mat[probe,] <- rep(mPACE_Models$model_means[[model_name]][probe], ncol(betas.mat))
  83. }
  84. }
  85. # Normalize the matrix to the gold standard dataset
  86. betas.norm <- preprocessCore::normalize.quantiles.use.target(betas.mat, target=mPACE_Models$gold_standard_means[[model_name]])
  87. rownames(betas.norm) <- rownames(betas.mat)
  88. colnames(betas.norm) <- colnames(betas.mat)
  89. # Calculate score:
  90. score = mPACE_Models$model_intercept[[model_name]] + rowSums(t(betas.norm[mPACE_Models$model_probes[[model_name]],]) %*% diag(mPACE_Models$model_weights[[model_name]]))
  91. names(score) <- colnames(betas.norm)
  92. if( length(samplesToRemove) > 0 ) {
  93. score.tmp <- rep(NA, length(samplesToRemove))
  94. names(score.tmp) <- samplesToRemove
  95. score <- c(score, score.tmp)
  96. }
  97. score <- score[colnames(betas)]
  98. score
  99. } else {
  100. result <- rep(NA, ncol(betas.mat))
  101. names(result) <- colnames(betas.mat)
  102. result
  103. }
  104. }
  105. })
  106. names(model_results) <- mPACE_Models$model_names
  107. model_results
  108. }

PACEProjector.R at commit 4b56998, under GPL-3.0 · at the source

Overview

Authors: Linda K McEvoy1, Bowei Zhang2, Steve Nguyen2, Adam X Maihofer3,4, Caroline M Nievergelt3,4, Ramon Casanova5, Steve Horvath6, Ake T Lu7, Christos Davatzikos8, Guray Erus8, Susan M Resnick8,9, Mark A Espeland10, Steve Rapp11, Kenneth Beckman12, Luigi Ferrucci13, Andrea Z LaCroix2, Aladdin H Shadyab2,14
ORCID iDs: Kenneth Beckman
14 affiliations
  1. Kaiser Permanente Washington Health Research Institute, Seattle, WA 98101, USA
  2. Herbert Wertheim School of Public Health and Human Longevity Science, University of California San Diego, La Jolla, CA 92037, USA
  3. Department of Psychiatry, School of Medicine, University of California San Diego, La Jolla, CA 92093, USA
  4. Veterans Affairs San Diego Healthcare System, Research Service, San Diego, CA 92161, USA
  5. Department of Biostatistics and Data Science, Wake Forest University School of Medicine, Winston-Salem, NC 27101, USA
  6. Altos Labs Cambridge Institute of Science, Cambridge, UK
  7. Altos Labs, San Diego, CA 92121, USA
  8. Department of Radiology, University of Pennsylvania School of Medicine, Philadelphia, PA 19104, USA
  9. Laboratory of Behavioral Neuroscience, National Institute on Aging, National Institutes of Health, Baltimore, MD 21224, USA
  10. Division of Gerontology and Geriatric Medicine, School of Medicine, Wake Forest University School of Medicine, Winston-Salem, NC 27101, USA
  11. Department of Psychiatry and Behavioral Medicine, Wake Forest University School of Medicine, Winston-Salem, NC 27103, USA
  12. Genomics Center, University of Minnesota, Minneapolis, MN 55455, USA
  13. Longitudinal Studies Section, Translational Gerontology Branch, National Institute on Aging, Baltimore, MD 21225, USA
  14. Division of Geriatrics, Gerontology, and Palliative Care, Department of Medicine, University of California San Diego, La Jolla, CA 92093, USA
Journal: Aging, volume 18, issue 1, pages 303-326
Dates: received 1 January 2026; accepted 11 March 2026; published online 7 April 2026; in print April 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.18632/aging.206369 · PMID 41949889 · PMCID PMC13285947 · OpenAlex W7151621018
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: structural MRI / diffusion (modality), other condition (population), Alzheimer's / dementia (population), clinical / translational (subfield)
Methods: Statistics, Connectivity, fMRI & imaging
Keywords: epigenetic clocks, brain age, biological aging, smoking, frontal lobe
Topic: Epigenetics and DNA Methylation (Molecular Biology, Biochemistry, Genetics and Molecular Biology), according to OpenAlex
Funding: NIA NIH HHS (R01 AG074345)
Citations: not cited yet (Europe PMC); 47 references in the paper

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

License: GPL-3.0
State: the link answers, verified on 29 September 2026
Evidence: files inventoried
Commit: 4b569983543e51d1022aecec9a25e694bb3a336a, 6 June 2025
Languages: R (4), JavaScript (1)
Size: 21 files, 5 scripts
Software Heritage: not archived
Found in: the text, “Epigenetic clocks”
Holds: README, license file, environment (DESCRIPTION), documentation, 1 notebook
Not found: CITATION.cff, tests, continuous integration
Availability: 1 check, the latest on 29 September 2026: the link answers
  • 29 September 2026: the link answers
7 files

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://doi.org/10.18632/aging.206369

BibTeX

@article{mcevoy2026association,
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/aging.206369},
url = {https://doi.org/10.18632/aging.206369},
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/04/07
VL - 18
IS - 1
SP - 303
EP - 326
SN - 1945-4589
PB - Impact Journals, LLC
DO - 10.18632/aging.206369
UR - https://doi.org/10.18632/aging.206369
LA - en
ER -

CSL-JSON

{
"id": "10.18632/aging.206369",
"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": "Aging (Albany NY)",
"volume": "18",
"issue": "1",
"page": "303-326",
"DOI": "10.18632/aging.206369",
"PMID": "41949889",
"PMCID": "PMC13285947",
"ISSN": "1945-4589",
"publisher": "Impact Journals, LLC",
"URL": "https://doi.org/10.18632/aging.206369",
"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 - health
In common: 4 references
[2] doi:10.1038/s41467-026-71271-9 [code]
Exposome-wide patterns predict brain health in aging.
Journal: Nature communications
In 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 reports
In 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: iScience
In 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 communications
In 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 communications
In 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: GeroScience
In 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 informatics
In 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 neuroscience
In 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.

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.