OSCR

Unveiling the glymphatic system's role in brain aging: A comprehensive biomarker and modifiable intervention target.

Code ↔ Paper

17 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 17 matches · 1 of them tie a paragraph to a whole file, not to given lines: a weak match, whose lines are not tinted
  1. [1] § Materials and Methods › Development and Validation of Brain Age Models. ↔ Brain age models/brain_age_model.py, lines 44–124 · score 0.86 · fold cross validation, absolute error, model training, chronological age, brain age model, XGBoost
  2. [2] § paragraph 3 ↔ DTI-ALPS Association/2_factor_analysis_ml.py, lines 1–25 · score 0.77 · CatBoost, LightGBM, machine learning, XGBoost, DTI ALPS, algorithms
  3. [3] § Materials and Methods › Protein-Wide and Genome-Wide Analysis of BAGs. ↔ BAGs Associations/BAG_GWAS/1_run_gwas.sh, the whole file · a weak match · score 0.76 · age squared sex, age sex interaction, GWAS, batch, gene, positional
  4. [4] § Results › Protein-Wide and Genome-Wide Associations of BAGs. ↔ BAGs Associations/BAG_associations_analysis.R, lines 407–457 · score 0.76 · IL18R1, BAG related proteins, BAG associated, CD36, CXCL17, LRRN1
  5. [5] § Results › BAGs in Organ-Specific Chronic Disease and Predict Mortality Risk. ↔ Brain age models/disease_analysis.py, lines 37–59 · score 0.73 · heart failure, respiratory failure, bipolar disorder, Nervous, stroke, parkinsonism
  6. [6] § Results › BAGs in Organ-Specific Chronic Disease and Predict Mortality Risk. ↔ BAGs Associations/BAG_associations_analysis.R, lines 41–120 · score 0.73 · heart failure, respiratory failure, bipolar disorder, stroke, parkinsonism, diabetes
  7. [7] § Materials and Methods › Modifiable Factors and Their Trajectory with BAG Change. ↔ BAGs Associations/BAG_associations_analysis.R, lines 614–663 · score 0.69 · latent class growth, modifiable factors, LCGA, trajectories, population, brain age
  8. [8] § Results › Specific Organ Age Gap on BAGs Derived from the DTI-ALPS. ↔ BAGs Associations/BAG_associations_visualization.R, lines 81–131 · score 0.66 · 60–65, 45–50, 70–75, organs, females, Pulmonary
  9. [9] § Materials and Methods › Development and Validation of Brain Age Models. ↔ Brain age models/visualize_predictions.py, lines 93–192 · score 0.65 · linear regression, predicted age, chronological age, brain age model, Pearson, correlation
  10. [10] § Results › Protein-Wide and Genome-Wide Associations of BAGs. ↔ BAGs Associations/BAG_associations_visualization.R, lines 485–560 · score 0.62 · BAG related proteins, genome wide, mortality risk, Manhattan, log10, Brain age gap
  11. [11] § Results › Modifiable Factors and Their Trajectories Associate with BAGs. ↔ BAGs Associations/BAG_associations_analysis.R, lines 726–768 · score 0.62 · red wine, mmHg, modifiable factors, WHR, trajectories, females
  12. [12] § Results › Protein-Wide and Genome-Wide Associations of BAGs. ↔ BAGs Associations/BAG_associations_analysis.R, lines 324–379 · score 0.60 · BAG related proteins, smoke status, alcohol frequency, Brain age gap, BMI, Cox
  13. [13] § Results › Modifiable Factors and Their Trajectories Associate with BAGs. ↔ BAGs Associations/BAG_associations_analysis.R, lines 614–663 · score 0.55 · latent class growth, Modifiable factors, LCGA, Brain age gap, trajectories, SBP
  14. [14] § Materials and Methods › Health-Related Outcomes and Mortality Risk Prediction. ↔ BAGs Associations/BAG_associations_analysis.R, lines 41–120 · score 0.55 · disease categories, chronic diseases, Stroke, Cohen, Disorders, healthy
  15. [15] § Results › Characteristic of the Study Population. ↔ Population characteristics/Population_characteristics.R, lines 1–50 · score 0.54 · multimodal brain imaging, age SD, Population, males, healthy, Disease
  16. [16] § Results › Specific Organ Age Gap on BAGs Derived from the DTI-ALPS. ↔ DTI-ALPS Association/2_factor_analysis_ml.py, lines 111–139 · score 0.53 · Gradient Boosting, XGBoost, SHAP, DTI ALPS, model
  17. [17] § Results › BAGs in Organ-Specific Chronic Disease and Predict Mortality Risk. ↔ BAGs Associations/BAG_associations_analysis.R, lines 1–39 · score 0.52 · Deceased individuals, mortality risk, fitting, Chronic, Organ, BAG

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 · 837 lines · 32 KB · no license · 8 matches

  1. # BAG Associations
  2. # This script investigates the association of Brain Age Gap (BAG) with organ age gap, disease, mortality risk, proteins, and modifiable factors
  3. # Workflow:
  4. # 1. Associations of organ age gap on brain and cognition age gap
  5. # 2. Brain age gaps in chronic diseases and deceased individuals
  6. # 3. Brain age gaps predict mortality risk
  7. # 4. Proteomic analysis of brain age gaps
  8. # 5. Association of modifiable factors with brain age gaps
  9. # 6. Trajectories of modifiable factors with brain age gaps
  10. #=============================================================================
  11. #1. Associations of organ age gap on brain and cognition age gap
  12. #=============================================================================
  13. library(lm.beta)
  14. data_all<-read.csv("Data_Brain_Organ_predictions.csv")
  15. data_female<-subset(data_all, Sex == 0)
  16. data_male<-subset(data_all, Sex == 1)
  17. ######1.1 All population
  18. data_all$Sex<-factor(data_all$Sex)
  19. for (col in 2:7){
  20. data_all[,col]<-scale(data_all[,col])
  21. }
  22. Brain_total<- c()
  23. for (i in c(4:6)){
  24. fit<-lm(Brain_age_gap_resid~data_all[,i]+Sex+Age_attending_2,data=data_all)
  25. n_obs <- nobs(fit)
  26. Brain_total<- rbind(Brain_total, c(colnames(data_all)[i], "Brain_Total", coef(summary(fit))[2,], confint(fit)[2,c(1,2)], n_obs))
  27. }
  28. Brain_total <- data.frame(Brain_total)
  29. Cognition_total<- c()
  30. for (i in c(4:6)){
  31. fit<-lm(Cognition_age_gap_resid~data_all[,i]+Sex+Age_attending_2,data=data_all)
  32. n_obs <- nobs(fit)
  33. Cognition_total<- rbind(Cognition_total, c(colnames(data_all)[i], "Cognition_Total", coef(summary(fit))[2,], confint(fit)[2,c(1,2)], n_obs))
  34. }
  35. Cognition_total <- data.frame(Cognition_total)
  36. ######1.2 Female
  37. Brain_female <- lm(Brain_age_gap_resid~data_female[,i]+Age_attending_2,data=data_female)
  38. Cognition_female <-lm(Cognition_age_gap_resid~data_female[,i]+Age_attending_2,data=data_female)
  39. ######1.3 Male
  40. Brain_male <- lm(Brain_age_gap_resid~data_male[,i]+Age_attending_2,data=data_male)
  41. Cognition_male <- lm(Cognition_age_gap_resid~data_male[,i]+Age_attending_2,data=data_male)
  42. ##Merge results
  43. Brain<-c()
  44. Brain<-rbind(Brain,
  45. Brain_total,
  46. Brain_female,
  47. Brain_male
  48. )
  49. write.csv(Brain,file="Regression_Brain_age_model_healthy.csv",row.names=FALSE)
  50. Cognition<-c()
  51. Cognition<-rbind(Cognition,
  52. Cognition_total,
  53. Cognition_female,
  54. Cognition_male
  55. )
  56. write.csv(Cognition,file="Regression_Cognition_age_model_healthy.csv",row.names=FALSE)
  57. #=============================================================================
  58. #2.Brain age gaps in chronic diseases and deceased individuals
  59. #=============================================================================
  60. ######4.1 18 disease categories
  61. data_list <- list(
  62. list(data = dt1, response_var = "Anxiety_disorders", group_var = "Group1"),
  63. list(data = dt2, response_var = "Bipolar_disorder", group_var = "Group2"),
  64. list(data = dt3, response_var = "Cancer", group_var = "Group3"),
  65. list(data = dt4, response_var = "COPD", group_var = "Group4"),
  66. list(data = dt5, response_var = "Dementia_Parkinsonism", group_var = "Group5"),
  67. list(data = dt6, response_var = "Depression", group_var = "Group6"),
  68. list(data = dt7, response_var = "Diabetes", group_var = "Group7"),
  69. list(data = dt8, response_var = "Heart_failure", group_var = "Group8"),
  70. list(data = dt9, response_var = "Hypertension", group_var = "Group9"),
  71. list(data = dt10, response_var = "Liver_disease", group_var = "Group10"),
  72. list(data = dt11, response_var = "Ischaemic_HD", group_var = "Group11"),
  73. list(data = dt12, response_var = "Multiple_sclerosis", group_var = "Group12"),
  74. list(data = dt13, response_var = "Osteoarthritis", group_var = "Group13"),
  75. list(data = dt14, response_var = "Osteoporosis", group_var = "Group14"),
  76. list(data = dt15, response_var = "Renal_failure", group_var = "Group15"),
  77. list(data = dt16, response_var = "Respiratory_failure", group_var = "Group16"),
  78. list(data = dt17, response_var = "Schizophrenia", group_var = "Group17"),
  79. list(data = dt18, response_var = "Stroke", group_var = "Group18")
  80. )
  81. results <- list()
  82. for (item in data_list) {
  83. data <- item$data
  84. response_var <- item$response_var
  85. group_var <- item$group_var
  86. fit <- t.test(as.formula(paste(response_var, "~", group_var)), data = data)
  87. n_disease <- sum(data[[group_var]] == "disease")
  88. n_healthy <- sum(data[[group_var]] == "healthy")
  89. sd_disease <- sd(data[[response_var]][data[[group_var]] == "disease"], na.rm = TRUE)
  90. sd_healthy <- sd(data[[response_var]][data[[group_var]] == "healthy"], na.rm = TRUE)
  91. result <- c(
  92. response_var,
  93. fit$statistic,
  94. fit$p.value,
  95. fit$conf.int[1],
  96. fit$conf.int[2],
  97. fit$estimate[1],
  98. fit$estimate[2],
  99. n_disease,
  100. n_healthy,
  101. sd_disease,
  102. sd_healthy
  103. )
  104. results[[length(results) + 1]] <- result
  105. }
  106. results_df <- do.call(rbind, results)
  107. ##calculate Cohen's d
  108. data <- data.frame(results_df)
  109. calculate_cohens_d <- function(t_value, n1, n2) {
  110. d <- t_value * sqrt((n1 + n2) / (n1 * n2))
  111. return(d)
  112. }
  113. t_value <- data$t.value
  114. n1 <- data$N_Healthy
  115. n2 <- data$N_Disease
  116. t_value <- as.numeric(t_value)
  117. n1 <- as.numeric(n1)
  118. n2 <- as.numeric(n2)
  119. Cohens_d <- calculate_cohens_d(t_value, n1, n2)
  120. Cohens_d <- data.frame(Cohens_d)
  121. Results <- cbind(data, Cohens_d)
  122. write.csv(Results, "Results_brain_age_gap_single_disease.csv", row.names = FALSE)
  123. ######2.2 eight major system diseases
  124. data_list <- list(
  125. list(data = dt1, response_var = "Abdominal", group_var = "Group1"),
  126. list(data = dt2, response_var = "Cancer", group_var = "Group2"),
  127. list(data = dt3, response_var = "Cardiovascular", group_var = "Group3"),
  128. list(data = dt4, response_var = "Endocrine", group_var = "Group4"),
  129. list(data = dt5, response_var = "Mental", group_var = "Group5"),
  130. list(data = dt6, response_var = "Musculoskeletal", group_var = "Group6"),
  131. list(data = dt7, response_var = "Nervous", group_var = "Group7"),
  132. list(data = dt8, response_var = "Pulmonary", group_var = "Group8")
  133. )
  134. results <- list()
  135. for (item in data_list) {
  136. data <- item$data
  137. response_var <- item$response_var
  138. group_var <- item$group_var
  139. fit <- t.test(as.formula(paste(response_var, "~", group_var)), data = data)
  140. n_disease <- sum(data[[group_var]] == "disease")
  141. n_healthy <- sum(data[[group_var]] == "healthy")
  142. sd_disease <- sd(data[[response_var]][data[[group_var]] == "disease"], na.rm = TRUE)
  143. sd_healthy <- sd(data[[response_var]][data[[group_var]] == "healthy"], na.rm = TRUE)
  144. result <- c(
  145. response_var,
  146. fit$statistic,
  147. fit$p.value,
  148. fit$conf.int[1],
  149. fit$conf.int[2],
  150. fit$estimate[1],
  151. fit$estimate[2],
  152. n_disease,
  153. n_healthy,
  154. sd_disease,
  155. sd_healthy
  156. )
  157. results[[length(results) + 1]] <- result
  158. }
  159. results_df <- do.call(rbind, results)
  160. ##calculate Cohen's d
  161. data <- data.frame(results_df)
  162. calculate_cohens_d <- function(t_value, n1, n2) {
  163. d <- t_value * sqrt((n1 + n2) / (n1 * n2))
  164. return(d)
  165. }
  166. t_value <- data$t.value
  167. n1 <- data$N_Healthy
  168. n2 <- data$N_Disease
  169. t_value <- as.numeric(t_value)
  170. n1 <- as.numeric(n1)
  171. n2 <- as.numeric(n2)
  172. Cohens_d <- calculate_cohens_d(t_value, n1, n2)
  173. Cohens_d <- data.frame(Cohens_d)
  174. Results <- cbind(data, Cohens_d)
  175. write.csv(Results, "Results_brain_age_gap_system_disease.csv", row.names = FALSE)
  176. ######2.3 Deceased individuals
  177. data <-read.csv("Data_Brain_age_mortality.csv")
  178. results <- data.frame(Group = character(),
  179. Statistic = numeric(),
  180. P_Value = numeric(),
  181. Conf_Int_Lower = numeric(),
  182. Conf_Int_Upper = numeric(),
  183. Mean_Disease = numeric(),
  184. Mean_Healthy = numeric(),
  185. N_Disease = integer(),
  186. N_Healthy = integer(),
  187. SD_Disease = numeric(),
  188. SD_Healthy = numeric(),
  189. stringsAsFactors = FALSE)
  190. fit <- t.test(age_gap_resid ~ group, data = data)
  191. n_mortality <- sum(data$group == "mortality")
  192. n_healthy <- sum(data$group == "healthy")
  193. sd_mortality <- sd(data$group == "mortality", na.rm = TRUE)
  194. sd_healthy <- sd(data$group == "healthy", na.rm = TRUE)
  195. result <- c("Condition", fit$statistic, fit$p.value, fit$conf.int[1], fit$conf.int[2],
  196. fit$estimate[1], fit$estimate[2], n_mortality, n_healthy, sd_mortality, sd_healthy)
  197. results <- rbind(results, result)
  198. write.csv(results, "Results_brain_age_gap_mortality.csv", row.names = FALSE)
  199. #=============================================================================
  200. #3.Brain age gaps predict mortality risk
  201. #=============================================================================
  202. library(survival)
  203. data <-read.csv("Data_Brain_age_mortality.csv")
  204. for (col in 4:14){
  205. data[,col]<-scale(data[,col])
  206. }
  207. data$Townsend_index <-scale(data$Townsend_index)
  208. for (col in 15:37){
  209. data[,col]<-factor(data[,col])
  210. }
  211. ##model 0
  212. data0 <- data
  213. cox_model0 <- coxph(Surv(t_death, Death_status) ~ true_age+Sex, data = data0)
  214. summary_cox <- summary(cox_model0)
  215. coef_table <- summary_cox$coefficients
  216. coef_df <- as.data.frame(coef_table)
  217. hr <- exp(coef_table[, "coef"])
  218. conf_int <- exp(confint(cox_model0))
  219. coef_df$HR_lower_95CI <- conf_int[, 1]
  220. coef_df$HR_upper_95CI <- conf_int[, 2]
  221. total_sample <- nrow(data0)
  222. total_events <- sum(data0$Death_status)
  223. write.csv(coef_df, file = "Cox_age_gap_mortality_m0.csv", row.names = TRUE)
  224. ##model 1
  225. data1 <- data
  226. cox_model1 <- coxph(Surv(t_death, Death_status) ~ age_gap_resid+true_age+Sex, data = data1)
  227. summary_cox <- summary(cox_model1)
  228. coef_table <- summary_cox$coefficients
  229. coef_df <- as.data.frame(coef_table)
  230. hr <- exp(coef_table[, "coef"])
  231. conf_int <- exp(confint(cox_model1))
  232. coef_df$HR_lower_95CI <- conf_int[, 1]
  233. coef_df$HR_upper_95CI <- conf_int[, 2]
  234. used_data <- model.frame(cox_model1)
  235. actual_sample <- nrow(used_data)
  236. actual_events <- sum(used_data$Death_status)
  237. write.csv(coef_df, file = "Cox_age_gap_mortality_m1.csv", row.names = TRUE)
  238. ##model2
  239. data2 <- data[complete.cases(data[, c(19:37)]), ]
  240. cox_model2 <- coxph(Surv(t_death, Death_status) ~ age_gap_resid+true_age+Sex+Cancer_2+Diabetes_2+
  241. Dementia_2+Parkinsonism_2+Multiple_sclerosis_2+Hypertension_2+Ischaemic_HD_2+
  242. Heart_failure_2+Stroke_2+COPD_2+Respiratory_failure_2+Iiver_disease_2+
  243. Osteoarthritis_2+Osteoporosis_2+Renal_failure_2+Bipolar_disorder_2
  244. +Depression_2+Anxiety_disorders_2, data = data2)
  245. summary_cox <- summary(cox_model2)
  246. ##model3
  247. data3 <- data[complete.cases(data[, c(18:38)]), ]
  248. cox_model3 <- coxph(Surv(t_death, Death_status) ~ age_gap_resid+true_age+Sex+Cancer_2+Diabetes_2+
  249. Dementia_2+Parkinsonism_2+Multiple_sclerosis_2+Hypertension_2+Ischaemic_HD_2+
  250. Heart_failure_2+Stroke_2+COPD_2+Respiratory_failure_2+Iiver_disease_2+
  251. Osteoarthritis_2+Osteoporosis_2+Renal_failure_2+Bipolar_disorder_2
  252. +Depression_2+Anxiety_disorders_2+Townsend_index+Ethnicity, data = data3)
  253. summary_cox <- summary(cox_model3)
  254. ##model4
  255. data4 <- data[complete.cases(data[, c(6:38)]), ]
  256. cox_model4 <- coxph(Surv(t_death, Death_status) ~ age_gap_resid+true_age+Sex+Cancer_2+Diabetes_2+
  257. Dementia_2+Parkinsonism_2+Multiple_sclerosis_2+Hypertension_2+Ischaemic_HD_2+
  258. Heart_failure_2+Stroke_2+COPD_2+Respiratory_failure_2+Iiver_disease_2+
  259. Osteoarthritis_2+Osteoporosis_2+Renal_failure_2+Bipolar_disorder_2
  260. +Depression_2+Anxiety_disorders_2+Townsend_index+Ethnicity+
  261. Walkpace_2+Mean_SBP_2+Mean_Pulse_2+Carotid_IMT_2+Hand_strength_2+
  262. WHR_2+BodyFat_Whole_2+Trunk_fat_mass_2+Leg_fat_mass_2+Arm_predict_mass_2+
  263. Long_illness_2, data = data4)
  264. summary_cox <- summary(cox_model4)
  265. ##calculate C-index
  266. library(survcomp)
  267. cindex0 <- concordance.index(predict(cox_model0),
  268. surv.time = data0$t_death,
  269. surv.event = data0$Death_status)
  270. cindex1 <- concordance.index(predict(cox_model1),
  271. surv.time = data1$t_death,
  272. surv.event = data1$Death_status)
  273. cindex2 <- concordance.index(predict(cox_model2),
  274. surv.time = data2$t_death,
  275. surv.event = data2$Death_status)
  276. cindex3 <- concordance.index(predict(cox_model3),
  277. surv.time = data3$t_death,
  278. surv.event = data3$Death_status)
  279. cindex4 <- concordance.index(predict(cox_model4),
  280. surv.time = data4$t_death,
  281. surv.event = data4$Death_status)
  282. print(paste("C-index for model 0:", cindex0$c.index))
  283. print(paste("C-index for model 1:", cindex1$c.index))
  284. print(paste("C-index for model 2:", cindex2$c.index))
  285. print(paste("C-index for model 3:", cindex3$c.index))
  286. print(paste("C-index for model 4:", cindex4$c.index))
  287. #=============================================================================
  288. #4. Proteomic analysis of brain age gaps
  289. #=============================================================================
  290. ######4.1 Association of proteins with brain age gaps
  291. library(lm.beta)
  292. data<-read.csv("Data_Brain_age_Proteomics.csv")
  293. data$Sex<-factor(data$Sex)
  294. data$Ethnicity<-factor(data$Ethnicity)
  295. result<- c()
  296. for (i in 12:2934){
  297. fit<-lm(Brain_age_gap_resid~data[,i]+Age_attending_2+Sex+Townsend_index,data=data)
  298. fit.std <- lm.beta(fit)
  299. result<- rbind(result, c(colnames(data)[i], coef(summary(fit.std))[2,]))
  300. }
  301. result <- data.frame(result)
  302. write.csv(result,file="Regression_brain_age_proteomics.csv",row.names=FALSE)
  303. ######4.2 BAG related proteins predict dementia risk
  304. library(survival)
  305. df <-read.csv("Data_Proteomics_dementia.csv")
  306. df1 <- df[, c(1,3,4,12:17,19,20,22)]
  307. df2 <- df[, c("id", "ART3", "EGLN1", "IGF2R", "PLA2G15", "ADAMTSL2", "ADGRD1", "CDH2",
  308. "CRIP2", "ACP5", "AGER", "CXCL17", "IL18R1", "LAMP3", "SCGB1A1", "TNFRSF6B",
  309. "LILRA5", "ADM", "ANGPTL7", "CD36", "CPM", "FABP4", "GPD1", "IL6", "LEP",
  310. "SELE", "TIMP4", "APLP1", "BCAN", "CA14", "CDH3", "KLK6", "LRRN1", "LRTM2",
  311. "MOG", "NCAN", "NFASC", "NPTXR", "OMG", "OXT", "PGF", "PODXL2", "SEZ6L",
  312. "SFRP1", "SLITRK1", "WFIKKN2")]
  313. data <- merge(df1, df2, by = "id")
  314. for (col in 13:57){
  315. data[,col]<-scale(data[,col])
  316. }
  317. data$Age_attending_0 <-scale(data$Age_attending_0)
  318. data$Townsend_index <-scale(data$Townsend_index)
  319. data$Mean_SBP_0 <-scale(data$Mean_SBP_0)
  320. data$BMI_0 <-scale(data$BMI_0)
  321. data$Sex <-factor(data$Sex)
  322. for (col in 7:10){
  323. data[,col]<-factor(data[,col])
  324. }
  325. model_configs <- list(
  326. # model1
  327. list(
  328. name = "m1",
  329. adjust_vars = "+ Age_attending_0 + Sex + Townsend_index + Education_0 + Ethnicity",
  330. output_file = "Cox_Proteomics_dementia_m1.csv"
  331. ),
  332. # model2
  333. list(
  334. name = "m2",
  335. adjust_vars = "+ Age_attending_0 + Sex + Townsend_index + Education_0 + Ethnicity + Smoke_status_0 + Alcohol_frequency_0 + Mean_SBP_0 + BMI_0",
  336. output_file = "Cox_Proteomics_dementia_m2.csv"
  337. )
  338. )
  339. run_protein_cox <- function(data, model_config, protein_cols = 13:57) {
  340. results_list <- list()
  341. for (i in protein_cols) {
  342. protein_name <- colnames(data)[i]
  343. formula_str <- paste("Surv(t_Dementia, Dementia_status) ~ ", protein_name, model_config$adjust_vars)
  344. formula <- as.formula(formula_str)
  345. cox_model <- coxph(formula, data = data)
  346. summary_cox <- summary(cox_model)
  347. coef_table <- summary_cox$coefficients
  348. coef_df <- as.data.frame(coef_table)
  349. hr <- exp(coef_table[, "coef"])
  350. conf_int <- exp(confint(cox_model))
  351. coef_df$HR_lower_95CI <- conf_int[, 1]
  352. coef_df$HR_upper_95CI <- conf_int[, 2]
  353. coef_df <- coef_df[1, ]
  354. coef_df$N_event <- summary_cox$nevent
  355. coef_df$N_total <- summary_cox$n
  356. coef_df$Protein <- protein_name
  357. results_list[[i - 12]] <- coef_df # 保持原索引对应逻辑(i-12)
  358. }
  359. final_results <- do.call(rbind, results_list)
  360. final_results <- data.frame(final_results)
  361. write.csv(final_results, file = model_config$output_file, row.names = TRUE)
  362. return(final_results)
  363. }
  364. all_model_results <- list()
  365. for (config in model_configs) {
  366. model_result <- run_protein_cox(data, config)
  367. all_model_results[[config$name]] <- model_result
  368. }
  369. ######4.3 BAG related proteins predict mortality risk
  370. df <-read.csv("Data_Proteomics_mortality.csv")
  371. df1 <- df[, c(1,2,3,10:17,19:39)]
  372. df2 <- df[, c("id", "ART3", "EGLN1", "IGF2R", "PLA2G15", "ADAMTSL2", "ADGRD1", "CDH2",
  373. "CRIP2", "ACP5", "AGER", "CXCL17", "IL18R1", "LAMP3", "SCGB1A1", "TNFRSF6B",
  374. "LILRA5", "ADM", "ANGPTL7", "CD36", "CPM", "FABP4", "GPD1", "IL6", "LEP",
  375. "SELE", "TIMP4", "APLP1", "BCAN", "CA14", "CDH3", "KLK6", "LRRN1", "LRTM2",
  376. "MOG", "NCAN", "NFASC", "NPTXR", "OMG", "OXT", "PGF", "PODXL2", "SEZ6L",
  377. "SFRP1", "SLITRK1", "WFIKKN2")]
  378. data <- merge(df1, df2, by = "id")
  379. for (col in 33:77){
  380. data[,col]<-scale(data[,col])
  381. }
  382. data$Age_attending_0 <-scale(data$Age_attending_0)
  383. data$Townsend_index <-scale(data$Townsend_index)
  384. data$Mean_SBP_0 <-scale(data$Mean_SBP_0)
  385. data$BMI_0 <-scale(data$BMI_0)
  386. data$Sex <-factor(data$Sex)
  387. for (col in 7:10){
  388. data[,col]<-factor(data[,col])
  389. }
  390. for (col in 13:32){
  391. data[,col]<-factor(data[,col])
  392. }
  393. model_configs <- list(
  394. # model1
  395. list(
  396. name = "m1",
  397. adjust_vars = "+ Age_attending_0 + Sex + Townsend_index + Education_0 + Ethnicity",
  398. output_file = "Cox_Proteomics_mortality_m1.csv"
  399. ),
  400. # model2
  401. list(
  402. name = "m2",
  403. adjust_vars = "+ Age_attending_0 + Sex + Townsend_index + Education_0 + Ethnicity + Smoke_status_0 + Alcohol_frequency_0 + Mean_SBP_0 + BMI_0",
  404. output_file = "Cox_Proteomics_mortality_m2.csv"
  405. ),
  406. # model3
  407. list(
  408. name = "m3",
  409. adjust_vars = "+ Age_attending_0 + Sex + Townsend_index + Education_0 + Ethnicity + Smoke_status_0 + Alcohol_frequency_0 + Mean_SBP_0 + BMI_0 + Cancer_0 + Diabetes_0 + Schizophrenia_0 + Bipolar_disorder_0 + Depression_0 + Anxiety_disorders_0 + Dementia_0 + Parkinsonism_0 + Multiple_sclerosis_0 + Hypertension_0 + Ischaemic_HD_0 + Heart_failure_0 + Stroke_0 + COPD_0 + Respiratory_failure_0 + Liver_disease_0 + Osteoarthritis_0 + Osteoporosis_0 + Renal_failure_0",
  410. output_file = "Cox_Proteomics_mortality_m3.csv"
  411. )
  412. )
  413. run_protein_mortality_cox <- function(data, model_config, protein_cols = 33:77) {
  414. results_list <- list()
  415. for (i in protein_cols) {
  416. protein_name <- colnames(data)[i]
  417. formula_str <- paste("Surv(t_Death, Death_status) ~ ", protein_name, model_config$adjust_vars)
  418. formula <- as.formula(formula_str)
  419. cox_model <- coxph(formula, data = data)
  420. summary_cox <- summary(cox_model)
  421. coef_table <- summary_cox$coefficients
  422. coef_df <- as.data.frame(coef_table)
  423. hr <- exp(coef_table[, "coef"])
  424. conf_int <- exp(confint(cox_model))
  425. coef_df$HR_lower_95CI <- conf_int[, 1]
  426. coef_df$HR_upper_95CI <- conf_int[, 2]
  427. coef_df <- coef_df[1, ]
  428. coef_df$N_event <- summary_cox$nevent
  429. coef_df$N_total <- summary_cox$n
  430. coef_df$Protein <- protein_name
  431. results_list[[i - 12]] <- coef_df
  432. }
  433. final_results <- do.call(rbind, results_list)
  434. final_results <- data.frame(final_results)
  435. write.csv(final_results, file = model_config$output_file, row.names = TRUE)
  436. return(final_results)
  437. }
  438. all_model_results <- list()
  439. for (config in model_configs) {
  440. model_result <- run_protein_mortality_cox(data, config)
  441. all_model_results[[config$name]] <- model_result
  442. }
  443. #=============================================================================
  444. #5.Association of modifiable factors with brain age gaps
  445. #=============================================================================
  446. ######5.1 All modifiable factors
  447. ######5.1.1 Total
  448. data<-read.csv("Data_Brain_age_modifiable_factors_total.csv")
  449. data$Sex<-factor(data$Sex)
  450. data$Ethnicity<-factor(data$Ethnicity)
  451. #Continuous variables
  452. result1<-c()
  453. for (i in 11:90){
  454. fit<-lm(Brain_age_gap_resid~data[,i]+Sex+Age_attending_2,data=data)
  455. fit.std <- lm.beta(fit)
  456. result1<-rbind(result1,
  457. c(colnames(data)[i], "0", coef(summary(fit.std))[2,]))
  458. }
  459. df1 <- data.frame(result1)
  460. #Categorical variables
  461. for (col in 91:167){
  462. data[,col]<-factor(data[,col])
  463. }
  464. result1 <- c()
  465. result2 <- c()
  466. for (i in 91:167) {
  467. fit <- lm(Brain_age_gap_resid~data[,i]+Sex+Age_attending_2,data=data)
  468. fit.std <- lm.beta(fit)
  469. for (j in 2:length(levels(data[, i]))) {
  470. coef_summary <- coef(summary(fit.std))[j, c(1:5)] # 获取系数、标准误和p值
  471. result1 <- rbind(result1, c(colnames(data)[i], coef_summary))
  472. result2 <- rbind(result2, levels(data[, i])[j])
  473. }
  474. }
  475. colnames(result2) <- "Levels"
  476. result <- cbind(result1, result2)
  477. df2 <- data.frame(result[,c(1,10,2,3,4,5,6)])
  478. Results <- rbind(df1, df2)
  479. write.csv(Results, file = "Regression_Brain_age_modifiable_factors_total.csv", row.names = FALSE)
  480. ######5.1.2 Female
  481. data_female<-subeset(data, Sex == 0)
  482. fit<-lm(Brain_age_gap_resid~data[,i]+Age_attending_2,data=data_female)
  483. ######5.1.3 Male
  484. data_male<-subeset(data, Sex == 1)
  485. fit<-lm(Brain_age_gap_resid~data[,i]+Age_attending_2,data=data_male)
  486. ######5.2 The top ten modifiable factors
  487. ######5.2.1 Total
  488. df_all<-read.csv("Data_Brain_age_Factors_group_total.csv")
  489. group_vars <- c("SBP_group_T2", "DBP_group_T2", "WHR_group_T2", "Arm_mass_group_T2",
  490. "Arm_fatfree_group_T2", "Leg_fatfree_group_T2", "Leg_fat_group_T2",
  491. "Body_fatfree_group_T2", "Beer_intake_group_T2", "Walkpace_group_T2")
  492. results <- data.frame(Group = character(),
  493. Statistic = numeric(),
  494. P_Value = numeric(),
  495. Conf_Int_Lower = numeric(),
  496. Conf_Int_Upper = numeric(),
  497. Mean_Normal = numeric(),
  498. Mean_Abnormal = numeric(),
  499. N_Normal = integer(),
  500. N_Abnormal = integer(),
  501. stringsAsFactors = FALSE)
  502. for (group_var in group_vars) {
  503. df_filtered <- df_all[complete.cases(df_all[[group_var]], df_all$Brain_age_gap_resid), ]
  504. fit <- t.test(Brain_age_gap_resid ~ df_filtered[[group_var]], data = df_filtered)
  505. n_normal <- sum(df_filtered[[group_var]] == "0", na.rm = TRUE)
  506. n_abnormal <- sum(df_filtered[[group_var]] == "1", na.rm = TRUE)
  507. result <- c(group_var, fit$statistic, fit$p.value, fit$conf.int[1], fit$conf.int[2],
  508. fit$estimate[1], fit$estimate[2], n_normal, n_abnormal)
  509. results <- rbind(results, result)
  510. }
  511. #Calculate Cohen's d
  512. calculate_cohens_d <- function(t_value, n1, n2) {
  513. d <- t_value / sqrt(n1 + n2)
  514. return(d)
  515. }
  516. t_value <- results$T_value
  517. n1 <- results$N_Normal
  518. n2 <- results$N_Abnormal
  519. t_value <- as.numeric(t_value)
  520. n1 <- as.numeric(n1)
  521. n2 <- as.numeric(n2)
  522. Cohens_d <- calculate_cohens_d(t_value, n1, n2)
  523. Cohens_d <- data.frame(Cohens_d)
  524. Results <- cbind(results, Cohens_d)
  525. write.csv(Results, "All_T-test_age_gap_factors.csv", row.names = FALSE)
  526. ######5.2.2 Female:same as the total population
  527. df_female<-read.csv("Data_Brain_age_Factors_group_female.csv")
  528. group_vars <- c("SBP_group_T2", "DBP_group_T2", "WHR_group_T2", "Heel_BMD_group_T2",
  529. "Walkpace_group_T2", "Red_wine_group_T2", "Coffee_group_T2",
  530. "Sun_group_T2", "Confide_group_T2", "Employment_group_T2")
  531. ######5.2.3 Male: same as the total population
  532. df_male<-read.csv("Data_Brain_age_Factors_group_male.csv")
  533. group_vars <- c("BMI_group_T2", "WHR_group_T2", "Leg_fat_group_T2", "Arm_fat_group_T2",
  534. "Body_fat_group_T2", "Trunk_fat_group_T2", "Leg_fat_per_group_T2",
  535. "Arm_fat_per_group_T2", "Body_fat_per_group_T2", "Trunk_fat_per_group_T2")
  536. ######5.3 Risk groups of modifiable factors
  537. ######5.3.1 Total
  538. data<-read.csv("Data_Brain_age_Risk_group_total.csv")
  539. data$Risk_group_T2<-factor(data$Risk_group_T2)
  540. fit<-lm(Brain_age_gap_resid~Risk_group_T2+Sex+Age_attending_2,data=data)
  541. coef_summary <- coef(summary(fit))[2:4, c(1:4)]
  542. result1 <- data.frame(coef_summary)
  543. result1$Group <- "Total"
  544. write.csv(result1, file = "Regression_Brain_age_risk_groups_total.csv", row.names = FALSE)
  545. ######5.3.2 Female
  546. data_female<-subeset(data, Sex == 0)
  547. fit<-lm(Brain_age_gap_resid~Risk_group_T2+Age_attending_2,data=data_female)
  548. ######5.3.3 Male
  549. data_male<-subeset(data, Sex == 1)
  550. fit<-lm(Brain_age_gap_resid~Risk_group_T2+Age_attending_2,data=data_male)
  551. #=============================================================================
  552. #6.Trajectories of modifiable factors with brain age gaps
  553. #=============================================================================
  554. ######6.1 Latent class growth analysis(LCGA)
  555. library("lcmm")
  556. library(ggplot2)
  557. library(dplyr)
  558. ######8.1.1 Total population: including SBP, DBP, WHR, we take SBP as an example
  559. ##SBP
  560. data_SBP<-read.csv("Data_SBP_healthy.csv")
  561. # basic model
  562. m1<-hlme(SBP~Time*Sex,subject='id',ng=1,data=data_SBP)
  563. summarytable(m1)
  564. #2 class
  565. m2a<-hlme(SBP~Time*Sex,mixture=~Time, subject='id',
  566. ng=2,data=data_SBP, B=m1)
  567. summary(m2a)
  568. postprob(m2a)
  569. summarytable(m2a)
  570. p2<- plot(m2a,
  571. which = "fit",
  572. var.time = "Time",
  573. ylab = "SBP (mmHg)",
  574. xlab = "Time (years)",
  575. lwd = 1.2,
  576. legend.loc = "top",
  577. cex = 0.75,
  578. cex.axis = 0.9,
  579. font.axis = 1,
  580. cex.lab = 1,
  581. font.lab = 2,
  582. xlim = c(2, 12),
  583. ylim = c(120, 180),
  584. mgp = c(1.8, 0.6, 0),
  585. main = " "
  586. )
  587. p2
  588. x<-m2a$pprob[,1:2]
  589. newdata<-merge(data_SBP,x,by="id")
  590. write.csv(newdata, file = "SBP_traj_long_healthy_2.csv", row.names = FALSE)
  591. #3 class
  592. m3a<-hlme(SBP~Time*Sex,mixture=~Time, subject='id',
  593. ng=3,data=data_SBP,B=m1)
  594. summary(m3a)
  595. postprob(m3a)
  596. summarytable(m3a)
  597. p3<- plot(m3a,
  598. which = "fit",
  599. var.time = "Time",
  600. ylab = "SBP (mmHg)",
  601. xlab = "Time (years)",
  602. lwd = 1.2,
  603. legend.loc = "top",
  604. cex = 0.75,
  605. cex.axis = 0.9,
  606. font.axis = 1,
  607. cex.lab = 1,
  608. font.lab = 2,
  609. xlim = c(2, 12),
  610. ylim = c(112, 205),
  611. mgp = c(1.8, 0.6, 0),
  612. main = " "
  613. )
  614. p3
  615. x<-m3a$pprob[,1:2]
  616. newdata<-merge(data_SBP,x,by="id")
  617. write.csv(newdata, file = "SBP_traj_long_healthy_3.csv", row.names = FALSE)
  618. #4 class
  619. m4a<-hlme(SBP~Time*Sex,mixture=~Time, subject='id',
  620. ng=4,data=data_SBP,B=m1)
  621. summary(m4a)
  622. postprob(m4a)
  623. summarytable(m4a)
  624. p4 <- plot(m4a,
  625. which = "fit",
  626. var.time = "Time",
  627. ylab = "",
  628. xlab = "",
  629. lwd = 1.2,
  630. legend.loc = "",
  631. cex = 0.75,
  632. cex.axis = 0.9,
  633. font.axis = 1,
  634. cex.lab = 1,
  635. font.lab = 2,
  636. xlim = c(2, 12),
  637. ylim = c(100, 190),
  638. mgp = c(1.8, 0.6, 0),
  639. main = " ",
  640. col = "blue",
  641. axes = FALSE
  642. )
  643. x<-m4a$pprob[,1:6]
  644. newdata<-merge(data_SBP,x,by= "id")
  645. write.csv(newdata, file = "SBP_traj_long_healthy_4.csv", row.names = FALSE)
  646. #5 class
  647. m5a<-hlme(SBP~Time*Sex,mixture=~Time, subject='id',
  648. ng=5,data=data_SBP,B=m1)
  649. summary(m5a)
  650. postprob(m5a)
  651. summarytable(m5a)
  652. p5<- plot(m5a,
  653. which = "fit",
  654. var.time = "Time",
  655. ylab = "SBP (mmHg)",
  656. xlab = "Time (years)",
  657. lwd = 1.2,
  658. legend.loc = "",
  659. cex = 0.75,
  660. cex.axis = 0.9,
  661. font.axis = 1,
  662. cex.lab = 1,
  663. font.lab = 2,
  664. xlim = c(2, 12),
  665. ylim = c(100, 200),
  666. mgp = c(1.8, 0.6, 0),
  667. main = " "
  668. )
  669. p5
  670. x<-m5a$pprob[,1:2]
  671. newdata<-merge(data_SBP,x,by="id")
  672. write.csv(newdata, file = "SBP_traj_long_healthy_5.csv", row.names = FALSE)
  673. ######6.1.2 Female: including WHR and the frequency of red wine intake, the method is the same as SBP
  674. ######6.1.3 Male: including BMI and leg fat mass, the method is the same as SBP
  675. ######6.2 Trajectory groups of modifiable factors with brain age gaps
  676. ######6.2.1 Total: taking SBP as an example
  677. ##SBP
  678. data<-read.csv("Brain_age_SBP_traj_wide_healthy.csv")
  679. data$Sex<-factor(data$Sex)
  680. data$Ethnicity<-factor(data$Ethnicity)
  681. data$Walkpace_2<-factor(data$Walkpace_2)
  682. for (col in 6:9){
  683. data[,col]<-factor(data[,col])
  684. }
  685. #model1
  686. result1 <- c()
  687. result2 <- c()
  688. result3 <- c()
  689. for (i in 6:9) {
  690. fit <- lm(Brain_age_gap_resid~data[,i]+Sex+Age_attending_2+Ethnicity+Townsend_index,data=data)
  691. for (j in 2:length(levels(data[, i]))) {
  692. coef_summary <- coef(summary(fit))[j, c(1:4)]
  693. result1 <- rbind(result1, c(colnames(data)[i], coef_summary))
  694. confint_values <- confint(fit)[j, c(1, 2)]
  695. result2 <- rbind(result2, c(colnames(data)[i], confint_values))
  696. result3 <- rbind(result3, levels(data[, i])[j])
  697. }
  698. }
  699. colnames(result3) <- "Levels"
  700. result <- cbind(result1, result2, result3)
  701. m1 <- data.frame(result[,c(1,9,2,7,8,3,4,5)])
  702. m1$Model <- "model1"
  703. #model2
  704. result1 <- c()
  705. result2 <- c()
  706. result3 <- c()
  707. for (i in 6:9) {
  708. fit <- lm(Brain_age_gap_resid~data[,i]+Sex+Age_attending_2+Ethnicity+Townsend_index+Walkpace_2+
  709. Leg_fat_percentage_2+WHR_2+BeerIntake_Weekly_2,data=data)
  710. for (j in 2:length(levels(data[, i]))) {
  711. coef_summary <- coef(summary(fit))[j, c(1:4)]
  712. result1 <- rbind(result1, c(colnames(data)[i], coef_summary))
  713. confint_values <- confint(fit)[j, c(1, 2)]
  714. result2 <- rbind(result2, c(colnames(data)[i], confint_values))
  715. result3 <- rbind(result3, levels(data[, i])[j])
  716. }
  717. }
  718. colnames(result3) <- "Levels"
  719. result <- cbind(result1, result2, result3)
  720. m2 <- data.frame(result[,c(1,9,2,7,8,3,4,5)])
  721. m2$Model <- "model2"
  722. Results <- rbind(m1, m2)
  723. write.csv(Results, file = "Regression_Brain_age_SBP_traj_total.csv", row.names = FALSE)
  724. ##DBP
  725. m1 <- lm(Brain_age_gap_resid~data[,i]+Sex+Age_attending_2+Ethnicity+Townsend_index,data=data)
  726. m2 <- lm(Brain_age_gap_resid~data[,i]+Sex+Age_attending_2+Ethnicity+Townsend_index+Walkpace_2+Leg_fat_percentage_2+WHR_2+BeerIntake_Weekly_2,data=data)
  727. ##WHR
  728. m1 <- lm(Brain_age_gap_resid~data[,i]+Sex+Age_attending_2+Ethnicity+Townsend_index,data=data)
  729. m2 <- lm(Brain_age_gap_resid~data[,i]+Sex+Age_attending_2+Ethnicity+Townsend_index+Walkpace_2+Leg_fat_percentage_2+Mean_DBP_2+BeerIntake_Weekly_2,data=data)
  730. ######6.2.2 Female
  731. ##WHR
  732. m1 <- lm(Brain_age_gap_resid~data[,i]+Age_attending_2+Ethnicity+Townsend_index,data=data)
  733. m2 <- lm(Brain_age_gap_resid~data[,i]+Age_attending_2+Ethnicity+Townsend_index+Walkpace_2+Mean_DBP_2+RedWineIntake_Weekly_2,data=data)
  734. ##Red Wine
  735. m1 <-lm(Brain_age_gap_resid~data[,i]+Age_attending_2+Ethnicity+Townsend_index,data=data)
  736. m2 <-lm(Brain_age_gap_resid~data[,i]+Age_attending_2+Ethnicity+Townsend_index+Walkpace_2+Mean_DBP_2+WHR_2,data=data)
  737. ######6.2.3 Male
  738. ##BMI
  739. m1 <- lm(Brain_age_gap_resid~data[,i]+Age_attending_2+Ethnicity+Townsend_index,data=data)
  740. m2 <- lm(Brain_age_gap_resid~data[,i]+Age_attending_2+Ethnicity+Townsend_index+Leg_fat_mass_2+Mean_SBP_2+BeerIntake_Weekly_2,data=data)
  741. ##Leg fat mass
  742. m1 <- lm(Brain_age_gap_resid~data[,i]+Age_attending_2+Ethnicity+Townsend_index,data=data)
  743. m2 <- lm(Brain_age_gap_resid~data[,i]+Age_attending_2+Ethnicity+Townsend_index+BMI_2+Mean_SBP_2+BeerIntake_Weekly_2,data=data)

