OSCR

Age-Related Differences in Resting-State Functional Connectivity Predict Specific Patterns of Speech Disfluency.

Code ↔ Paper

3 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 3 matches
  1. [1] § METHODS › Predicting Disfluency From Age, EF, and Network Segregation ↔ Analysis Files/RSFC_stats_analysis_OSF.Rmd, lines 1130–1157 · score 0.57 · Johnson Neyman, simple slopes, intervals, interactively, predicted, Education
  2. [2] § METHODS › Participant Demographics ↔ Analysis Files/RSFC_stats_analysis_OSF.Rmd, lines 120–170 · score 0.55 · Cook, distance, threshold, outliers, MMSE, MoCA
  3. [3] § RESULTS › Network Segregation Predicts Disfluency ↔ Analysis Files/RSFC_stats_analysis_OSF.Rmd, lines 1130–1157 · score 0.52 · Johnson Neyman, simple slopes, DMN segregation, younger, interaction, older

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 Markdown · 1,813 lines · 56 KB · no license · 3 matches

  1. ---
  2. title: "RSFC_stats_analysis"
  3. output: html_document
  4. date: "2025-04-25"
  5. ---
  6. ```{r load libraries}
  7. library ("readr")
  8. library("tidyverse")
  9. library("ggplot2")
  10. library("dplyr")
  11. library("broom")
  12. library("knitr")
  13. library("psych")
  14. library("kableExtra")
  15. ```
  16. This script runs the regression and mediation analysis for RSFC data for the DMN, MD, and Language networks and the Speech disfluency data for a dataset comprising thress cohorts "PND", "MP", and "PND2".
  17. Master_data_updated.csv contains all behavioral data including Fluency (for tasks "Speech" and "Where"), Stroop, moca/mmse, etc.
  18. All rsfc files contain subject measures of resting state functional connectivity: segregation, within, and between network connectivity
  19. Note on "discourse type" aka speech elcitation task:
  20. For MP and PND2, this script calculates averages collapsed across "Speech" and "Where" (Open-ended prompt and "Frog Where Are You?" respectively)
  21. ```{r load data}
  22. bhv_data <- read_csv(
  23. "master_data_updated.csv",
  24. col_types = cols(sex = col_character())
  25. )
  26. rsfc_data_PND <- read_csv("PND_subject_measures.csv")
  27. rsfc_data_MP <- read_csv("MP_subject_measures.csv")
  28. rsfc_data_PND2 <- read_csv("PND2_subject_measures.csv")
  29. #view(bhv_data)
  30. #view(rsfc_data_PND)
  31. #view(rsfc_data_MP)
  32. #view(rsfc_data_PND2)
  33. ```
  34. #Data Wrangling Steps
  35. Here we are collapsing Where and Speech for MP and PND2, merging the Speech data with the RSFC data, and getting a count of the sample before and after exclusion criteria
  36. ```{r clean behavioral data}
  37. #Collapse Where and Speech data for MP and PND2
  38. #Define disfluency columns to average
  39. cols_to_average <- c(
  40. "mor_words", "perc_prolongation", "perc_wwr", "perc_total_repetitions", "perc_mono_wwr",
  41. "perc_phrase_repetitions", "perc_word_revisions", "perc_phrase_revisions", "perc_total_revisions",
  42. "perc_filled_pauses", "perc_pauses", "perc_typical_disfluencies", "perc_stutter_disfluencies",
  43. "perc_total_disfluencies", "freq_types", "freq_tokens", "freq_ttr", "total_trad_fps",
  44. "total_fillers", "percentage_fillers", "percentage_trad_fps", "duration", "speech_rate"
  45. )
  46. #Collapse row pairs for MP
  47. collapsed_MP <- bhv_data %>%
  48. filter(project == "MP") %>%
  49. group_by(subject) %>%
  50. summarise(across(all_of(cols_to_average), mean, na.rm = TRUE), .groups = "drop") %>%
  51. left_join(
  52. bhv_data %>% filter(project == "MP") %>% group_by(subject) %>% slice(1) %>%
  53. select(-all_of(cols_to_average), -discourse_type),
  54. by = "subject"
  55. ) %>%
  56. mutate(discourse_type = "BOTH") %>% #change discourse type label
  57. relocate(project)
  58. #Collapse row pairs for PND2
  59. collapsed_PND2 <- bhv_data %>%
  60. filter(project == "PND2") %>%
  61. group_by(subject) %>%
  62. summarise(across(all_of(cols_to_average), mean, na.rm = TRUE), .groups = "drop") %>%
  63. left_join(
  64. bhv_data %>% filter(project == "PND2") %>% group_by(subject) %>% slice(1) %>%
  65. select(-all_of(cols_to_average), -discourse_type),
  66. by = "subject"
  67. ) %>%
  68. mutate(discourse_type = "BOTH") %>% #change discourse type label
  69. relocate(project)
  70. #Keep PND
  71. PND_unchanged <- bhv_data %>%
  72. filter(project == "PND")
  73. #Bind all three dataframes
  74. final_bhv_df <- bind_rows(PND_unchanged, collapsed_MP, collapsed_PND2)
  75. View(final_bhv_df)
  76. ```
  77. ```{r Merge Behavioral data w RSFC data}
  78. #Merge all Fluency data with RSFC data
  79. rsfc_data_PND <- rsfc_data_PND %>%
  80. rename(subject = Subject_ID) %>%
  81. mutate(project = "PND")
  82. rsfc_data_MP <- rsfc_data_MP %>%
  83. rename(subject = Subject_ID) %>%
  84. mutate(project = "MP")
  85. rsfc_data_PND2 <- rsfc_data_PND2 %>%
  86. rename(subject = Subject_ID) %>%
  87. mutate(project = "PND2")
  88. #Combine all RSFC datasets
  89. rsfc_data_all <- bind_rows(rsfc_data_PND, rsfc_data_MP, rsfc_data_PND2)
  90. #Merge RSFC with behavioral data
  91. merged_initial <- final_bhv_df %>%
  92. left_join(rsfc_data_all, by = c("subject", "project"))
  93. # Get initial sample size BEFORE exclusions
  94. initial_n <- nrow(merged_initial)
  95. cat("Initial sample size (before exclusions):", initial_n, "\n")
  96. view(merged_initial)
  97. range_age <- range(merged_initial$age, na.rm = TRUE)
  98. cat("Youngest participant age:", range_age[1], "\n")
  99. cat("Oldest participant age:", range_age[2], "\n")
  100. ```
  101. ```{r Apply Exclusion criteria}
  102. # Exclude based on moca and mmse
  103. excluded_cog <- merged_initial %>%
  104. filter((!is.na(mmse) & mmse < 24) | (!is.na(moca_score) & moca_score < 26))
  105. tmp_step1 <- merged_initial %>%
  106. filter(is.na(mmse) | mmse >= 24) %>%
  107. filter(is.na(moca_score) | moca_score >= 26)
  108. # Exclude based on missing key variables
  109. key_vars <- c("stroop_effect", "perc_total_disfluencies",
  110. "Lang_LH_within", "DMN_within", "MD_within",
  111. "Lang_to_DMN", "Lang_to_MD", "DMN_to_MD")
  112. excluded_missing <- tmp_step1 %>%
  113. filter(if_any(all_of(key_vars), is.na))
  114. tmp_step2 <- tmp_step1 %>%
  115. filter(if_all(all_of(key_vars), ~ !is.na(.)))
  116. # Exclude based on Cook’s Distance
  117. model_cook <- lm(perc_total_disfluencies ~ age + education, data = tmp_step2)
  118. cooks_d <- cooks.distance(model_cook)
  119. threshold <- 4 / nrow(tmp_step2)
  120. excluded_outliers <- tmp_step2[which(cooks_d > threshold), ]
  121. merged_data <- tmp_step2[which(cooks_d <= threshold), ]
  122. # Summary of Exclusions
  123. cat("Initial sample size:", initial_n, "\n")
  124. cat("Excluded for cognitive criteria:", nrow(excluded_cog), "\n")
  125. cat("Excluded for missing key variables:", nrow(excluded_missing), "\n")
  126. cat("Excluded as outliers based on Cook’s Distance:", nrow(excluded_outliers), "\n")
  127. cat("Final analytic sample:", nrow(merged_data), "\n\n")
  128. # Use Participant IDs to see who was excluded and why
  129. #excluded_cog %>%
  130. #select(subject, project) %>%
  131. #print(n = Inf)
  132. #excluded_missing %>%
  133. #select(subject, project) %>%
  134. #print(n = Inf)
  135. #excluded_outliers %>%
  136. #select(subject, project) %>%
  137. #print(n = Inf)
  138. view(merged_data)
  139. ```
  140. #Quality Check data distrubutions
  141. ```{r QC key variables}
  142. # Select key numeric variables for QC
  143. qc_vars <- c("age", "education", "stroop_effect",
  144. "perc_total_disfluencies", "perc_total_repetitions",
  145. "perc_filled_pauses", "perc_pauses", "perc_prolongation",
  146. "perc_total_revisions")
  147. # Run descriptive statistics (includes skew, kurtosis)
  148. describe(merged_data[qc_vars])
  149. ```
  150. ```{r QC plots}
  151. qc_vars <- c(
  152. "age",
  153. "education",
  154. "stroop_effect",
  155. "perc_total_disfluencies",
  156. "perc_total_repetitions",
  157. "perc_filled_pauses",
  158. "perc_pauses",
  159. "perc_prolangation",
  160. "perc_total_revisions"
  161. )
  162. # Loop through variables
  163. for (var in qc_vars) {
  164. data_vec <- merged_data[[var]]
  165. # Skip non-numeric just in case
  166. if (is.numeric(data_vec)) {
  167. # Set up side-by-side plots
  168. par(mfrow = c(1, 2))
  169. # Histogram
  170. hist(data_vec,
  171. main = paste("Histogram of", var),
  172. xlab = var,
  173. col = "lightgray",
  174. border = "white")
  175. # Q-Q plot
  176. qqnorm(data_vec, main = paste("Q-Q Plot of", var))
  177. qqline(data_vec, col = "red", lwd = 2)
  178. # Pause between variables to review each set
  179. readline(prompt = paste("Press [Enter] to continue to next variable:", var))
  180. }
  181. }
  182. # Reset plotting layout back to default
  183. par(mfrow = c(1, 1))
  184. ```
  185. #Get Descriptives
  186. ```{r Desciptives}
  187. merged_data %>%
  188. summarise(
  189. N = n(),
  190. mean_age = mean(age, na.rm = TRUE),
  191. sd_age = sd(age, na.rm = TRUE),
  192. min_age = min(age, na.rm = TRUE),
  193. max_age = max(age, na.rm = TRUE),
  194. n_female = sum(sex == "F", na.rm = TRUE),
  195. mean_education = mean(education, na.rm = TRUE),
  196. min_edu = min(education, na.rm = TRUE),
  197. max_edu = max(education, na.rm = TRUE),
  198. sd_education = sd(education, na.rm = TRUE)
  199. )
  200. ```
  201. #Get cog/ling battery performance
  202. Note that here we are calculating means only for mmse, moca, stroop interference effect, forward digit span, backward digit span, pitt_acc (reading span accuracy), and pitt_pu (reading span partial unit score), and VF semantic category total tokens. Descriptives for the other tasks e.g., WAISS, speed of processing, etc. were calculated in an additional .rmd called RSFC_cog_battery_means.rmd.
  203. ```{r cognitive performance means}
  204. cog_vars <- c(
  205. "mmse", "moca_score", "stroop_effect", "forward_digit", "backward_digit",
  206. "pitt_acc", "pitt_pu", "phon_total", "sem_total")
  207. #summary table for mean, SD, and age beta
  208. summary_stats <- map_dfr(cog_vars, function(var) {
  209. this_data <- merged_data[[var]]
  210. model <- lm(reformulate("age", response = var), data = merged_data)
  211. tibble(
  212. variable = var,
  213. mean = mean(this_data, na.rm = TRUE),
  214. sd = sd(this_data, na.rm = TRUE),
  215. min = min(this_data, na.rm = TRUE),
  216. max = max(this_data, na.rm = TRUE),
  217. beta_age = coef(model)["age"]
  218. )
  219. })
  220. summary_stats
  221. ```
  222. #Start of LM analyses
  223. He we begin the LM analyses. We ran seperate models to test if Age, EF, and all RSFC measures predicted any of the 6 disfluency subtypes.
  224. We started first with simple Age effects for disfluency, RSFC, and EF (Stroop) performance.
  225. ## Age effects
  226. ```{r Age effects for disfluency}
  227. #first make sure 'project' and is a factor to have it as a covariate
  228. merged_data$project <- factor(merged_data$project)
  229. disfluency_vars <- c(
  230. "perc_total_disfluencies",
  231. "perc_total_repetitions",
  232. "perc_filled_pauses",
  233. "perc_pauses",
  234. "perc_total_revisions",
  235. "perc_prolongation"
  236. )
  237. age_effects_disfluency <- data.frame()
  238. for (var in disfluency_vars) {
  239. # Fit the model controlling for age education, and project
  240. frm <- as.formula(paste(var, "~ age + education + project"))
  241. model_disfluency <- lm(frm, data = merged_data)
  242. #Get age coefficient and CI
  243. s <- summary(model_disfluency)
  244. age_coef <- coef(s)["age", ]
  245. age_ci <- confint(model_disfluency)["age", ] # 95% CI
  246. #Build a results row including CI
  247. result_row <- data.frame(
  248. outcome = var,
  249. estimate = age_coef["Estimate"],
  250. std.error = age_coef["Std. Error"],
  251. statistic = age_coef["t value"],
  252. p.value = age_coef["Pr(>|t|)"],
  253. CI_lower = age_ci[1],
  254. CI_upper = age_ci[2]
  255. )
  256. age_effects_disfluency <- rbind(age_effects_disfluency, result_row)
  257. }
  258. #Apply fdr correction across the six tests
  259. age_effects_disfluency$adj.p <- p.adjust(age_effects_disfluency$p.value,
  260. method = "fdr")
  261. print(age_effects_disfluency)
  262. ```
  263. ```{r Age on disfluency_results_table}
  264. age_effects_disfluency %>%
  265. kable(
  266. format = ifelse(knitr::is_latex_output(), "latex", "html"),
  267. digits = 3,
  268. caption = "Age Effects on Disfluency Measures (fdr-adjusted)"
  269. ) %>%
  270. kable_styling(full_width = FALSE)
  271. ```
  272. ```{r Age effects for RSFC}
  273. rsfc_vars <- c(
  274. "Lang_LH_within", "DMN_within", "MD_within",
  275. "Lang_to_DMN", "Lang_to_MD",
  276. "Lang_LH_segregation", "DMN_segregation", "MD_segregation"
  277. )
  278. #Create an empty data frame to store results
  279. age_effects_rsfc <- data.frame()
  280. #Loop through each RSFC variable
  281. for (var in rsfc_vars) {
  282. #Fit LM
  283. model_RSFC <- lm(as.formula(paste(var, "~ age + education + project")), data = merged_data)
  284. #Extract summary for the age predictor
  285. model_summary <- summary(model_RSFC)
  286. age_coef <- coef(model_summary)["age", ]
  287. #Store results
  288. result_row <- data.frame(
  289. outcome = var,
  290. estimate = age_coef["Estimate"],
  291. std.error = age_coef["Std. Error"],
  292. statistic = age_coef["t value"],
  293. p.value = age_coef["Pr(>|t|)"]
  294. )
  295. #Get age coefficient and CI
  296. s <- summary(model_RSFC)
  297. age_coef <- coef(s)["age", ]
  298. age_ci <- confint(model_RSFC)["age", ] # 95% CI
  299. #Build a results row including CI
  300. result_row <- data.frame(
  301. outcome = var,
  302. estimate = age_coef["Estimate"],
  303. std.error = age_coef["Std. Error"],
  304. statistic = age_coef["t value"],
  305. p.value = age_coef["Pr(>|t|)"],
  306. CI_lower = age_ci[1],
  307. CI_upper = age_ci[2]
  308. )
  309. age_effects_rsfc <- rbind(age_effects_rsfc, result_row)
  310. }
  311. ```
  312. ```{r Age effects just on network segregation}
  313. seg_vars <- c("Lang_LH_segregation", "DMN_segregation", "MD_segregation")
  314. # lm age models
  315. age_seg <- map_dfr(seg_vars, function(var) {
  316. m <- lm(as.formula(paste(var, "~ age + education + project")), data = merged_data)
  317. est <- coef(summary(m))["age", "Estimate"]
  318. se <- coef(summary(m))["age", "Std. Error"]
  319. t <- coef(summary(m))["age", "t value"]
  320. p <- coef(summary(m))["age", "Pr(>|t|)"]
  321. ci <- confint(m)["age", ]
  322. tibble(
  323. network = var,
  324. estimate = est,
  325. std.error = se,
  326. t.value = t,
  327. p.value = p,
  328. CI_lower = ci[1],
  329. CI_upper = ci[2]
  330. )
  331. })
  332. # FDR-correct across the three p-values
  333. age_seg <- age_seg %>%
  334. mutate(q_fdr = p.adjust(p.value, method = "fdr"))
  335. # Print the table
  336. age_seg %>%
  337. kable(digits = 3, caption = "Age Effects on Network Segregation (FDR-adjusted)") %>%
  338. kable_styling(full_width = FALSE)
  339. ```
  340. ```{r Age effects for RSFC}
  341. #Apply fdr correction across the 8 tests
  342. age_effects_rsfc$adj.p <- p.adjust(age_effects_rsfc$p.value,
  343. method = "fdr")
  344. print(age_effects_rsfc)
  345. age_effects_rsfc %>%
  346. kable(
  347. format = ifelse(knitr::is_latex_output(), "latex", "html"),
  348. digits = 3,
  349. caption = "Age Effects on RSFC Measures (fdr-adjusted)"
  350. ) %>%
  351. kable_styling(full_width = FALSE)
  352. ```
  353. ```{r Age on Stroop}
  354. # Fit model
  355. age_stroop <- lm(stroop_effect ~ age + education + project, data = merged_data)
  356. # Model summary
  357. ci_age <- summary(age_stroop)
  358. # Extract age coefficient
  359. coef_age <- ci_age$coefficients["age", ]
  360. print(ci_age)
  361. # Extract 95% CI for age
  362. ci_full <- confint(age_stroop)
  363. ci_age <- ci_full[match("age", rownames(ci_full)), ]
  364. # Raw & FDR-adjusted p-value
  365. p_raw <- coef_age["Pr(>|t|)"]
  366. p_adj <- p.adjust(p_raw, method = "fdr")
  367. # View full model summary
  368. print(ci_age)
  369. ```
  370. ##LM Analyses within and between rsfc measures
  371. Note that the manuscript focuses only on segregation as this is a measures of both within and between. Within and Between analyses and results however are reported in the supplemental materials.
  372. ```{r Mean center predictor variables}
  373. #First mean center all preditor variables
  374. merged_data <- merged_data %>%
  375. mutate(
  376. age_c = scale(age, scale = FALSE),
  377. stroop_effect_c = scale(stroop_effect, scale = FALSE),
  378. Lang_LH_within_c = scale(Lang_LH_within, scale = FALSE),
  379. MD_within_c = scale(MD_within, scale = FALSE),
  380. DMN_within_c = scale(DMN_within, scale = FALSE),
  381. Lang_to_DMN_c = scale(Lang_to_DMN, scale = FALSE),
  382. Lang_to_MD_c = scale(Lang_to_MD, scale = FALSE),
  383. DMN_to_MD_c = scale(DMN_to_MD, scale = FALSE),
  384. Lang_LH_segregation_c = scale(Lang_LH_segregation, scale = FALSE),
  385. MD_segregation_c = scale(MD_segregation, scale = FALSE),
  386. DMN_segregation_c = scale(DMN_segregation, scale = FALSE)
  387. )
  388. ```
  389. ```{r Within DMN models}
  390. #Total disfluencies
  391. model_total_disfluencies_DMN <- lm(
  392. perc_total_disfluencies ~ age_c + stroop_effect_c + DMN_within_c +
  393. age_c:stroop_effect_c + age_c:DMN_within_c + education + project,
  394. data = merged_data %>% filter(!is.na(perc_total_disfluencies)),
  395. na.action = na.exclude
  396. )
  397. #Total repetitions
  398. model_total_repetitions_DMN <- lm(
  399. perc_total_repetitions ~ age_c + stroop_effect_c + DMN_within_c +
  400. age_c:stroop_effect_c + age_c:DMN_within_c + education + project,
  401. data = merged_data %>% filter(!is.na(perc_total_repetitions)),
  402. na.action = na.exclude
  403. )
  404. #Filled pauses
  405. model_filled_pauses_DMN <- lm(
  406. perc_filled_pauses ~ age_c + stroop_effect_c + DMN_within_c +
  407. age_c:stroop_effect_c + age_c:DMN_within_c + education + project,
  408. data = merged_data %>% filter(!is.na(perc_filled_pauses)),
  409. na.action = na.exclude
  410. )
  411. #Unfilled pauses
  412. model_unfilled_pauses_DMN <- lm(
  413. perc_pauses ~ age_c + stroop_effect_c + DMN_within_c +
  414. age_c:stroop_effect_c + age_c:DMN_within_c + education + project,
  415. data = merged_data %>% filter(!is.na(perc_pauses)),
  416. na.action = na.exclude
  417. )
  418. #Prolongations
  419. model_prolongation_DMN <- lm(
  420. perc_prolongation ~ age_c + stroop_effect_c + DMN_within_c +
  421. age_c:stroop_effect_c + age_c:DMN_within_c + education + project,
  422. data = merged_data %>% filter(!is.na(perc_prolongation)),
  423. na.action = na.exclude
  424. )
  425. #Revisions
  426. model_total_revisions_DMN <- lm(
  427. perc_total_revisions ~ age_c + stroop_effect_c + DMN_within_c +
  428. age_c:stroop_effect_c + age_c:DMN_within_c + education + project,
  429. data = merged_data %>% filter(!is.na(perc_total_revisions)),
  430. na.action = na.exclude
  431. )
  432. #List all models
  433. models <- list(
  434. total_disfluencies = model_total_disfluencies_DMN,
  435. total_repetitions = model_total_repetitions_DMN,
  436. filled_pauses = model_filled_pauses_DMN,
  437. unfilled_pauses = model_unfilled_pauses_DMN,
  438. prolongation = model_prolongation_DMN,
  439. total_revisions = model_total_revisions_DMN
  440. )
  441. #Print summary() and confint() for each model
  442. for(name in names(models)) {
  443. cat("\n\n### Model for", name, "\n")
  444. print(summary(models[[name]]))
  445. cat("\n95% CI for coefficients:\n")
  446. print(confint(models[[name]]))
  447. }
  448. # extract raw p-values for DMN_within_c
  449. p_raw <- sapply(models, function(m) {
  450. summary(m)$coefficients["DMN_within_c", "Pr(>|t|)"]
  451. })
  452. # apply fdr correction across 6 tests --> main effects only
  453. # (the `n=` argument forces it to use 6 even if p_raw is shorter)
  454. p_adj <- p.adjust(p_raw, method = "fdr", n = 6)
  455. cat("\n\nfdr-adjusted p-values:\n")
  456. print(p_adj)
  457. # Extract raw p-values for interaction term age_c:DMN_within_c
  458. p_raw_interactions <- sapply(models, function(m) {
  459. summary(m)$coefficients["age_c:DMN_within_c", "Pr(>|t|)"]
  460. })
  461. # Now apply FDR correction across those 6 interaction tests
  462. p_adj_interactions <- p.adjust(p_raw_interactions, method = "fdr", n = 6)
  463. cat("\n\nFDR-adjusted p-values for age_c:DMN_within_c interaction:\n")
  464. print(p_adj_interactions)
  465. ```
  466. ```{r total disfluencies interactions}
  467. library(interactions)
  468. interact_plot(
  469. model_total_disfluencies_DMN,
  470. pred = DMN_within_c,
  471. modx = age_c,
  472. interval = TRUE,
  473. x.label = "Within-network DMN FC (centered)",
  474. y.label = "Total Disfluencies (%)",
  475. modx.labels = c("Younger", "Average", "Older")
  476. )
  477. sim_slopes(
  478. model_total_disfluencies_DMN,
  479. pred = DMN_within_c,
  480. modx = age_c,
  481. jnplot = TRUE
  482. )
  483. ```
  484. ```{r repetitions}
  485. interact_plot(
  486. model_total_repetitions_DMN,
  487. pred = DMN_within_c,
  488. modx = age_c,
  489. interval = TRUE,
  490. x.label = "Within-network DMN FC (centered)",
  491. y.label = "Repetitions (%)",
  492. modx.labels = c("Younger", "Average", "Older")
  493. )
  494. sim_slopes(
  495. model_total_repetitions_DMN,
  496. pred = DMN_within_c,
  497. modx = age_c,
  498. jnplot = TRUE
  499. )
  500. ```
  501. ```{r filled pauses}
  502. interact_plot(
  503. model_filled_pauses_DMN,
  504. pred = DMN_within_c,
  505. modx = age_c,
  506. interval = TRUE,
  507. x.label = "Within-network DMN FC (centered)",
  508. y.label = "Filled Pauses (%)",
  509. modx.labels = c("Younger", "Average", "Older")
  510. )
  511. sim_slopes(
  512. model_filled_pauses_DMN,
  513. pred = DMN_within_c,
  514. modx = age_c,
  515. jnplot = TRUE
  516. )
  517. ```
  518. ```{r Wihin MD models}
  519. # Within MD --> disfluencies
  520. # Total disfluencies
  521. model_total_disfluencies_MD <- lm(
  522. perc_total_disfluencies ~ age_c + stroop_effect_c + MD_within_c +
  523. age_c:stroop_effect_c + age_c:MD_within_c + education + project,
  524. data = merged_data %>% filter(!is.na(perc_total_disfluencies)),
  525. na.action = na.exclude
  526. )
  527. # Total repetitions
  528. model_total_repetitions_MD <- lm(
  529. perc_total_repetitions ~ age_c + stroop_effect_c + MD_within_c +
  530. age_c:stroop_effect_c + age_c:MD_within_c + education + project,
  531. data = merged_data %>% filter(!is.na(perc_total_repetitions)),
  532. na.action = na.exclude
  533. )
  534. # Filled pauses
  535. model_filled_pauses_MD <- lm(
  536. perc_filled_pauses ~ age_c + stroop_effect_c + MD_within_c +
  537. age_c:stroop_effect_c + age_c:MD_within_c + education + project,
  538. data = merged_data %>% filter(!is.na(perc_filled_pauses)),
  539. na.action = na.exclude
  540. )
  541. # Unfilled pauses
  542. model_unfilled_pauses_MD <- lm(
  543. perc_pauses ~ age_c + stroop_effect_c + MD_within_c +
  544. age_c:stroop_effect_c + age_c:MD_within_c + education + project,
  545. data = merged_data %>% filter(!is.na(perc_pauses)),
  546. na.action = na.exclude
  547. )
  548. # Prolongations
  549. model_prolongation_MD <- lm(
  550. perc_prolongation ~ age_c + stroop_effect_c + MD_within_c +
  551. age_c:stroop_effect_c + age_c:MD_within_c + education + project,
  552. data = merged_data %>% filter(!is.na(perc_prolongation)),
  553. na.action = na.exclude
  554. )
  555. # Revisions
  556. model_total_revisions_MD <- lm(
  557. perc_total_revisions ~ age_c + stroop_effect_c + MD_within_c +
  558. age_c:stroop_effect_c + age_c:MD_within_c + education + project,
  559. data = merged_data %>% filter(!is.na(perc_total_revisions)),
  560. na.action = na.exclude
  561. )
  562. # List all MD models
  563. models_MD <- list(
  564. total_disfluencies = model_total_disfluencies_MD,
  565. total_repetitions = model_total_repetitions_MD,
  566. filled_pauses = model_filled_pauses_MD,
  567. unfilled_pauses = model_unfilled_pauses_MD,
  568. prolongation = model_prolongation_MD,
  569. total_revisions = model_total_revisions_MD
  570. )
  571. # Print summary() and 95% CI for each model
  572. for (name in names(models_MD)) {
  573. cat("\n\n### Model for", name, "\n")
  574. print(summary(models_MD[[name]]))
  575. cat("\n95% CI for coefficients:\n")
  576. print(confint(models_MD[[name]]))
  577. }
  578. #Extract raw p-values for the MD_within_c term
  579. p_raw_MD <- sapply(models_MD, function(m) {
  580. summary(m)$coefficients["MD_within_c", "Pr(>|t|)"]
  581. })
  582. #Apply fdr correction across 6 tests
  583. p_adj_MD <- p.adjust(p_raw_MD, method = "fdr", n = 6)
  584. cat("\n\nfdr-adjusted p-values for MD_within_c across models:\n")
  585. print(p_adj_MD)
  586. ```
  587. ```{r Within Lang}
  588. # Total disfluencies
  589. model_total_disfluencies_LANG <- lm(
  590. perc_total_disfluencies ~ age_c + stroop_effect_c + Lang_LH_within_c +
  591. age_c:stroop_effect_c + age_c:Lang_LH_within_c + education + project,
  592. data = merged_data %>% filter(!is.na(perc_total_disfluencies)),
  593. na.action = na.exclude
  594. )
  595. # Total repetitions
  596. model_total_repetitions_LANG <- lm(
  597. perc_total_repetitions ~ age_c + stroop_effect_c + Lang_LH_within_c +
  598. age_c:stroop_effect_c + age_c:Lang_LH_within_c + education + project,
  599. data = merged_data %>% filter(!is.na(perc_total_repetitions)),
  600. na.action = na.exclude
  601. )
  602. # Filled pauses
  603. model_filled_pauses_LANG <- lm(
  604. perc_filled_pauses ~ age_c + stroop_effect_c + Lang_LH_within_c +
  605. age_c:stroop_effect_c + age_c:Lang_LH_within_c + education + project,
  606. data = merged_data %>% filter(!is.na(perc_filled_pauses)),
  607. na.action = na.exclude
  608. )
  609. # Unfilled pauses
  610. model_unfilled_pauses_LANG <- lm(
  611. perc_pauses ~ age_c + stroop_effect_c + Lang_LH_within_c +
  612. age_c:stroop_effect_c + age_c:Lang_LH_within_c + education + project,
  613. data = merged_data %>% filter(!is.na(perc_pauses)),
  614. na.action = na.exclude
  615. )
  616. # Prolongations
  617. model_prolongation_LANG <- lm(
  618. perc_prolongation ~ age_c + stroop_effect_c + Lang_LH_within_c +
  619. age_c:stroop_effect_c + age_c:Lang_LH_within_c + education + project,
  620. data = merged_data %>% filter(!is.na(perc_prolongation)),
  621. na.action = na.exclude
  622. )
  623. # Revisions
  624. model_total_revisions_LANG <- lm(
  625. perc_total_revisions ~ age_c + stroop_effect_c + Lang_LH_within_c +
  626. age_c:stroop_effect_c + age_c:Lang_LH_within_c + education + project,
  627. data = merged_data %>% filter(!is.na(perc_total_revisions)),
  628. na.action = na.exclude
  629. )
  630. # List all LANGUAGE models
  631. models_LANG <- list(
  632. total_disfluencies = model_total_disfluencies_LANG,
  633. total_repetitions = model_total_repetitions_LANG,
  634. filled_pauses = model_filled_pauses_LANG,
  635. unfilled_pauses = model_unfilled_pauses_LANG,
  636. prolongation = model_prolongation_LANG,
  637. total_revisions = model_total_revisions_LANG
  638. )
  639. # Print summary() and 95% CI for each model
  640. for (name in names(models_LANG)) {
  641. cat("\n\n### Model for", name, "\n")
  642. print(summary(models_LANG[[name]]))
  643. cat("\n95% CI for coefficients:\n")
  644. print(confint(models_LANG[[name]]))
  645. }
  646. #Extract raw p-values for the Lang_LH_within_c term
  647. p_raw_LANG <- sapply(models_LANG, function(m) {
  648. summary(m)$coefficients["Lang_LH_within_c", "Pr(>|t|)"]
  649. })
  650. #Apply fdr correction across 6 tests
  651. p_adj_LANG <- p.adjust(p_raw_LANG, method = "fdr", n = 6)
  652. cat("\n\nfdr-adjusted p-values for Lang_LH_within_c across models:\n")
  653. print(p_adj_LANG)
  654. ```
  655. ```{r Between Lang to DMN }
  656. # Between Language to DMN
  657. # Total disfluencies
  658. model_total_disfluencies_LangToDMN <- lm(
  659. perc_total_disfluencies ~ age_c + stroop_effect_c + Lang_to_DMN_c +
  660. age_c:stroop_effect_c + age_c:Lang_to_DMN_c + education + project,
  661. data = merged_data %>% filter(!is.na(perc_total_disfluencies)),
  662. na.action = na.exclude
  663. )
  664. # Total repetitions
  665. model_total_repetitions_LangToDMN <- lm(
  666. perc_total_repetitions ~ age_c + stroop_effect_c + Lang_to_DMN_c +
  667. age_c:stroop_effect_c + age_c:Lang_to_DMN_c + education + project,
  668. data = merged_data %>% filter(!is.na(perc_total_repetitions)),
  669. na.action = na.exclude
  670. )
  671. # Filled pauses
  672. model_filled_pauses_LangToDMN <- lm(
  673. perc_filled_pauses ~ age_c + stroop_effect_c + Lang_to_DMN_c +
  674. age_c:stroop_effect_c + age_c:Lang_to_DMN_c + education + project,
  675. data = merged_data %>% filter(!is.na(perc_filled_pauses)),
  676. na.action = na.exclude
  677. )
  678. # Unfilled pauses
  679. model_unfilled_pauses_LangToDMN <- lm(
  680. perc_pauses ~ age_c + stroop_effect_c + Lang_to_DMN_c +
  681. age_c:stroop_effect_c + age_c:Lang_to_DMN_c + education + project,
  682. data = merged_data %>% filter(!is.na(perc_pauses)),
  683. na.action = na.exclude
  684. )
  685. # Prolongations
  686. model_prolongation_LangToDMN <- lm(
  687. perc_prolongation ~ age_c + stroop_effect_c + Lang_to_DMN_c +
  688. age_c:stroop_effect_c + age_c:Lang_to_DMN_c + education + project,
  689. data = merged_data %>% filter(!is.na(perc_prolongation)),
  690. na.action = na.exclude
  691. )
  692. # Revisions
  693. model_total_revisions_LangToDMN <- lm(
  694. perc_total_revisions ~ age_c + stroop_effect_c + Lang_to_DMN_c +
  695. age_c:stroop_effect_c + age_c:Lang_to_DMN_c + education + project,
  696. data = merged_data %>% filter(!is.na(perc_total_revisions)),
  697. na.action = na.exclude
  698. )
  699. # List all Lang -->DMN models
  700. models_LangToDMN <- list(
  701. total_disfluencies = model_total_disfluencies_LangToDMN,
  702. total_repetitions = model_total_repetitions_LangToDMN,
  703. filled_pauses = model_filled_pauses_LangToDMN,
  704. unfilled_pauses = model_unfilled_pauses_LangToDMN,
  705. prolongation = model_prolongation_LangToDMN,
  706. total_revisions = model_total_revisions_LangToDMN
  707. )
  708. # Print summary() and 95% CI for each model
  709. for (name in names(models_LangToDMN)) {
  710. cat("\n\n### Model for", name, "\n")
  711. print(summary(models_LangToDMN[[name]]))
  712. cat("\n95% CI for coefficients:\n")
  713. print(confint(models_LangToDMN[[name]]))
  714. }
  715. # get raw p-values
  716. p_raw_main <- sapply(models_LangToDMN, function(m) {
  717. summary(m)$coefficients["Lang_to_DMN_c", "Pr(>|t|)"]
  718. })
  719. p_raw_interaction <- sapply(models_LangToDMN, function(m) {
  720. summary(m)$coefficients["age_c:Lang_to_DMN_c", "Pr(>|t|)"]
  721. })
  722. # Apply FDR correction
  723. p_adj_main <- p.adjust(p_raw_main, method = "fdr", n = length(p_raw_main))
  724. p_adj_interaction <- p.adjust(p_raw_interaction, method = "fdr", n = length(p_raw_interaction))
  725. # Print results
  726. cat("\n\nFDR-adjusted p-values for Lang_to_DMN_c (main effect):\n")
  727. print(p_adj_main)
  728. cat("\n\nFDR-adjusted p-values for age_c:Lang_to_DMN_c (interaction):\n")
  729. print(p_adj_interaction)
  730. ```
  731. ```{r test interactions}
  732. library(interactions)
  733. # Plot the interaction: Lang–DMN FC × Age predicting Filled Pauses
  734. interact_plot(
  735. model_total_disfluencies_LangToDMN,
  736. pred = Lang_to_DMN_c,
  737. modx = age_c,
  738. interval = TRUE,
  739. x.label = "Lang–DMN FC (centered)",
  740. y.label = "Total disfluencies (%)",
  741. modx.labels = c("Younger", "Average", "Older")
  742. )
  743. # Simple slopes and Johnson-Neyman test
  744. sim_slopes(
  745. model_total_disfluencies_LangToDMN,
  746. pred = Lang_to_DMN_c,
  747. modx = age_c,
  748. jnplot = TRUE
  749. )
  750. ```
  751. ```{r plot interaction}
  752. # Plot the interaction: Lang–DMN FC × Age predicting Filled Pauses
  753. interact_plot(
  754. model_total_repetitions_LangToDMN,
  755. pred = Lang_to_DMN_c,
  756. modx = age_c,
  757. interval = TRUE,
  758. x.label = "Lang–DMN FC (centered)",
  759. y.label = "Total disfluencies (%)",
  760. modx.labels = c("Younger", "Average", "Older")
  761. )
  762. # Simple slopes and Johnson-Neyman test
  763. sim_slopes(
  764. model_total_repetitions_LangToDMN,
  765. pred = Lang_to_DMN_c,
  766. modx = age_c,
  767. jnplot = TRUE
  768. )
  769. ```
  770. ```{r Between Lang to MD}
  771. # Total disfluencies
  772. model_total_disfluencies_LangToMD <- lm(
  773. perc_total_disfluencies ~ age_c + stroop_effect_c + Lang_to_MD_c +
  774. age_c:stroop_effect_c + age_c:Lang_to_MD_c + education + project,
  775. data = merged_data %>% filter(!is.na(perc_total_disfluencies)),
  776. na.action = na.exclude
  777. )
  778. # Total repetitions
  779. model_total_repetitions_LangToMD <- lm(
  780. perc_total_repetitions ~ age_c + stroop_effect_c + Lang_to_MD_c +
  781. age_c:stroop_effect_c + age_c:Lang_to_MD_c + education + project,
  782. data = merged_data %>% filter(!is.na(perc_total_repetitions)),
  783. na.action = na.exclude
  784. )
  785. # Filled pauses
  786. model_filled_pauses_LangToMD <- lm(
  787. perc_filled_pauses ~ age_c + stroop_effect_c + Lang_to_MD_c +
  788. age_c:stroop_effect_c + age_c:Lang_to_MD_c + education + project,
  789. data = merged_data %>% filter(!is.na(perc_filled_pauses)),
  790. na.action = na.exclude
  791. )
  792. # Unfilled pauses
  793. model_unfilled_pauses_LangToMD <- lm(
  794. perc_pauses ~ age_c + stroop_effect_c + Lang_to_MD_c +
  795. age_c:stroop_effect_c + age_c:Lang_to_MD_c + education + project,
  796. data = merged_data %>% filter(!is.na(perc_pauses)),
  797. na.action = na.exclude
  798. )
  799. # Prolongations
  800. model_prolongation_LangToMD <- lm(
  801. perc_prolongation ~ age_c + stroop_effect_c + Lang_to_MD_c +
  802. age_c:stroop_effect_c + age_c:Lang_to_MD_c + education + project,
  803. data = merged_data %>% filter(!is.na(perc_prolongation)),
  804. na.action = na.exclude
  805. )
  806. # Revisions
  807. model_total_revisions_LangToMD <- lm(
  808. perc_total_revisions ~ age_c + stroop_effect_c + Lang_to_MD_c +
  809. age_c:stroop_effect_c + age_c:Lang_to_MD_c + education + project,
  810. data = merged_data %>% filter(!is.na(perc_total_revisions)),
  811. na.action = na.exclude
  812. )
  813. # List all Lang→MD models
  814. models_LangToMD <- list(
  815. total_disfluencies = model_total_disfluencies_LangToMD,
  816. total_repetitions = model_total_repetitions_LangToMD,
  817. filled_pauses = model_filled_pauses_LangToMD,
  818. unfilled_pauses = model_unfilled_pauses_LangToMD,
  819. prolongation = model_prolongation_LangToMD,
  820. total_revisions = model_total_revisions_LangToMD
  821. )
  822. # Print summary() and 95% CI for each model
  823. for (name in names(models_LangToMD)) {
  824. cat("\n\n### Model for", name, "\n")
  825. print(summary(models_LangToMD[[name]]))
  826. cat("\n95% CI for coefficients:\n")
  827. print(confint(models_LangToMD[[name]]))
  828. }
  829. # FDR Correction
  830. #Extract raw p-values for Lang_to_MD_c
  831. p_raw_LangToMD <- sapply(models_LangToMD, function(m) {
  832. summary(m)$coefficients["Lang_to_MD_c", "Pr(>|t|)"]
  833. })
  834. #Apply fdr correction across 6 tests
  835. p_adj_LangToMD <- p.adjust(p_raw_LangToMD, method = "fdr", n = 6)
  836. cat("\n\nfdr-adjusted p-values for Lang_to_MD_c across models:\n")
  837. print(p_adj_LangToMD)
  838. ```
  839. ```{r Between DMN to MD}
  840. #Ran this model but since there were no a priori hypotheses, this is not included in the manuscript results
  841. # Total disfluencies
  842. model_total_disfluencies_DMNtoMD <- lm(
  843. perc_total_disfluencies ~ age_c + stroop_effect_c + DMN_to_MD_c +
  844. age_c:stroop_effect_c + age_c:DMN_to_MD_c + education + project,
  845. data = merged_data %>% filter(!is.na(perc_total_disfluencies)),
  846. na.action = na.exclude
  847. )
  848. # Total repetitions
  849. model_total_repetitions_DMNtoMD <- lm(
  850. perc_total_repetitions ~ age_c + stroop_effect_c + DMN_to_MD_c +
  851. age_c:stroop_effect_c + age_c:DMN_to_MD_c + education + project,
  852. data = merged_data %>% filter(!is.na(perc_total_repetitions)),
  853. na.action = na.exclude
  854. )
  855. # Filled pauses
  856. model_filled_pauses_DMNtoMD <- lm(
  857. perc_filled_pauses ~ age_c + stroop_effect_c + DMN_to_MD_c +
  858. age_c:stroop_effect_c + age_c:DMN_to_MD_c + education + project,
  859. data = merged_data %>% filter(!is.na(perc_filled_pauses)),
  860. na.action = na.exclude
  861. )
  862. # Unfilled pauses
  863. model_unfilled_pauses_DMNtoMD <- lm(
  864. perc_pauses ~ age_c + stroop_effect_c + DMN_to_MD_c +
  865. age_c:stroop_effect_c + age_c:DMN_to_MD_c + education + project,
  866. data = merged_data %>% filter(!is.na(perc_pauses)),
  867. na.action = na.exclude
  868. )
  869. # Prolongations
  870. model_prolongation_DMNtoMD <- lm(
  871. perc_prolongation ~ age_c + stroop_effect_c + DMN_to_MD_c +
  872. age_c:stroop_effect_c + age_c:DMN_to_MD_c + education + project,
  873. data = merged_data %>% filter(!is.na(perc_prolongation)),
  874. na.action = na.exclude
  875. )
  876. # Revisions
  877. model_total_revisions_DMNtoMD <- lm(
  878. perc_total_revisions ~ age_c + stroop_effect_c + DMN_to_MD_c +
  879. age_c:stroop_effect_c + age_c:DMN_to_MD_c + education + project,
  880. data = merged_data %>% filter(!is.na(perc_total_revisions)),
  881. na.action = na.exclude
  882. )
  883. # List all DMN to MD models
  884. models_DMNtoMD <- list(
  885. total_disfluencies = model_total_disfluencies_DMNtoMD,
  886. total_repetitions = model_total_repetitions_DMNtoMD,
  887. filled_pauses = model_filled_pauses_DMNtoMD,
  888. unfilled_pauses = model_unfilled_pauses_DMNtoMD,
  889. prolongation = model_prolongation_DMNtoMD,
  890. total_revisions = model_total_revisions_DMNtoMD
  891. )
  892. # Print summary() and 95% CI for each model
  893. for (name in names(models_DMNtoMD)) {
  894. cat("\n\n### Model for", name, "\n")
  895. print(summary(models_DMNtoMD[[name]]))
  896. cat("\n95% CI for coefficients:\n")
  897. print(confint(models_DMNtoMD[[name]]))
  898. }
  899. #FDR correction
  900. #Extract raw p-values for the DMN_to_MD_c term
  901. p_raw_DMNtoMD <- sapply(models_DMNtoMD, function(m) {
  902. summary(m)$coefficients["DMN_to_MD_c", "Pr(>|t|)"]
  903. })
  904. #Apply fdr correction across 6 tests
  905. p_adj_DMNtoMD <- p.adjust(p_raw_DMNtoMD, method = "fdr", n = 6)
  906. cat("\n\nfdr-adjusted p-values for DMN_to_MD_c across models:\n")
  907. print(p_adj_DMNtoMD)
  908. ```
  909. #LM Analyses Segregation rsfc measure
  910. Here is the main analyses reported in the manuscript i.e., the Segregation measure
  911. ```{r Segregation DMN}
  912. # Total disfluencies
  913. model_total_disfluencies_DMNseg <- lm(
  914. perc_total_disfluencies ~ age_c + stroop_effect_c + DMN_segregation_c +
  915. age_c:stroop_effect_c + age_c:DMN_segregation_c + education + project,
  916. data = merged_data %>% filter(!is.na(perc_total_disfluencies)),
  917. na.action = na.exclude
  918. )
  919. # Total repetitions
  920. model_total_repetitions_DMNseg <- lm(
  921. perc_total_repetitions ~ age_c + stroop_effect_c + DMN_segregation_c +
  922. age_c:stroop_effect_c + age_c:DMN_segregation_c + education + project,
  923. data = merged_data %>% filter(!is.na(perc_total_repetitions)),
  924. na.action = na.exclude
  925. )
  926. # Filled pauses
  927. model_filled_pauses_DMNseg <- lm(
  928. perc_filled_pauses ~ age_c + stroop_effect_c + DMN_segregation_c +
  929. age_c:stroop_effect_c + age_c:DMN_segregation_c + education + project,
  930. data = merged_data %>% filter(!is.na(perc_filled_pauses)),
  931. na.action = na.exclude
  932. )
  933. # Unfilled pauses
  934. model_unfilled_pauses_DMNseg <- lm(
  935. perc_pauses ~ age_c + stroop_effect_c + DMN_segregation_c +
  936. age_c:stroop_effect_c + age_c:DMN_segregation_c + education + project,
  937. data = merged_data %>% filter(!is.na(perc_pauses)),
  938. na.action = na.exclude
  939. )
  940. # Prolongations
  941. model_prolongation_DMNseg <- lm(
  942. perc_prolongation ~ age_c + stroop_effect_c + DMN_segregation_c +
  943. age_c:stroop_effect_c + age_c:DMN_segregation_c + education + project,
  944. data = merged_data %>% filter(!is.na(perc_prolongation)),
  945. na.action = na.exclude
  946. )
  947. # Revisions
  948. model_total_revisions_DMNseg <- lm(
  949. perc_total_revisions ~ age_c + stroop_effect_c + DMN_segregation_c +
  950. age_c:stroop_effect_c + age_c:DMN_segregation_c + education + project,
  951. data = merged_data %>% filter(!is.na(perc_total_revisions)),
  952. na.action = na.exclude
  953. )
  954. # List all DMN segregation models
  955. models_DMNseg <- list(
  956. total_disfluencies = model_total_disfluencies_DMNseg,
  957. total_repetitions = model_total_repetitions_DMNseg,
  958. filled_pauses = model_filled_pauses_DMNseg,
  959. unfilled_pauses = model_unfilled_pauses_DMNseg,
  960. prolongation = model_prolongation_DMNseg,
  961. total_revisions = model_total_revisions_DMNseg
  962. )
  963. # Print summary() and 95% CI for each model
  964. for (name in names(models_DMNseg)) {
  965. cat("\n\n### Model for", name, "\n")
  966. print(summary(models_DMNseg[[name]]))
  967. cat("\n95% CI for coefficients:\n")
  968. print(confint(models_DMNseg[[name]]))
  969. }
  970. ```
  971. ```{r Test Interactions Age x DMNseg}
  972. # Model
  973. model_dmn_total <- lm(
  974. perc_total_disfluencies ~ age_c + DMN_segregation_c +
  975. stroop_effect_c + age_c:DMN_segregation_c +
  976. age_c:stroop_effect_c + education + project,
  977. data = merged_data
  978. )
  979. # Plot interaction
  980. interact_plot(
  981. model_dmn_total,
  982. pred = DMN_segregation_c,
  983. modx = age_c,
  984. interval = TRUE,
  985. x.label = "DMN Segregation (centered)",
  986. y.label = "Total Disfluencies (%)",
  987. modx.labels = c("Younger", "Average", "Older")
  988. )
  989. # Simple slopes and Johnson-Neyman
  990. sim_slopes(
  991. model_dmn_total,
  992. pred = DMN_segregation_c,
  993. modx = age_c,
  994. jnplot = TRUE
  995. )
  996. ```
  997. ```{r Test Interactions Age x DMNseg}
  998. model_dmn_reps <- lm(
  999. perc_total_repetitions ~ age_c + DMN_segregation_c +
  1000. stroop_effect_c + age_c:DMN_segregation_c +
  1001. age_c:stroop_effect_c + education + project,
  1002. data = merged_data
  1003. )
  1004. interact_plot(
  1005. model_dmn_reps,
  1006. pred = DMN_segregation_c,
  1007. modx = age_c,
  1008. interval = TRUE,
  1009. x.label = "DMN Segregation (centered)",
  1010. y.label = "Repetitions (%)",
  1011. modx.labels = c("Younger", "Average", "Older")
  1012. )
  1013. sim_slopes(
  1014. model_dmn_reps,
  1015. pred = DMN_segregation_c,
  1016. modx = age_c,
  1017. jnplot = TRUE
  1018. )
  1019. ```
  1020. ```{r Segregation MD}
  1021. # Total disfluencies
  1022. model_total_disfluencies_MDseg <- lm(
  1023. perc_total_disfluencies ~ age_c + stroop_effect_c + MD_segregation_c +
  1024. age_c:stroop_effect_c + age_c:MD_segregation_c + education + project,
  1025. data = merged_data %>% filter(!is.na(perc_total_disfluencies)),
  1026. na.action = na.exclude
  1027. )
  1028. # Total repetitions
  1029. model_total_repetitions_MDseg <- lm(
  1030. perc_total_repetitions ~ age_c + stroop_effect_c + MD_segregation_c +
  1031. age_c:stroop_effect_c + age_c:MD_segregation_c + education + project,
  1032. data = merged_data %>% filter(!is.na(perc_total_repetitions)),
  1033. na.action = na.exclude
  1034. )
  1035. # Filled pauses
  1036. model_filled_pauses_MDseg <- lm(
  1037. perc_filled_pauses ~ age_c + stroop_effect_c + MD_segregation_c +
  1038. age_c:stroop_effect_c + age_c:MD_segregation_c + education + project,
  1039. data = merged_data %>% filter(!is.na(perc_filled_pauses)),
  1040. na.action = na.exclude
  1041. )
  1042. # Unfilled pauses
  1043. model_unfilled_pauses_MDseg <- lm(
  1044. perc_pauses ~ age_c + stroop_effect_c + MD_segregation_c +
  1045. age_c:stroop_effect_c + age_c:MD_segregation_c + education + project,
  1046. data = merged_data %>% filter(!is.na(perc_pauses)),
  1047. na.action = na.exclude
  1048. )
  1049. # Prolongations
  1050. model_prolongation_MDseg <- lm(
  1051. perc_prolongation ~ age_c + stroop_effect_c + MD_segregation_c +
  1052. age_c:stroop_effect_c + age_c:MD_segregation_c + education + project,
  1053. data = merged_data %>% filter(!is.na(perc_prolongation)),
  1054. na.action = na.exclude
  1055. )
  1056. # Revisions
  1057. model_total_revisions_MDseg <- lm(
  1058. perc_total_revisions ~ age_c + stroop_effect_c + MD_segregation_c +
  1059. age_c:stroop_effect_c + age_c:MD_segregation_c + education + project,
  1060. data = merged_data %>% filter(!is.na(perc_total_revisions)),
  1061. na.action = na.exclude
  1062. )
  1063. # List all MD segregation models
  1064. models_MDseg <- list(
  1065. total_disfluencies = model_total_disfluencies_MDseg,
  1066. total_repetitions = model_total_repetitions_MDseg,
  1067. filled_pauses = model_filled_pauses_MDseg,
  1068. unfilled_pauses = model_unfilled_pauses_MDseg,
  1069. prolongation = model_prolongation_MDseg,
  1070. total_revisions = model_total_revisions_MDseg
  1071. )
  1072. # Print summary() and 95% CI for each model
  1073. for (name in names(models_MDseg)) {
  1074. cat("\n\n### Model for", name, "\n")
  1075. print(summary(models_MDseg[[name]]))
  1076. cat("\n95% CI for coefficients:\n")
  1077. print(confint(models_MDseg[[name]]))
  1078. }
  1079. ```
  1080. ```{r Segregation Lang}
  1081. # Total disfluencies
  1082. model_total_disfluencies_LANGseg <- lm(
  1083. perc_total_disfluencies ~ age_c + stroop_effect_c + Lang_LH_segregation_c +
  1084. age_c:stroop_effect_c + age_c:Lang_LH_segregation_c + education + project,
  1085. data = merged_data %>% filter(!is.na(perc_total_disfluencies)),
  1086. na.action = na.exclude
  1087. )
  1088. # Total repetitions
  1089. model_total_repetitions_LANGseg <- lm(
  1090. perc_total_repetitions ~ age_c + stroop_effect_c + Lang_LH_segregation_c +
  1091. age_c:stroop_effect_c + age_c:Lang_LH_segregation_c + education + project,
  1092. data = merged_data %>% filter(!is.na(perc_total_repetitions)),
  1093. na.action = na.exclude
  1094. )
  1095. # Filled pauses
  1096. model_filled_pauses_LANGseg <- lm(
  1097. perc_filled_pauses ~ age_c + stroop_effect_c + Lang_LH_segregation_c +
  1098. age_c:stroop_effect_c + age_c:Lang_LH_segregation_c + education + project,
  1099. data = merged_data %>% filter(!is.na(perc_filled_pauses)),
  1100. na.action = na.exclude
  1101. )
  1102. # Unfilled pauses
  1103. model_unfilled_pauses_LANGseg <- lm(
  1104. perc_pauses ~ age_c + stroop_effect_c + Lang_LH_segregation_c +
  1105. age_c:stroop_effect_c + age_c:Lang_LH_segregation_c + education + project,
  1106. data = merged_data %>% filter(!is.na(perc_pauses)),
  1107. na.action = na.exclude
  1108. )
  1109. # Prolongations
  1110. model_prolongation_LANGseg <- lm(
  1111. perc_prolongation ~ age_c + stroop_effect_c + Lang_LH_segregation_c +
  1112. age_c:stroop_effect_c + age_c:Lang_LH_segregation_c + education + project,
  1113. data = merged_data %>% filter(!is.na(perc_prolongation)),
  1114. na.action = na.exclude
  1115. )
  1116. # Revisions
  1117. model_total_revisions_LANGseg <- lm(
  1118. perc_total_revisions ~ age_c + stroop_effect_c + Lang_LH_segregation_c +
  1119. age_c:stroop_effect_c + age_c:Lang_LH_segregation_c + education + project,
  1120. data = merged_data %>% filter(!is.na(perc_total_revisions)),
  1121. na.action = na.exclude
  1122. )
  1123. # List all LANGUAGE segregation models
  1124. models_LANGseg <- list(
  1125. total_disfluencies = model_total_disfluencies_LANGseg,
  1126. total_repetitions = model_total_repetitions_LANGseg,
  1127. filled_pauses = model_filled_pauses_LANGseg,
  1128. unfilled_pauses = model_unfilled_pauses_LANGseg,
  1129. prolongation = model_prolongation_LANGseg,
  1130. total_revisions = model_total_revisions_LANGseg
  1131. )
  1132. # Print summary() and 95% CI for each model
  1133. for (name in names(models_LANGseg)) {
  1134. cat("\n\n### Model for", name, "\n")
  1135. print(summary(models_LANGseg[[name]]))
  1136. cat("\n95% CI for coefficients:\n")
  1137. print(confint(models_LANGseg[[name]]))
  1138. }
  1139. ```
  1140. #Correct for Multiple Comparisons Main Effects
  1141. ```{r fdr correction}
  1142. #Extract raw p-values for each network’s 6 disfluency tests
  1143. p_DMN <- sapply(models_DMNseg, function(m) coef(summary(m))["DMN_segregation_c", "Pr(>|t|)"])
  1144. p_MD <- sapply(models_MDseg, function(m) coef(summary(m))["MD_segregation_c", "Pr(>|t|)"])
  1145. p_LANG <- sapply(models_LANGseg, function(m) coef(summary(m))["Lang_LH_segregation_c","Pr(>|t|)"])
  1146. #FDR-adjust within each network
  1147. q_DMN <- p.adjust(p_DMN, method = "fdr")
  1148. q_MD <- p.adjust(p_MD, method = "fdr")
  1149. q_LANG <- p.adjust(p_LANG, method = "fdr")
  1150. #Make a combined table
  1151. seg_by_net <- bind_rows(
  1152. tibble(
  1153. network = "DMN",
  1154. outcome = names(p_DMN),
  1155. p_raw = unname(p_DMN),
  1156. q_fdr = unname(q_DMN)
  1157. ),
  1158. tibble(
  1159. network = "MD",
  1160. outcome = names(p_MD),
  1161. p_raw = unname(p_MD),
  1162. q_fdr = unname(q_MD)
  1163. ),
  1164. tibble(
  1165. network = "LANG",
  1166. outcome = names(p_LANG),
  1167. p_raw = unname(p_LANG),
  1168. q_fdr = unname(q_LANG)
  1169. )
  1170. )
  1171. #Print table
  1172. seg_by_net %>%
  1173. arrange(network, q_fdr) %>%
  1174. kable(
  1175. digits = 3,
  1176. caption = "Network-specific Segregation → Disfluency: raw p and FDR-q"
  1177. ) %>%
  1178. kable_styling(full_width = FALSE)
  1179. ```
  1180. #Correct for Multiple Comparisons: Interactions
  1181. ```{r fdr correction interactions}
  1182. #Extract six interaction p-values per network
  1183. pint_DMN <- sapply(models_DMNseg, function(m) coef(summary(m))["age_c:DMN_segregation_c", "Pr(>|t|)"])
  1184. pint_MD <- sapply(models_MDseg, function(m) coef(summary(m))["age_c:MD_segregation_c", "Pr(>|t|)"])
  1185. pint_LANG <- sapply(models_LANGseg, function(m) coef(summary(m))["age_c:Lang_LH_segregation_c","Pr(>|t|)"])
  1186. #Apply FDR correction
  1187. q_int_DMN <- p.adjust(pint_DMN, method = "fdr")
  1188. q_int_MD <- p.adjust(pint_MD, method = "fdr")
  1189. q_int_LANG <- p.adjust(pint_LANG, method = "fdr")
  1190. #Make a table
  1191. int_by_net <- bind_rows(
  1192. tibble(network = "DMN", outcome = names(pint_DMN), p_int = pint_DMN, q_int = q_int_DMN),
  1193. tibble(network = "MD", outcome = names(pint_MD), p_int = pint_MD, q_int = q_int_MD),
  1194. tibble(network = "LANG", outcome = names(pint_LANG), p_int = pint_LANG, q_int = q_int_LANG)
  1195. )
  1196. #print
  1197. int_by_net %>%
  1198. arrange(network, q_int) %>%
  1199. kable(
  1200. digits = 3,
  1201. caption = "Network‐specific Segregation × Age Interactions: raw p and FDR‐q"
  1202. ) %>%
  1203. kable_styling(full_width = FALSE)
  1204. ```
  1205. #Start of mediation analyses
  1206. First we will see if disfluency is mediated by Stroop, then DMN segregation, then Lang-to-DMN between
  1207. ```{r load libraries}
  1208. library(mediation)
  1209. ```
  1210. ##Mediation A: Stroop mediatior for Total Disfluencies
  1211. Age --> Stroop --> Total_Disfluency
  1212. ```{r mediation model A}
  1213. #Path 1: Age --> EF (Stroop)
  1214. model_A1 <- lm(stroop_effect ~ age + education +project, data = merged_data)
  1215. #Path 2: EF (Stroop) --> Total Disfluencies (controlling for Age)
  1216. model_A2 <- lm(perc_total_disfluencies ~ stroop_effect + age + education +project, data = merged_data)
  1217. #Path 3: Age --> Total Disfluencies
  1218. model_A3 <- lm(perc_total_disfluencies ~ age + education + project, data = merged_data)
  1219. summary(model_A1)
  1220. summary(model_A2)
  1221. summary(model_A3)
  1222. ```
  1223. ##Mediation B: Stroop mediatior for Revisions
  1224. Age --> Stroop --> Revisions
  1225. Now I am going to check just revisions since this overall seems to be the disfluency type that was most sensitive
  1226. ```{r mediation model B}
  1227. #Path 1: Age --> Stroop (same)
  1228. model_B1_rev <- lm(stroop_effect ~ age + education + project, data = merged_data)
  1229. #Path 2: Stroop --> Revisions (controlling for Age)
  1230. model_B2_rev <- lm(perc_total_revisions ~ stroop_effect + age + education + project, data = merged_data)
  1231. # Path 3: Age --> Revisions
  1232. model_B3_rev <- lm(perc_total_revisions ~ age + education + project, data = merged_data)
  1233. summary(model_B1_rev)
  1234. summary(model_B2_rev)
  1235. summary(model_B3_rev)
  1236. ```
  1237. ```{r Full mediation model B}
  1238. # Filter to missing data
  1239. modelB_data <- merged_data %>%
  1240. filter(!is.na(age), !is.na(education), !is.na(stroop_effect), !is.na(perc_total_revisions))
  1241. #re-fit models
  1242. modelB_mediator <- lm(stroop_effect ~ age + education + project, data = modelB_data)
  1243. modelB_outcome <- lm(perc_total_revisions ~ stroop_effect + age + education + project, data = modelB_data)
  1244. #Mediation analysis
  1245. library(mediation)
  1246. set.seed(1234)
  1247. modelB_med <- mediate(
  1248. model.m = modelB_mediator,
  1249. model.y = modelB_outcome,
  1250. treat = "age",
  1251. mediator = "stroop_effect",
  1252. boot = TRUE,
  1253. sims = 5000
  1254. )
  1255. summary(modelB_med)
  1256. ```
  1257. ##Mediation C: Stroop mediator for Filled Pauses
  1258. Age --> Stroop --> Filled Pauses
  1259. ```{r mediation C}
  1260. #Path 1: Age --> Stroop
  1261. model_C1_fp <- lm(stroop_effect ~ age + education + project, data = merged_data)
  1262. #Path 2: Stroop --> Filled Pauses (controlling for Age)
  1263. model_C2_fp <- lm(perc_filled_pauses ~ stroop_effect + age + education + project, data = merged_data)
  1264. #Path 3: Age --> Filled Pauses
  1265. model_C3_fp <- lm(perc_filled_pauses ~ age + education + project, data = merged_data)
  1266. summary(model_C1_fp)
  1267. summary(model_C2_fp)
  1268. summary(model_C3_fp)
  1269. ```
  1270. ```{r Full Mediation model C}
  1271. # Filter to missing data
  1272. modelC_data <- merged_data %>%
  1273. filter(!is.na(age), !is.na(education), !is.na(stroop_effect), !is.na(perc_filled_pauses))
  1274. #re-fit models
  1275. modelC_mediator <- lm(stroop_effect ~ age + education + project, data = modelC_data)
  1276. modelC_outcome <- lm(perc_filled_pauses ~ stroop_effect + age + education + project, data = modelC_data)
  1277. #Mediation analysis
  1278. library(mediation)
  1279. set.seed(1234)
  1280. modelC_med <- mediate(
  1281. model.m = modelC_mediator,
  1282. model.y = modelC_outcome,
  1283. treat = "age",
  1284. mediator = "stroop_effect",
  1285. boot = TRUE,
  1286. sims = 5000
  1287. )
  1288. summary(modelC_med)
  1289. ```
  1290. ##Mediation D: Stroop mediator for Unfilled Pauses
  1291. Age --> Stroop --> Unfilled Pauses
  1292. ```{r Mediation model D}
  1293. #Path 1: Age --> Stroop
  1294. model_D1_sp <- lm(stroop_effect ~ age + education + project, data = merged_data)
  1295. #Path 2: Stroop --> Silent Pauses (controlling for Age)
  1296. model_D2_sp <- lm(perc_pauses ~ stroop_effect + age + education + project, data = merged_data)
  1297. #Path 3: Age --> Silent Pauses
  1298. model_D3_sp <- lm(perc_pauses ~ age + education + project, data = merged_data)
  1299. summary(model_D1_sp)
  1300. summary(model_D2_sp)
  1301. summary(model_D3_sp)
  1302. ```
  1303. ```{r full mediation model D}
  1304. # Filter to missing data
  1305. modelD_data <- merged_data %>%
  1306. filter(!is.na(age), !is.na(education), !is.na(stroop_effect), !is.na(perc_pauses))
  1307. #re-fit models
  1308. modelD_mediator <- lm(stroop_effect ~ age + education + project, data = modelD_data)
  1309. modelD_outcome <- lm(perc_filled_pauses ~ stroop_effect + age + education + project, data = modelD_data)
  1310. #Mediation analysis
  1311. library(mediation)
  1312. set.seed(1234)
  1313. modelD_med <- mediate(
  1314. model.m = modelD_mediator,
  1315. model.y = modelD_outcome,
  1316. treat = "age",
  1317. mediator = "stroop_effect",
  1318. boot = TRUE,
  1319. sims = 5000
  1320. )
  1321. summary(modelD_med)
  1322. ```
  1323. #Mediation Analysis RSFC Measures
  1324. Based on the LM analyses results the best candidates identified were:
  1325. Age --> DMN_Segregation --> Revisions
  1326. Age --> Lang_to_DMN --> Revisions
  1327. Age --> Lang_to-MD --> Unfilled Pauses
  1328. Do not meet mediation criteria:
  1329. - MD segregation: Age-related change, but no FC --> disfluency effect
  1330. - MD within / Lang within / Lang segregation: No FC --> disfluency link at all
  1331. - DMN-to-MD: Not predictive of disfluency
  1332. - Lang within: No effects
  1333. - MD within: No effects
  1334. - DMN segregation → total disfluencies: Only marginal effect
  1335. ##Mediation Model E: DMN segregation
  1336. ```{r Mediation model E check}
  1337. # Path 1: Age → DMN segregation
  1338. model_E1 <- lm(DMN_segregation_c ~ age + education + project, data = merged_data)
  1339. # Path 2: DMN segregation → Revisions (controlling for Age)
  1340. model_E2 <- lm(perc_total_revisions ~ DMN_segregation_c + age + education + project, data = merged_data)
  1341. # Path 3: Age → Revisions
  1342. model_E3 <- lm(perc_total_revisions ~ age + education + project, data = merged_data)
  1343. summary(model_E1)
  1344. summary(model_E2)
  1345. summary(model_E3)
  1346. ```
  1347. ```{r Full mediation model E}
  1348. # Filter to complete cases for relevant variables
  1349. med_data_E <- merged_data %>%
  1350. filter(!is.na(age), !is.na(education), !is.na(DMN_segregation_c), !is.na(perc_total_revisions))
  1351. # Make sure the mediator is treated as numeric
  1352. merged_data$DMN_segregation_c <- as.numeric(merged_data$DMN_segregation_c)
  1353. # Refit the models
  1354. modelE_mediator <- lm(DMN_segregation_c ~ age + education + project, data = merged_data)
  1355. modelE_outcome <- lm(perc_total_revisions ~ DMN_segregation_c + age + education + project, data = merged_data)
  1356. # Run mediation
  1357. library(mediation)
  1358. set.seed(1234)
  1359. modelE_med <- mediate(
  1360. model.m = modelE_mediator,
  1361. model.y = modelE_outcome,
  1362. treat = "age",
  1363. mediator = "DMN_segregation_c",
  1364. boot = TRUE,
  1365. sims = 5000
  1366. )
  1367. # Summarize results
  1368. summary(modelE_med)
  1369. ```
  1370. ##Mediation model F: Lang_to_DMN
  1371. ```{r Mediation model F}
  1372. # Path 1: Age → Lang_to_DMN
  1373. #model_F1 <- lm(Lang_to_DMN ~ age + education + project, data = merged_data)
  1374. # Path 2: Lang_to_DMN → Revisions (controlling for Age)
  1375. #model_F2 <- lm(perc_total_revisions ~ Lang_to_DMN + age + education + project, data = merged_data)
  1376. # Path 3: Age → Revisions
  1377. #model_F3 <- lm(perc_total_revisions ~ age + education + project, data = merged_data)
  1378. #summary(model_F1)
  1379. #summary(model_F2)
  1380. #summary(model_F3)
  1381. ```
  1382. ```{r Full mediation model F}
  1383. # Step 1: Subset to complete cases for relevant variables
  1384. modelF_data <- merged_data %>%
  1385. filter( !is.na(age), !is.na(education), !is.na(Lang_to_DMN), !is.na(perc_total_revisions)
  1386. )
  1387. # Step 2: Fit the mediator model (Path a)
  1388. mediator_model_F <- lm(Lang_to_DMN ~ age + education + project, data = modelF_data)
  1389. # Step 3: Fit the outcome model (Paths b and c′)
  1390. outcome_model_F <- lm(perc_total_revisions ~ Lang_to_DMN + age + education + project, data = modelF_data)
  1391. # Step 4: Run mediation analysis
  1392. set.seed(1234)
  1393. mediation_result_F <- mediate(
  1394. model.m = mediator_model_F,
  1395. model.y = outcome_model_F,
  1396. treat = "age",
  1397. mediator = "Lang_to_DMN",
  1398. boot = TRUE,
  1399. sims = 5000
  1400. )
  1401. # Step 5: View results
  1402. summary(mediation_result_F)
  1403. ```
  1404. ##Mediation model G: Lang_to_DMN
  1405. ```{r Mediation model G}
  1406. # Path 1: Age → Lang_to_MD
  1407. model_G1 <- lm(Lang_to_MD ~ age + education + project, data = merged_data)
  1408. # Path 2: Lang_to_MD → Unfilled Pauses (controlling for Age)
  1409. model_G2 <- lm(perc_pauses ~ Lang_to_MD + age + education + project, data = merged_data)
  1410. # Path 3: Age → Unfilled Pauses
  1411. model_G3 <- lm(perc_pauses ~ age + education + project, data = merged_data)
  1412. summary(model_G1)
  1413. summary(model_G2)
  1414. summary(model_G3)
  1415. ```
  1416. ##Mediation model H: Stroop on repetitions
  1417. ```{r mediation model H}
  1418. # Path a: Age --> Stroop
  1419. model_Ha <- lm(stroop_effect ~ age + education + project, data = merged_data)
  1420. # Path b: Stroop --> Repetitions
  1421. model_Hb <- lm(perc_total_repetitions ~ stroop_effect + age + education + project, data = merged_data)
  1422. # Path c: Age --> Repetitions
  1423. model_Hc <- lm(perc_total_repetitions ~ age + education + project, data = merged_data)
  1424. summary(model_Ha)
  1425. summary(model_Hb)
  1426. summary(model_Hc)
  1427. ```
  1428. ```{r full mediation model H}
  1429. # Filter to missing data
  1430. modelH_data <- merged_data %>%
  1431. filter(!is.na(age), !is.na(education), !is.na(stroop_effect), !is.na(perc_pauses))
  1432. #re-fit models
  1433. modelH_mediator <- lm(stroop_effect ~ age + education + project, data = modelH_data)
  1434. modelH_outcome <- lm(perc_filled_pauses ~ stroop_effect + age + education + project, data = modelH_data)
  1435. #Mediation analysis
  1436. library(mediation)
  1437. set.seed(1234)
  1438. modelH_med <- mediate(
  1439. model.m = modelH_mediator,
  1440. model.y = modelH_outcome,
  1441. treat = "age",
  1442. mediator = "stroop_effect",
  1443. boot = TRUE,
  1444. sims = 5000
  1445. )
  1446. summary(modelH_med)
  1447. ```
  1448. ##Mediation model I: DMN seg on repetitions
  1449. ```{r mediation model I}
  1450. # Path a: Age --> DMN segregation
  1451. model_Ia <- lm(DMN_segregation_c ~ age + education + project, data = merged_data)
  1452. # Path b: DMN segregation --> Repetitions
  1453. model_Ib <- lm(perc_total_repetitions ~ DMN_segregation_c + age + education + project, data = merged_data)
  1454. # Path c: Age --> Repetitions
  1455. model_Ic <- lm(perc_total_repetitions ~ age + education + project, data = merged_data)
  1456. # Review model summaries
  1457. summary(model_Ia)
  1458. summary(model_Ib)
  1459. summary(model_Ic)
  1460. ```
  1461. ```{r full mediation model I}
  1462. # Subset complete cases
  1463. modelI_data <- merged_data %>%
  1464. filter(!is.na(age), !is.na(education), !is.na(project),
  1465. !is.na(DMN_segregation_c), !is.na(perc_total_repetitions))
  1466. # Convert to numeric (fixes the error)
  1467. modelI_data$DMN_segregation_c <- as.numeric(modelI_data$DMN_segregation_c)
  1468. # Refit models
  1469. modelI_mediator <- lm(DMN_segregation_c ~ age + education + project, data = modelI_data)
  1470. modelI_outcome <- lm(perc_total_repetitions ~ DMN_segregation_c + age + education + project, data = modelI_data)
  1471. # Run mediation
  1472. library(mediation)
  1473. set.seed(1234)
  1474. modelI_med <- mediate(
  1475. model.m = modelI_mediator,
  1476. model.y = modelI_outcome,
  1477. treat = "age",
  1478. mediator = "DMN_segregation_c",
  1479. boot = TRUE,
  1480. sims = 5000
  1481. )
  1482. # Display results
  1483. summary(modelI_med)
  1484. ```
  1485. #Mediation model J: Lang_to_DMN on repetitions
  1486. ```{r mediation model J repetitions}
  1487. # Path a: Age --> Lang-to-DMN
  1488. model_Ja <- lm(Lang_to_DMN ~ age + education + project, data = merged_data)
  1489. # Path b: Lang-to-DMN --> Repetitions
  1490. model_Jb <- lm(perc_total_repetitions ~ Lang_to_DMN + age + education + project, data = merged_data)
  1491. # Path c: Age --> Repetitions
  1492. model_Jc <- lm(perc_total_repetitions ~ age + education + project, data = merged_data)
  1493. # Review model summaries
  1494. summary(model_Ja)
  1495. summary(model_Jb)
  1496. summary(model_Jc)
  1497. ```
  1498. ```{r full mediation model J}
  1499. # Subset complete cases
  1500. modelJ_data <- merged_data %>%
  1501. filter(!is.na(age), !is.na(education), !is.na(project),
  1502. !is.na(Lang_to_DMN), !is.na(perc_total_repetitions))
  1503. # Convert to numeric (fixes potential mediation error)
  1504. modelJ_data$Lang_to_DMN <- as.numeric(modelJ_data$Lang_to_DMN)
  1505. # Refit models
  1506. modelJ_mediator <- lm(Lang_to_DMN ~ age + education + project, data = modelJ_data)
  1507. modelJ_outcome <- lm(perc_total_repetitions ~ Lang_to_DMN + age + education + project, data = modelJ_data)
  1508. # Run mediation
  1509. library(mediation)
  1510. set.seed(1234)
  1511. modelJ_med <- mediate(
  1512. model.m = modelJ_mediator,
  1513. model.y = modelJ_outcome,
  1514. treat = "age",
  1515. mediator = "Lang_to_DMN",
  1516. boot = TRUE,
  1517. sims = 5000
  1518. )
  1519. # Display results
  1520. summary(modelJ_med)
  1521. ```
  1522. #Serial Mediation check: Stroop ~ DMN segregation + age + education
  1523. ```{r lm check}
  1524. model_stroop_DMNseg <- lm(stroop_effect ~ DMN_segregation_c + age + education +project, data = merged_data)
  1525. summary(model_stroop_DMNseg)
  1526. ```
  1527. #Serial Mediation check: Stroop ~ Lang_to_DMN + age + education
  1528. ```{r lm check}
  1529. model_stroop_LangDMN <- lm(stroop_effect ~ Lang_to_DMN + age + education + project, data = merged_data)
  1530. summary(model_stroop_LangDMN)
  1531. ```
  1532. #Serial Mediation Analysis
  1533. ```{r serial mediation}
  1534. # Model 1: Mediator model (Stroop ~ Age + RSFC + education)
  1535. model_m <- lm(stroop_effect ~ age + DMN_segregation + education + project, data = merged_data)
  1536. # Model 2: Outcome model (Disfluency ~ Age + Stroop + RSFC + education)
  1537. model_y <- lm(perc_total_disfluencies ~ age + stroop_effect + DMN_segregation + education + project, data = merged_data)
  1538. # Run mediation analysis
  1539. library(mediation)
  1540. med_out <- mediate(model.m = model_m, model.y = model_y,
  1541. treat = "age", mediator = "stroop_effect",
  1542. boot = TRUE, sims = 5000)
  1543. summary(med_out)
  1544. ```

