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; OSCR does not store it: 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 (how the code is found and 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.1038/s41598-025-11350-x [code]
Associations between epigenetic age and brain age in young people.
Journal: Scientific reports
In common: structural MRI / diffusion, 10 references
[2] doi:10.1007/s11357-024-01376-w [code]
Complementary value of molecular, phenotypic, and functional aging biomarkers in dementia prediction.
Journal: GeroScience
In common: Alzheimer's / dementia, structural MRI / diffusion, clinical / translational, 9 references
[3] doi:10.1038/s41598-024-60311-3 [code]
Accelerated epigenetic age is associated with whole-brain functional connectivity and impaired cognitive performance in older adults.
Journal: Scientific reports
In common: 9 references
[4] doi:10.1007/s11357-023-00941-z [code]
Sex differences in biological aging and the association with clinical measures in older adults.
Journal: GeroScience
In common: clinical / translational, 8 references
[5] doi:10.64898/2026.03.09.26347914 [code]
Multimodal Ageing Biomarkers and Plasma Proteomic Signatures Associated with All-Cause Mortality
Journal: medRxiv (preprint)
In common: structural MRI / diffusion, clinical / translational, 7 references
[6] doi:10.1212/wnl.0000000000200898
Association of Pace of Aging Measured by Blood-Based DNA Methylation With Age-Related Cognitive Impairment and Dementia.
Journal: Neurology
In common: Alzheimer's / dementia, clinical / translational, 7 references
[7] doi:10.3390/jpm12111850 [code]
Neuroimaging-Based Brain Age Estimation: A Promising Personalized Biomarker in Neuropsychiatry.
Journal: Journal of personalized medicine
In common: structural MRI / diffusion, clinical / translational, 6 references
[8] doi:10.1101/2025.05.09.653064 [code]
Lifestyle, Early-life, and Genetic Health Risk Factors Underlying the Brain Age Gap: A Mega-Analysis Across 3,934 Individuals from the ENIGMA MDD Consortium
Journal: bioRxiv (preprint)
In common: structural MRI / diffusion, 7 references
[9] doi:10.1016/j.bpsgos.2025.100577 [code]
Epigenetic and Structural Brain Aging and Their Associations With Major Depressive Disorder.
Journal: Biological psychiatry global open science
In common: structural MRI / diffusion, 7 references
[10] doi:10.1111/acel.70281 [code]
DNA Methylation Signatures of Systemic Inflammation Are Associated With Brain Volume, Cognitive Trajectories, and Long-Term Dementia Risk.
Journal: Aging cell
In common: Alzheimer's / dementia, structural MRI / diffusion, 6 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.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/doi/10.18632/aging.206369.svg)](https://openscicode.org/badge/doi/10.18632/aging.206369)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/doi/10.18632/aging.206369.svg
   :target: https://openscicode.org/badge/doi/10.18632/aging.206369
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.18632/aging.206369"><img src="https://openscicode.org/badge/doi/10.18632/aging.206369.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

On GitHub, open the README, choose Edit (the pencil), paste the snippet under the title, then "Commit changes".

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge 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: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.