BAG_associations_analysis.R at commit ad082d1, no license · at the source

Overview

Authors: Yuanyuan Fang1,2, Wenxi Luo3, Hao Huang1,2, Lusen Ran1,2, Yuqin He1,2, Chang Cheng1,2, Yao Yao1,2, Yuxiang Hou4, Haibo Zheng4, Dengji Pan1,2, Shabei Xu1,2, Xiang Luo1,2, Tingting Qin5, Xingjie Hao6, Feng Lu4, Wei Wang1,2, Minghuan Wang1,2
  1. Department of Neurology, Tongji Hospital, Tongji Medical College, Huazhong University of Science and Technology, Wuhan 430030, China
  2. Hubei Key Laboratory of Neural Injury and Functional Reconstruction, Huazhong University of Science and Technology, Wuhan 430030, China
  3. College of Life Science and Technology, Huazhong University of Science and Technology, Wuhan 430030, China
  4. School of Computer Science and Technology, National Engineering Research Center for Big Data Technology and System, Services Computing Technology and System Lab, Cluster and Grid Computing Lab, Huazhong University of Science and Technology, Wuhan 430030, China
  5. Clinical Research Center, Tongji Hospital, Tongji Medical College, Huazhong University of Science and Technology, Wuhan 430030, China
  6. Department of Epidemiology and Biostatistics, Ministry of Education Key Laboratory of Environment and Health, School of Public Health, Tongji Medical College, Huazhong University of Science and Technology, Wuhan 430030, China