RSFC_stats_analysis_OSF.Rmd, no license · at the source

Overview

Authors: Megan S Nakamura1, Haoyun Zhang2, Michele T Diaz1
  1. The Pennsylvania State University, University Park, PA
  2. Centre for Cognitive and Brain Sciences, Department of Psychology, University of Macau, Taipa, Macau SAR, China
Institutions: Pennsylvania State University (United States); University of Macau (Macao SAR China)
Journal: Neurobiology of language (Cambridge, Mass.), volume 7, article NOL.a.245
Dates: received 31 July 2025; accepted 11 February 2026; published online 23 April 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1162/nol.a.245 · PMID 42088907 · PMCID PMC13137885 · OpenAlex W7131129959
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: fMRI (modality), cognitive (subfield)
Methods: Spectral & time-frequency, Connectivity, Statistics, fMRI & imaging, Physiology & signal measures
Keywords: aging, disfluency, functional magnetic resonance imaging (fMRI), resting-state functional connectivity (RSFC), speech production
Topic: Neurobiology of Language and Bilingualism (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: NIA NIH HHS (R01 AG034138, T32 AG049676)
Citations: not cited yet (Europe PMC); 99 references in the paper

Abstract

Fluent speech production remains largely preserved across adulthood, yet subtle disruptions such as pauses, repetitions, and revisions become more common with age. These disfluencies may reflect underlying cognitive and neural changes that accompany aging, particularly in executive function (EF) and large-scale brain network organization. In this study, we examined whether EF and resting-state functional connectivity (RSFC) independently or jointly explained age-related differences in naturalistic speech disfluencies in an adult lifespan sample (n = 252, ages 20–81 years). RSFC was used to assess network segregation within three systems implicated in language and cognitive control: language network, default mode network (DMN), and multiple demand (MD) network. These task-independent connectivity patterns provide insight into how the brain’s functional architecture impacts speech production and its age-related vulnerabilities. Our findings indicate that age was associated with increased rates of specific disfluency subtypes, such as unfilled pauses, repetitions, and revisions, as well as lower EF and lower language, MD, and DMN network segregation. Although increasing age was associated with lower EF, EF performance did not predict disfluencies or mediate their age-related increase. In contrast, higher DMN segregation predicted lower overall disfluencies, repetitions, and revisions. Age moderated the relationship between DMN segregation and repetitions, with a significant association only in younger and middle-aged adults, suggesting weaker brain–behavior relationships at older ages. DMN segregation also partially mediated the relationship between age and revisions. These findings suggest that while EF relates to planning-related disruptions, changes in functional brain organization may more directly contribute to age-related increases in self-monitoring disfluencies.

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 3 matches between paragraphs and lines of code.

OSF vp9za

License: none: the authors keep all their rights
State: the link answers, verified on 29 September 2026
Evidence: files inventoried
Languages: R (1)
Size: 8 files, 1 script
Software Heritage: not checked
Found in: “Data Availability Statement”
Holds: 1 notebook
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: broom (1 file), ggplot2 (1 file), psych (1 file), tidyverse (1 file)
Availability: 1 check, the latest on 29 September 2026: the link answers (HTTP 200)
  • 29 September 2026: the link answers (HTTP 200)
1 file
At the source: osf.io/vp9za

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;
  • 1 script, each with its path and the digest of its content;
  • 3 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 Availability Statement

The data and analysis scripts are openly available on the OSF at: https://osf.io/vp9za. Raw imaging data may be available upon request.

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

Recorded: type, language, journal, volume, pages, dates, 3 authors, 5 keywords, 1 funder, 91 references.

Cite

This paper

Nakamura, M. S., Zhang, H., & Diaz, M. T. (2026). Age-Related Differences in Resting-State Functional Connectivity Predict Specific Patterns of Speech Disfluency. Neurobiology of language (Cambridge, Mass.), 7, NOL.a.245. https://doi.org/10.1162/nol.a.245

BibTeX

@article{nakamura2026age,
author = {Nakamura, Megan S and Zhang, Haoyun and Diaz, Michele T},
title = {{Age-Related Differences in Resting-State Functional Connectivity Predict Specific Patterns of Speech Disfluency}},
journal = {Neurobiology of language (Cambridge, Mass.)},
year = {2026},
month = apr,
volume = {7},
pages = {NOL.a.245},
publisher = {MIT Press},
issn = {2641-4368},
doi = {10.1162/nol.a.245},
url = {https://doi.org/10.1162/nol.a.245},
pmid = {42088907},
pmcid = {PMC13137885}
}

RIS

TY - JOUR
AU - Nakamura, Megan S
AU - Zhang, Haoyun
AU - Diaz, Michele T
TI - Age-Related Differences in Resting-State Functional Connectivity Predict Specific Patterns of Speech Disfluency
T2 - Neurobiology of language (Cambridge, Mass.)
J2 - Neurobiol Lang (Camb)
PY - 2026
DA - 2026/04/23
VL - 7
SP - NOL.a.245
SN - 2641-4368
PB - MIT Press
DO - 10.1162/nol.a.245
UR - https://doi.org/10.1162/nol.a.245
LA - en
ER -

CSL-JSON

{
"id": "10.1162/nol.a.245",
"type": "article-journal",
"title": "Age-Related Differences in Resting-State Functional Connectivity Predict Specific Patterns of Speech Disfluency",
"container-title": "Neurobiology of language (Cambridge, Mass.)",
"author": [
{
"family": "Nakamura",
"given": "Megan S"
},
{
"family": "Zhang",
"given": "Haoyun"
},
{
"family": "Diaz",
"given": "Michele T"
}
],
"container-title-short": "Neurobiol Lang (Camb)",
"volume": "7",
"page": "NOL.a.245",
"DOI": "10.1162/nol.a.245",
"PMID": "42088907",
"PMCID": "PMC13137885",
"ISSN": "2641-4368",
"publisher": "MIT Press",
"URL": "https://doi.org/10.1162/nol.a.245",
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
23
]
]
}
}

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/s41467-026-76598-x
Preserved topography, lateralization, selectivity, and functional connectivity of the language network in older brains.
Journal: Nature communications
In common: fMRI, cognitive, 12 references
[2] doi:10.1038/s42003-026-10282-0 [code]
Genetic risk of Alzheimer's disease is associated with loss of brain network segregation in midlife.
Journal: Communications biology
In common: psych, broom, ggplot2, 1 other tool, 5 references
[3] doi:10.1016/j.neuroimage.2026.122186
Aging, brain network connectivity, and cognition: evidence from resting-state dynamic arterial spin labeling.
Journal: NeuroImage
In common: fMRI, cognitive, 7 references
[4] doi:10.1162/imag.a.1285 [code]
Individualized mapping of functional brain networks in older adulthood.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: fMRI, 7 references
[5] doi:10.1186/s40337-026-01671-1 [code]
Aberrant large- and mesoscale network segregation and integration in bulimia nervosa.
Journal: Journal of eating disorders
In common: broom, ggplot2, tidyverse, fMRI, 4 references
[6] doi:10.1162/netn.a.542
High brain network system segregation is differentially linked with cognitive performance across the life span.
Journal: Network neuroscience (Cambridge, Mass.)
In common: fMRI, cognitive, 6 references
[7] doi:10.1162/imag.a.1283 [code]
The language network responds robustly to sentences across tasks.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: broom, tidyverse, fMRI, 4 references
[8] doi:10.1162/imag.a.1338 [code]
Systematic fMRI signal differences across cohorts alter lifespan trajectories of functional brain networks.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: fMRI, 5 references
[9] doi:10.1093/braincomms/fcag279 [code]
Network flexibility facilitates treatment-induced recovery in post-stroke aphasia.
Journal: Brain communications
In common: psych, broom, ggplot2, 1 other tool, fMRI, 1 reference
[10] doi:10.1162/imag.a.1298 [code]
Frontoparietal control-default mode connectivity predicts TMS effects on cognitive control.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: psych, ggplot2, tidyverse, cognitive, 2 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.