Dates: received 24 June 2025; accepted 4 March 2026; published online 27 April 2026; in print 5 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1073/pnas.2516601123 · PMID 42044335 · PMCID PMC13142974 · OpenAlex W7156218534
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: structural MRI / diffusion (modality), human (organism), clinical / translational (subfield)
Methods: Statistics, Smoothing, state filtering, decompositions, Machine learning, Connectivity
Keywords: brain age gap, glymphatic system, DTI-ALPS index, aggressive blood control, sex-stratified differences
MeSH: Aging*, Brain*, Glymphatic System*, Aged, Biomarkers, Diffusion Tensor Imaging, Female, Humans, Male, Middle Aged, UK Biobank (* major topic)
Topic: Cerebrospinal fluid and hydrocephalus (Cellular and Molecular Neuroscience, Neuroscience), according to OpenAlex
Funding: United States Department of Defense (U01 AG024904, W81XWH, W81XWH-12-2, W81XWH-12, W81XWH1220012, AG024904); National Natural Science Foundation of China (U01 AG024904, W81XWH-12-2-0012); China Postdoctoral Science Foundation (2024M751021); Natural Science Foundation of Hubei Province; National Institutes of Health (3u01ag024904-10s2, W81XWH, W81XWH-12-2-0012, AG024904)
Citations: cited by 1 paper (Europe PMC); 77 references in the paper

Abstract

The focus of this study is to investigate the role of diffusion tensor imaging along the perivascular space (DTI-ALPS) index in brain aging. To address this, we first examined the association of DTI-ALPS with aging hallmarks among 40,488 UK Biobank (UKB) participants. Next, we developed normative brain age models incorporating the DTI-ALPS index from 12,401 healthy UKB adults and validated in UKB-ADNI and UKB-TALENT datasets. Finally, we explored the relationship between brain age gap (BAG) with peripheral organ function, chronic diseases, proteomics, and genetics, while identifying modifiable factors in a longitudinal cohort. The findings revealed that DTI-ALPS index correlated with chronological age, telomere length, brain structure, and cognition. A brain age model integrating the DTI-ALPS index achieved good accuracy in the UKB (r = 0.756) and replicated well in two independent datasets (UKB-ADNI: r = 0.766; UKB-TALENT: r = 0.724), with choroid plexus volume emerging as an additional contributor. Musculoskeletal health was a key driver for brain aging in females, while pulmonary metrics prevailed in males. Neurodegenerative and metabolic disorders increased BAGs, imparting increased mortality risk. Protein-wide and genome-wide analysis identified 154 BAG-related proteins and 11 loci. Modifiable factors, particularly systolic blood pressure below 120 mmHg, were strongly associated with reduced BAGs. Overall, the DTI-ALPS index is a promising brain aging biomarker, offering insights into links between brain and peripheral health, and highlighting sex-stratified therapeutic strategies. Aggressive blood pressure control may mitigate brain aging and promote long-term brain health.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 17 matches between paragraphs and lines of code.

Lwxixixi/Brain-Aging

License: none: the authors keep all their rights
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Commit: ad082d1bbae62ca6420bc8f3ea2434cb4917f219, 25 January 2026
Languages: Python (7), R (5), Shell (3)
Size: 16 files, 15 scripts
Software Heritage: not archived
Found in: “Data, Materials, and Software Availability”
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: pandas (7 files), NumPy (6 files), Matplotlib (4 files), scikit-learn (4 files), ggplot2 (3 files), tidyverse (3 files), XGBoost (3 files), SHAP (2 files), ComplexHeatmap (1 file), data.table (1 file), ggpubr (1 file), LightGBM (1 file), pheatmap (1 file), pROC (1 file), SciPy (1 file), seaborn (1 file), survival (1 file)
Availability: 1 check, the latest on 30 September 2026: the link answers
  • 30 September 2026: the link answers
16 files

The paper's code and data availability statement is in the Data section.

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;
  • 15 scripts, each with its path and the digest of its content;
  • 17 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • 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.

Data, Materials, and Software Availability

Data for this study were sourced from publicly available datasets, including UK Biobank (https://www.ukbiobank.ac.uk/) (72) and ADNI (https://adni.loni.usc.edu/) (73). Additionally, we utilized an in-house TALENT dataset (ChiCTR1900027225), which is accessible via the following link: https://www.chictr.org.cn/ (74). No accession codes are needed to access these data, and the authors do not hold any special access privileges to the data from these databases beyond what is available to other researchers. All data are included in the manuscript and/or supporting information. Python software is available from https://github.com/Python (75), and R software is available from https://www.r-project.org/ (76). The code used for data processing and core analysis has been made publicly available at https://github.com/Lwxixixi/Brain-Aging.git (77).

Reproduced under the paper's license (CC BY), from the paper cited above.

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, 30 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 17 authors, 5 keywords, 11 MeSH terms, 5 funders, 70 references.

Cite

This paper

Fang, Y., Luo, W., Huang, H., Ran, L., He, Y., Cheng, C., Yao, Y., Hou, Y., Zheng, H., Pan, D., Xu, S., Luo, X., Qin, T., Hao, X., Lu, F., Wang, W., & Wang, M. (2026). Unveiling the glymphatic system's role in brain aging: A comprehensive biomarker and modifiable intervention target. Proceedings of the National Academy of Sciences of the United States of America, 123(18), e2516601123. https://doi.org/10.1073/pnas.2516601123

BibTeX

@article{fang2026unveiling,
author = {Fang, Yuanyuan and Luo, Wenxi and Huang, Hao and Ran, Lusen and He, Yuqin and Cheng, Chang and Yao, Yao and Hou, Yuxiang and Zheng, Haibo and Pan, Dengji and Xu, Shabei and Luo, Xiang and Qin, Tingting and Hao, Xingjie and Lu, Feng and Wang, Wei and Wang, Minghuan},
title = {{Unveiling the glymphatic system's role in brain aging: A comprehensive biomarker and modifiable intervention target}},
journal = {Proceedings of the National Academy of Sciences of the United States of America},
year = {2026},
month = apr,
volume = {123},
number = {18},
pages = {e2516601123},
publisher = {National Academy of Sciences},
issn = {0027-8424},
doi = {10.1073/pnas.2516601123},
url = {https://doi.org/10.1073/pnas.2516601123},
pmid = {42044335},
pmcid = {PMC13142974}
}

RIS

TY - JOUR
AU - Fang, Yuanyuan
AU - Luo, Wenxi
AU - Huang, Hao
AU - Ran, Lusen
AU - He, Yuqin
AU - Cheng, Chang
AU - Yao, Yao
AU - Hou, Yuxiang
AU - Zheng, Haibo
AU - Pan, Dengji
AU - Xu, Shabei
AU - Luo, Xiang
AU - Qin, Tingting
AU - Hao, Xingjie
AU - Lu, Feng
AU - Wang, Wei
AU - Wang, Minghuan
TI - Unveiling the glymphatic system's role in brain aging: A comprehensive biomarker and modifiable intervention target
T2 - Proceedings of the National Academy of Sciences of the United States of America
J2 - Proc Natl Acad Sci U S A
PY - 2026
DA - 2026/04/27
VL - 123
IS - 18
SP - e2516601123
SN - 0027-8424
PB - National Academy of Sciences
DO - 10.1073/pnas.2516601123
UR - https://doi.org/10.1073/pnas.2516601123
LA - en
ER -

CSL-JSON

{
"id": "10.1073/pnas.2516601123",
"type": "article-journal",
"title": "Unveiling the glymphatic system's role in brain aging: A comprehensive biomarker and modifiable intervention target",
"container-title": "Proceedings of the National Academy of Sciences of the United States of America",
"author": [
{
"family": "Fang",
"given": "Yuanyuan"
},
{
"family": "Luo",
"given": "Wenxi"
},
{
"family": "Huang",
"given": "Hao"
},
{
"family": "Ran",
"given": "Lusen"
},
{
"family": "He",
"given": "Yuqin"
},
{
"family": "Cheng",
"given": "Chang"
},
{
"family": "Yao",
"given": "Yao"
},
{
"family": "Hou",
"given": "Yuxiang"
},
{
"family": "Zheng",
"given": "Haibo"
},
{
"family": "Pan",
"given": "Dengji"
},
{
"family": "Xu",
"given": "Shabei"
},
{
"family": "Luo",
"given": "Xiang"
},
{
"family": "Qin",
"given": "Tingting"
},
{
"family": "Hao",
"given": "Xingjie"
},
{
"family": "Lu",
"given": "Feng"
},
{
"family": "Wang",
"given": "Wei"
},
{
"family": "Wang",
"given": "Minghuan"
}
],
"container-title-short": "Proc Natl Acad Sci U S A",
"volume": "123",
"issue": "18",
"page": "e2516601123",
"DOI": "10.1073/pnas.2516601123",
"PMID": "42044335",
"PMCID": "PMC13142974",
"ISSN": "0027-8424",
"publisher": "National Academy of Sciences",
"URL": "https://doi.org/10.1073/pnas.2516601123",
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
27
]
]
}
}

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/s42003-026-10957-8 [code]
Brain defence by the extracellular matrix protein Cochlin.
Journal: Communications biology
In common: survival, SHAP, XGBoost, 12 other tools
[2] doi:10.1093/bioinformatics/btag592 [code]
Network-based stratification of allele-specific expression reveals patient subgroups in Huntington's disease.
Journal: Bioinformatics (Oxford, England)
In common: pROC, survival, ComplexHeatmap, 11 other tools
[3] doi:10.3390/ijms27156925 [code]
XGBoost-SHAP Interpretable Modeling Identifies and Validates an Eight-Gene Biomarker for Hepatic Encephalopathy Risk Prediction in Cirrhosis.
Journal: International journal of molecular sciences
In common: LightGBM, pROC, survival, 6 other tools
[4] doi:10.1016/j.xcrm.2026.102766 [code]
A longitudinal single-cell and spatial multiomic atlas of pediatric high-grade glioma.
Journal: Cell reports. Medicine
In common: pROC, ComplexHeatmap, pheatmap, 10 other tools
[5] doi:10.1016/j.nicl.2026.104012 [code]
Structural-functional multilayer brain network properties and outcome of combined repetitive transcranial magnetic stimulation and psychotherapy for obsessive-compulsive disorder.
Journal: NeuroImage. Clinical
In common: survival, SHAP, XGBoost, 9 other tools, structural MRI / diffusion
[6] doi:10.1186/s13073-026-01704-z [code]
Gene expression profiling enables refined parcellation of cortical layers in the heterogeneous human cerebral cortex.
Journal: Genome medicine
In common: XGBoost, ComplexHeatmap, pheatmap, 10 other tools
[7] doi:10.1016/j.isci.2026.115657 [code]
Integration of machine learning to develop a disulfidptosis model for predicting glioma prognosis, immunotherapy response, and drug.
Journal: iScience
In common: pROC, survival, ComplexHeatmap, 7 other tools, clinical / translational
[8] doi:10.1371/journal.pmed.1004860 [code]
Brain aging patterns among nine neurological disorders: A case-control study.
Journal: PLoS medicine
In common: SHAP, XGBoost, scikit-learn, 3 other tools, structural MRI / diffusion, 5 references
[9] doi:10.1038/s41467-026-76837-1 [code]
Drug screen and machine learning predict neuroprotective agents in a preclinical human model of childhood dementia.
Journal: Nature communications
In common: SHAP, XGBoost, ComplexHeatmap, 9 other tools
[10] doi:10.1093/neuonc/noag128 [code]
Spatially-resolved single-cell imaging of melanoma brain metastases identifies localized immune patterns predictive of immune checkpoint blockade response.
Journal: Neuro-oncology
In common: pROC, survival, ComplexHeatmap, 7 other tools, clinical / translational

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.