OSCR

MIND diet moderates the associations between cerebrovascular and neurodegenerative disease burden and cognition.

Code ↔ Paper

2 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 2 matches
  1. [1] § Materials and methods › Dietary information ↔ MIND_diet_scoring_code_SF.R, lines 78–108 · score 0.82 · extra virgin olive, green leafy vegetables, brain healthy, unhealthy food, fast foods, processed meats
  2. [2] § Materials and methods › Dietary information ↔ MIND_diet_scoring_code.R, lines 3–42 · score 0.82 · extra virgin olive, green leafy vegetables, brain healthy, unhealthy food, fast foods, processed meats

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 · 945 lines · 39 KB · no license · 1 match

  1. cat(
  2. "\nNOTE: Make sure you have replaced (Ctrl+H) all instances of \"rosé\" to \"rose\" to remove the accent in the food consumption file. Otherwise R may not read it properly\n"
  3. )
  4. options(readr.show_col_types = FALSE)
  5. options(dplyr.summarise.inform = FALSE)
  6. # VioScreen FFQ to MIND diet score code:
  7. # ---- Load Packages ----
  8. required_packages <- c("readxl",
  9. "openxlsx",
  10. "readr",
  11. "tidyverse",
  12. "stringr",
  13. "optparse")
  14. installed_packages <- rownames(installed.packages())
  15. missing_packages <- setdiff(required_packages, installed_packages)
  16. if (length(missing_packages) > 0) {
  17. suppressMessages(suppressWarnings(install.packages(missing_packages, quiet = TRUE)))
  18. }
  19. invisible(lapply(required_packages, function(pkg) {
  20. suppressMessages(suppressPackageStartupMessages(library(
  21. pkg,
  22. character.only = TRUE,
  23. quietly = TRUE,
  24. warn.conflicts = FALSE
  25. )))
  26. }))
  27. rm(installed_packages, missing_packages, required_packages)
  28. # Read options
  29. option_list <- list(
  30. make_option(
  31. c("-f", "--food_consumption_csv_path"),
  32. type = "character",
  33. default = "FFQREP_CONSUMPTION_IU.csv",
  34. help = "The path to open the food consumption csv file, e.g., user/home/food_consumption.csv. "
  35. ),
  36. make_option(
  37. c("-n", "--nutrient_vector_csv_path"),
  38. type = "character",
  39. default = "FFQREP_NUTRVECTOR_IU.csv",
  40. help = "The path to open the food consumption csv file, e.g., user/home/nutrient_vector.csv"
  41. ),
  42. make_option(
  43. c("-u", "--unique_food_portions_xl_path"),
  44. type = "character",
  45. default = paste0("unique_food_portions_", Sys.Date(), ".xlsx"),
  46. help = "The path to write the unique food portions xlsx file, e.g., user/home/unique_portions.csv"
  47. ),
  48. make_option(
  49. c("-U", "--edited_unique_food_portions_xl_path"),
  50. type = "character",
  51. help = "The path to write the edited unique food portions xlsx file, e.g., user/home/unique_portions_edited.csv"
  52. ),
  53. make_option(
  54. c("-o", "--output_csv_path"),
  55. type = "character",
  56. default = paste0("FFQ_summary_with_MIND_scores_", Sys.Date(), ".csv"),
  57. help = "The path to write the FFQ summary with mind diet scores xlsx file, e.g., user/home/FFQ_mind.csv"
  58. ),
  59. make_option(
  60. c("-O", "--output_xlsx_path"),
  61. type = "character",
  62. default = paste0("FFQ_summary_with_MIND_scores_", Sys.Date(), ".xlsx"),
  63. help = "The path to write the FFQ summary with mind diet scores xlsx file, e.g., user/home/FFQ_mind.xlsx"
  64. )
  65. )
  66. opt <- parse_args(OptionParser(option_list = option_list))
  67. # ---- Read in the data ----
  68. # Set your working directory
  69. # setwd("C:/insert_working_directory_file_path")
  70. # Read in the VioScreen output data (.csv files)
  71. # NOTE: BEFORE ENTERING THE FOOD CONSUMPTION FILE INTO R:** Replace (Ctrl+H)
  72. # all “rosé” to "rose" to remove the accent; otherwise R may not read it properly
  73. # Read in the Food Consumption file containing the item-level data
  74. diet_data <- read_csv(opt$food_consumption_csv_path)
  75. # Read in the Nutrient Vector file containing the summary data
  76. summary_data <- read_csv(opt$nutrient_vector_csv_path)
  77. # ---- STEP 1: FOOD ITEM SELECTION ----
  78. # (1) Select the foods from the VioScreen FFQ that that fit into the MIND diet scoring.
  79. # (2) Assign each of those foods into one of the 15 MIND diet food categories.
  80. # 10 brain-healthy food categories: Green leafy vegetables, Other vegetables, Nuts, Berries, Beans/legumes, Whole grains, Fish, Poultry, Extra Virgin Olive Oil, Wine,
  81. # 5 unhealthy food categories: Red and processed meats, Butter and margarine, Cheese, Pastries and sweets, Fried/fast foods)
  82. # (3) Filter the dataset for only those foods relavent to the MIND diet scoring.
  83. # 1-Select the foods from the VioScreen FFQ that that fit into the MIND diet scoring.
  84. # Get a list of the unique foods `FoodDescription` from the VioScreen FFQ.
  85. # **NOTE:** The VioScreen FFQ only outputs foods selected by the participant/population. Therefore, our lists of included
  86. # and excluded foods may not include all possible foods from the VioScreen FFQ output. These lists are in Supplemental files.
  87. # As relevant foods appear, they may be added to the respective table (included or excluded).
  88. # sort(unique(diet_data$FoodDescription)) # unique() allows you to see all the unique foods present; sort () puts the unique foods in alphabetical order
  89. # 2-Assign each of those foods into one of the 15 MIND diet food categories
  90. # & 3-Filter the dataset for only those foods relevant to the MIND diet scoring.
  91. # NOTE: The foods from the `FoodDescription` variable must match exactly what is listed here.
  92. mind_categories <- list(
  93. # 10 brain-healthy food categories: Green leafy vegetables, Other vegetables, Nuts, Berries, Beans/legumes, Whole grains, Fish, Poultry, Extra Virgin Olive Oil, Wine,
  94. # "Green leafy vegetables"
  95. "Green leafy vegetables" = c(
  96. "Cooked greens, such as kale, mustard greens and collards",
  97. "Cooked greens, such as spinach, swiss chard and beet greens",
  98. "Green salad (Lettuce or spinach)"
  99. ),
  100. # "Other vegetables"
  101. "Other vegetables" = c(
  102. "Beets (cooked, pickled or raw)",
  103. "Broccoli",
  104. "Carrots - cooked",
  105. "Carrots - raw",
  106. "Cauliflower, cabbage and Brussels sprouts",
  107. "Coleslaw",
  108. "Corn and hominy",
  109. "Fresh tomatoes",
  110. "Green or string beans",
  111. "Green peas",
  112. "Green peppers and green chilies, cooked",
  113. "Green peppers and green chilies, raw",
  114. "Mushrooms cooked in soup, stew or main dishes such as white, shiitake and portabella",
  115. "Onions and leeks",
  116. "Red peppers and red chilies, cooked",
  117. "Red peppers and red chilies, raw",
  118. "Summer squash and zucchini",
  119. "Winter squash such as acorn, butternut and pumpkin"
  120. ),
  121. # "Nuts"
  122. "Nuts" = c("Peanut butter, peanuts and other nuts and seeds"),
  123. # "Berries"
  124. "Berries" = c("Berries such as strawberries and blueberries"),
  125. # "Beans/legumes"
  126. "Beans/legumes" = c(
  127. "All other beans such as baked beans, lima beans and chili without meat",
  128. "Bean soups such as pea, lentil and black bean",
  129. "Cooked soybeans or edamame",
  130. "Hummus",
  131. "Legumes such as black, pinto, garbanzo and lentils",
  132. "Rice and beans, eaten together as a side dish",
  133. "Tempeh",
  134. "Tofu"
  135. ),
  136. # "Whole grains"
  137. "Whole grains" = c(
  138. "Complete or primarily whole grain cold cereal",
  139. "Cooked whole grain cereals",
  140. "Lowfat whole grain crackers",
  141. "Quinoa, sorghum, millet or kasha (buckwheat groats)",
  142. "Regular whole grain crackers",
  143. "Snack bars such as Lara bars, KIND bars, Luna bars",
  144. "Spaghetti and other pasta with cheese or cream sauce, including macaroni and cheese (whole wheat)",
  145. "Spaghetti and other pasta with oil, cheese or cream sauce, including macaroni and cheese (whole wheat)",
  146. "Spaghetti or other pastas with oil or pesto sauces (whole wheat)",
  147. "Spaghetti, lasagna and other pasta with tomato sauce (whole wheat and no meat)",
  148. "Whole grain breads, including bagels and rolls",
  149. "Whole grain breads, including bagels and rolls (100% Whole Grains)",
  150. "Whole grain flour tortillas",
  151. "Whole grain pancakes, French toast or waffles",
  152. "Whole kernel grains such as brown rice"
  153. ),
  154. # "Fish"
  155. "Fish" = c(
  156. "Canned tuna, tuna salad and tuna casserole",
  157. "Dark fish (broiled or baked) such as salmon, mackerel and bluefish",
  158. "Fish or shrimp tacos or tostadas",
  159. "Shellfish, not fried (shrimp, lobster, crab and oysters)",
  160. "Sushi such as tuna, salmon and California roll",
  161. "White fish (broiled or baked) such as sole, halibut, snapper and cod"
  162. ),
  163. # "Poultry"
  164. "Poultry" = c(
  165. "Chicken and turkey (roasted, stewed, grilled or broiled), with skin",
  166. "Chicken and turkey (roasted, stewed, grilled or broiled), without skin"
  167. ),
  168. # "Extra Virgin Olive Oil"
  169. "Extra Virgin Olive Oil" = c(
  170. "Oil, olive (Cereals and Breads)",
  171. "Oil, olive (Fat used in cooking)",
  172. "Oil, olive (Fats on grains and beans)",
  173. "Oil, olive (Fats on potatoes and squash)",
  174. "Oil, olive (Fats used on vegetables)",
  175. "Oil, olive (Cereals and Breads)",
  176. "Oil, olive (Fat used in cooking)",
  177. "Oil, olive (Fats on potatoes, rice, noodles and beans)",
  178. "Oil, olive (Fats used on vegetables)"
  179. ),
  180. # "Wine"
  181. "Wine" = c("Red Wine", "White or rose wine"),
  182. # 5 unhealthy food categories: Red and processed meats, Butter and margarine, Cheese, Pastries and sweets, Fried/fast foods)
  183. # "Red and processed meats"
  184. "Red and processed meats" = c(
  185. "All other lunch meat such as bologna, salami and Spam",
  186. "Bacon and breakfast sausage",
  187. "Beef, pork, ham and lamb - with fat",
  188. "Beef, pork, ham and lamb - without fat",
  189. "Ground meat, lean",
  190. "Ground meat, regular",
  191. "Lunch meat such as bologna, salami and Spam",
  192. "Lunch meats such as ham, turkey and lowfat bologna",
  193. "Regular hot dogs and sausage such as bratwurst and chorizo",
  194. "Turkey bacon or low fat breakfast sausage"
  195. ),
  196. # "Butter and margarine"
  197. "Butter and margarine" = c(
  198. "Butter or ghee (Cereals and Breads)",
  199. "Butter or ghee (Fat used in cooking)",
  200. "Butter or ghee (Fats on grains and beans)",
  201. "Butter or ghee (Fats on potatoes and squash)",
  202. "Butter or ghee (Fats used on vegetables)",
  203. "Margarine, lowfat (Cereals and Breads)",
  204. "Margarine, lowfat (Fat used in cooking)",
  205. "Margarine, lowfat (Fats on grains and beans)",
  206. "Margarine, lowfat (Fats on potatoes and squash)",
  207. "Margarine, lowfat (Fats used on vegetables)",
  208. "Margarine, stick (Cereals and Breads)",
  209. "Margarine, stick (Fat used in cooking)",
  210. "Margarine, stick (Fats on grains and beans)",
  211. "Margarine, stick (Fats on potatoes and squash)",
  212. "Margarine, stick (Fats used on vegetables)",
  213. "Margarine, tub (Cereals and Breads)",
  214. "Margarine, tub (Fat used in cooking)",
  215. "Margarine, tub (Fats on grains and beans)",
  216. "Margarine, tub (Fats on potatoes and squash)",
  217. "Margarine, tub (Fats used on vegetables)",
  218. "Butter (Cereals and Breads)",
  219. "Butter (Fat used in cooking)",
  220. "Butter (Fats on potatoes, rice, noodles and beans)",
  221. "Butter (Fats used on vegetables)",
  222. "Margarine, lowfat (Fats on potatoes, rice, noodles and beans)",
  223. "Margarine, stick (Fats on potatoes, rice, noodles and beans)",
  224. "Margarine, tub (Fats on potatoes, rice, noodles and beans)"
  225. ),
  226. # "Cheese"
  227. "Cheese" = c(
  228. "All other cheese, such as American, cheddar or cream cheese, including cheese used in cooking",
  229. "American, cheddar or cream cheese, including cheese used in cooking",
  230. "Cheese sauce and cream sauce",
  231. "Pizza",
  232. "Regular cottage cheese and ricotta cheese"
  233. ),
  234. # "Pastries and sweets"
  235. "Pastries and sweets" = c(
  236. "Chocolate, candy bars, and toffee",
  237. "Cookies and cakes - lowfat",
  238. "Cookies and cakes - regular",
  239. "Doughnuts, pies and pastries",
  240. "Ice cream and milkshakes",
  241. "Muffins, scones, croissants and biscuits",
  242. "Other soy desserts such as cheesecake",
  243. "Pudding, custard and flan"
  244. ),
  245. # "Fried/fast foods"
  246. "Fried/fast foods" = c(
  247. "Chimichangas or flautas with meat",
  248. "French fries, fried potatoes and hash browns",
  249. "Fried chicken, including chicken nuggets and tenders",
  250. "Fried fish, fish sandwich and fried shellfish (shrimp, oysters)",
  251. "Regular potato, tortilla chips, corn chips and puffs"
  252. )
  253. )
  254. # Combine all the selected MIND diet foods into a single vector (mind_foods) using unlist(mind_categories). This vector is used to filter the dataset.
  255. mind_foods <- unlist(mind_categories)
  256. # Filter the data to include only MIND diet foods and assign each food to its respective MIND diet category.
  257. diet_filtered <- diet_data %>%
  258. filter(FoodDescription %in% mind_foods) %>% # Filter the data to include only rows where FoodDescription matches one of the MIND diet foods in the mind_foods vector
  259. mutate(
  260. # Create a new variable named `FoodCategory` and assign each food to its respective category
  261. FoodCategory = case_when(
  262. FoodDescription %in% mind_categories[["Green leafy vegetables"]] ~ "Green leafy vegetables",
  263. FoodDescription %in% mind_categories[["Other vegetables"]] ~ "Other vegetables",
  264. FoodDescription %in% mind_categories[["Nuts"]] ~ "Nuts",
  265. FoodDescription %in% mind_categories[["Berries"]] ~ "Berries",
  266. FoodDescription %in% mind_categories[["Beans/legumes"]] ~ "Beans/legumes",
  267. FoodDescription %in% mind_categories[["Whole grains"]] ~ "Whole grains",
  268. FoodDescription %in% mind_categories[["Fish"]] ~ "Fish",
  269. FoodDescription %in% mind_categories[["Poultry"]] ~ "Poultry",
  270. FoodDescription %in% mind_categories[["Extra Virgin Olive Oil"]] ~ "Extra Virgin Olive Oil",
  271. FoodDescription %in% mind_categories[["Wine"]] ~ "Wine",
  272. FoodDescription %in% mind_categories[["Red and processed meats"]] ~ "Red and processed meats",
  273. FoodDescription %in% mind_categories[["Butter and margarine"]] ~ "Butter and margarine",
  274. FoodDescription %in% mind_categories[["Cheese"]] ~ "Cheese",
  275. FoodDescription %in% mind_categories[["Pastries and sweets"]] ~ "Pastries and sweets",
  276. FoodDescription %in% mind_categories[["Fried/fast foods"]] ~ "Fried/fast foods",
  277. TRUE ~ "Unknown" # Default to "Unknown" if no match is found
  278. )
  279. )
  280. # Display the names of the columns in the filtered dataset, make sure the new variable`FoodCategory` is at the end.
  281. #names(diet_filtered)
  282. # Check the unique values for `FoodDescription` in the filtered dataset to see if anything unexpected is categorized as "Unknown"
  283. # "Unknown" should not be present.
  284. #unique(diet_filtered$FoodCategory)
  285. # View the filtered dataset. It should only contain the `FoodDescriptions` we selected, and should contain the new variable, `FoodCategory`.
  286. #View(diet_filtered)
  287. # ---- STEP 2: STANDARDIZE PORTION SIZES ----
  288. # In the VioScreen FFQ, each participant selects the portion size they typically eat.
  289. # We will standardize the portion sizes by determining how many one-serving equivalents they eat.
  290. # The output responses for 'PortionSize' are not numeric, so we will do this manually
  291. # for the unique sets of responses.
  292. # (1) Select all unique combinations of foods and portion sizes and export as an excel file.
  293. # (2) Determine a one-serving equivalent for each food.
  294. # NOTE: If new foods are included into the MIND diet scoring (Step 1), determine a 1-serving equivalent for those foods.
  295. # A one-serving equivalent was determined based on the average consumption in the US for adults aged 60+ according to the USDA databases.
  296. # The one-serving equivalents are provided in a data table.
  297. # (3) Calculate the # of servings eaten for those combinations in the excel file, import back in, and merge.
  298. # Define the desired order of `FoodCategory` (for the file export)
  299. food_category_order <- c(
  300. "Green leafy vegetables",
  301. "Other vegetables",
  302. "Nuts",
  303. "Berries",
  304. "Beans/legumes",
  305. "Whole grains",
  306. "Fish",
  307. "Poultry",
  308. "Extra Virgin Olive Oil",
  309. "Wine",
  310. "Red and processed meats",
  311. "Butter and margarine",
  312. "Cheese",
  313. "Pastries and sweets",
  314. "Fried/fast foods"
  315. )
  316. # Arrange the data by FoodCategory and FoodDescription so that food groups are together and the foods are sorted.
  317. # This ordering makes them match the table with correpsonging 1-serving portion sizes for easier input.
  318. # Select all unique combinations of FoodDescriptions and PortionSize
  319. # Convert FoodCategory into a factor with the specified order
  320. diet_arranged <- diet_filtered %>%
  321. mutate(FoodCategory = factor(FoodCategory, levels = food_category_order)) %>% # Set factor levels to put foods in desired order
  322. arrange(FoodCategory, FoodDescription) %>% # Sort first by FoodCategory, then by FoodDescription
  323. select(FoodCategory, FoodDescription, PortionSize) %>% # Keep only relevant columns
  324. unique() # Select unique combinations
  325. # View to make sure it contains all unique combinations of FoodCategory, FoodDescription, PortionSize
  326. # View(diet_arranged)
  327. # Export the unique combinations of foods and portion sizes to excel.
  328. # NOTE: change name of file to not overwrite !
  329. # Once edited, change file name to _edited so that you don't lose your work if you accidentally overwrite it
  330. write.xlsx(diet_arranged, file = opt$unique_food_portions_xl_path)
  331. cat("\nUnique portions file written to",
  332. opt$unique_food_portions_xl_path)
  333. # NOTE: Input and calculate the standardized serving sizes in the excel file.
  334. # Add columns:
  335. # "1Serving" -- For each food, input what a one-serving equivalent is
  336. # "AmountEaten" -- Convert each participants 'PortionSize' to a numerical value (based on serving type) - interpret for each food
  337. # "ServingsEaten" -- To calculate servings eaten, divide AmountEaten by 1Serving
  338. # This now gives a standardized value across participants for servings eaten
  339. # Note: These are only for the unique combinations of foods and portion sizes, so we can now apply it to the whole dataset
  340. if (is.null(opt$edited_unique_food_portions_xl_path)) {
  341. cat("\nNo edited unique food portions file provided. \nPlease edit the newly-created unique portions file [",opt$unique_food_portions_xl_path,"], save it under a new name, and rerun this script with the edited filename (provided to -U) to complete the pipeline.\n")
  342. }
  343. if (!is.null(opt$edited_unique_food_portions_xl_path)) {
  344. # Read in the edited portion sizes table
  345. portions <- read.xlsx(opt$edited_unique_food_portions_xl_path)
  346. # Select only the necessary columns and filter out rows with NA in ServingsEaten
  347. portions <- portions %>%
  348. select(FoodDescription, PortionSize, ServingsEaten) %>%
  349. filter(!is.na(PortionSize))
  350. # Make sure it looks how we expect it does
  351. # portions %>% View
  352. # Merge the portions table with the diet_filtered dataframe to add in the serving sizes
  353. diet_standardized <-
  354. merge(
  355. diet_filtered,
  356. # individual data
  357. portions,
  358. # essentially a look up table of how many serves every response corresponds to
  359. by = c("FoodDescription", "PortionSize"),
  360. # matching based on the combination of the food description and the
  361. # portion size (their unit of response) which will then give the number of serves eaten for that response
  362. all = TRUE # this means that we keep all rows, even if they don't have a match in the data frame to be merged
  363. )
  364. # Select the columns we're interested in and view to make sure it worked
  365. # diet_standardized %>%
  366. # select(UserId, FoodDescription, FoodCategory, PortionSize, ServingsEaten) %>%
  367. # View
  368. # As a final check, make sure there are no missing data for 'ServingsEaten'
  369. # diet_standardized %>%
  370. # filter(is.na(ServingsEaten)) %>% # select those with NA value for ServingsEaten
  371. # select(UserId, FoodDescription, FoodCategory, PortionSize, ServingsEaten) %>% # just the columns we want
  372. # View # open in display
  373. # There should be no rows with NA servings
  374. # ---- STEP 3: STANDARDIZE FREQUENCY ----
  375. # In the VioScreen output,
  376. # "Frequency" is the participants response for how often they consume the food (how many times per day, week, month).
  377. # View the unique Frequency variables in the dataset and ensure all of them are covered in the frequency mapping table below.
  378. sort(unique(diet_standardized$Frequency))
  379. # This is a frequency mapping table that translates the original frequency values into numerical, standardized, weekly frequencies.
  380. # This is similar to, but not identical to using the 'YearlyFrequency' variable / 52 (weeks in a year).
  381. # All variables with a range get averaged. ; Variables per day get multiplied by 7 (days in a week). ; Variables per month get divided by 4.345 (weeks in a month).
  382. frequency_mapping <- tibble::tibble(
  383. # The listing order of Frequency corresponds to the listing order of WeeklyFrequency.
  384. Frequency = c(
  385. "1 day per week",
  386. "1 per day",
  387. "1 per month",
  388. "1 per week",
  389. "1-2 per week",
  390. "1-3 per month",
  391. "2 days per week",
  392. "2 per day",
  393. "2 per week",
  394. "2+ per day",
  395. "2-3 days per month",
  396. "2-3 per day",
  397. "2-3 per month",
  398. "2-4 per week",
  399. "2-6 per week",
  400. "3 days per week",
  401. "3 per day",
  402. "3+ per day",
  403. "3-4 per week",
  404. "4 days per week",
  405. "4 per day",
  406. "4+ per day",
  407. "4-5 per day",
  408. "5 days per week",
  409. "5 per day",
  410. "5+ per day",
  411. "5-6 per week",
  412. "6 days per week",
  413. "6+ per day",
  414. "7+ per day",
  415. "Every day",
  416. "Less than 1 per month",
  417. "Less than 1 per week"
  418. ),
  419. WeeklyFrequency = c(
  420. 1,
  421. 7,
  422. 0.23,
  423. 1,
  424. 1.5,
  425. 0.46,
  426. 2,
  427. 14,
  428. 2,
  429. 14,
  430. 0.575,
  431. 17.5,
  432. 0.575,
  433. 3,
  434. 4,
  435. 3,
  436. 21,
  437. 21,
  438. 3.5,
  439. 4,
  440. 28,
  441. 28,
  442. 31.5,
  443. 5,
  444. 35,
  445. 35,
  446. 5.5,
  447. 6,
  448. 42,
  449. 49,
  450. 7,
  451. 0.115,
  452. 0.5
  453. )
  454. )
  455. # View the frequency mapping table
  456. # View(frequency_mapping)
  457. # Create a new variable called `WeeklyFrequency` by merging the diet_standardized dataframe (the subset with only MIND diet foods) with the frequency mapping table
  458. diet_standardized <- diet_standardized %>%
  459. left_join(frequency_mapping, by = "Frequency")
  460. # Select relevant columns and view to verify
  461. # diet_standardized %>%
  462. # select(UserId, Frequency, WeeklyFrequency) %>%
  463. # distinct %>% # gives the unique combinations only
  464. # View()
  465. # Check for any missing values in WeeklyFrequency
  466. # diet_standardized %>%
  467. # filter(is.na(WeeklyFrequency)) %>%
  468. # select(UserId, FoodDescription, FoodCategory, PortionSize, ServingsEaten, Frequency, YearlyFrequency, WeeklyFrequency) %>%
  469. # View()
  470. # ---- STEP 4: CALCULATE WEEKLY SERVINGS ----
  471. # Calculate total number of servings eaten per week.
  472. # Multiply the ServingsEaten we calculated in Step 2 by the standardized weekly frequency we calculated in Step 3.
  473. diet_standardized <-
  474. diet_standardized %>%
  475. mutate(servings_week = ServingsEaten * WeeklyFrequency)
  476. # View the variables we're interested in to confirm things look as they should: the new variable for the total number of servings eaten per week, should equal ServingsEaten * WeeklyFrequency
  477. # diet_standardized %>% select(
  478. # FoodDescription,
  479. # FoodCategory,
  480. # PortionSize,
  481. # ServingsEaten,
  482. # WeeklyFrequency,
  483. # servings_week,
  484. # ) %>% View
  485. # ---- STEP 5: SUM BY FOOD CATEGORY ----
  486. # For each FoodCategory, sum up the servings eaten for each person to get how many total servings eaten for each category.
  487. # Create a table that sums the total servings by category and person (rather than across the whole table)
  488. category_totals <-
  489. diet_standardized %>%
  490. group_by(UserId, FoodCategory) %>% # we want to calculate the below separately for each person/category combo
  491. summarize(CategoryTotalWeek = sum(servings_week, na.rm = TRUE)) # the new category variables are just summing across those in each category
  492. # Add the new data to the existing database by merging it matched on the combination of ID and category
  493. diet_standardized <-
  494. left_join(diet_standardized,
  495. category_totals,
  496. by = c("UserId", "FoodCategory"))
  497. # View the data for the relevant columns. Ensure the new variable category_totals sums up all servings_week for each category, per person
  498. # diet_standardized %>%
  499. # select(
  500. # UserId,
  501. # FoodDescription,
  502. # FoodCategory,
  503. # ServingsEaten,
  504. # servings_week,
  505. # CategoryTotalWeek
  506. # ) %>%
  507. # arrange(UserId, FoodCategory) %>% # order by UserId and category so that we can manually verify
  508. # View()
  509. # To export the weekly total servings for each category, with the MIND scores:
  510. # Summarized table for CategoryTotalWeek
  511. category_week_total <-
  512. diet_standardized %>%
  513. group_by(UserId, FoodCategory) %>%
  514. summarize(CategoryTotalWeek = first(CategoryTotalWeek),
  515. .groups = 'drop') %>% # Take the first non-NA value
  516. pivot_wider(
  517. names_from = FoodCategory,
  518. values_from = CategoryTotalWeek,
  519. names_prefix = "Category_Total_Weekly_Servings_"
  520. )
  521. # View the summarized dataset for CategoryTotalWeek
  522. # category_week_total %>% View()
  523. # Convert the NAs to zeros, since it means they did not eat any foods in that food category over an average of a week
  524. category_week_total[is.na(category_week_total)] <- 0
  525. # Make sure the zeros added properly
  526. # category_week_total %>% View()
  527. # Merge the summarized category totals back into the original dataframe
  528. diet_standardized <- diet_standardized %>%
  529. left_join(category_week_total, by = "UserId")
  530. # View the updated dataframe with the new variables
  531. # diet_standardized %>% View()
  532. # names(diet_standardized)
  533. # View the data for the relevant columns
  534. # diet_standardized %>%
  535. # select(
  536. # UserId,
  537. # FoodDescription,
  538. # FoodCategory,
  539. # ServingsEaten,
  540. # servings_week,
  541. # CategoryTotalWeek,
  542. # "Category_Total_Weekly_Servings_Green leafy vegetables",
  543. # "Category_Total_Weekly_Servings_Other vegetables",
  544. # "Category_Total_Weekly_Servings_Nuts",
  545. # "Category_Total_Weekly_Servings_Berries",
  546. # "Category_Total_Weekly_Servings_Beans/legumes",
  547. # "Category_Total_Weekly_Servings_Whole grains",
  548. # "Category_Total_Weekly_Servings_Fish",
  549. # "Category_Total_Weekly_Servings_Poultry",
  550. # "Category_Total_Weekly_Servings_Extra Virgin Olive Oil",
  551. # "Category_Total_Weekly_Servings_Wine",
  552. # "Category_Total_Weekly_Servings_Red and processed meats",
  553. # "Category_Total_Weekly_Servings_Butter and margarine",
  554. # "Category_Total_Weekly_Servings_Cheese",
  555. # "Category_Total_Weekly_Servings_Pastries and sweets",
  556. # "Category_Total_Weekly_Servings_Fried/fast foods"
  557. # ) %>%
  558. # arrange(UserId, FoodCategory) %>% # order by UserId and category so that we can manually verify
  559. # View()
  560. # ---- STEP 6: ASSIGN CATEGORY SCORES ----
  561. # Define the cut offs for the MIND diet food categories, using weekly cutoffs.
  562. # Calculate MIND diet subscores for each category. Each of the 15 categories scored as 0, 0.5, or 1.
  563. # Everything to the left of the "~" is the criteria to be evaluated, and to the right is the value it will return if the criteria are met.
  564. # The output is going to a new variable called "MIND_[sub-category]" because this is nested in a mutate() call.
  565. diet_standardized <-
  566. diet_standardized %>%
  567. mutate(
  568. # 10 'brain-healthy' foods
  569. MIND_green_leafy_veg =
  570. case_when(
  571. FoodCategory == "Green leafy vegetables" &
  572. CategoryTotalWeek <= 2 ~ 0,
  573. FoodCategory == "Green leafy vegetables" &
  574. CategoryTotalWeek > 2 & CategoryTotalWeek < 7 ~ 0.5,
  575. FoodCategory == "Green leafy vegetables" &
  576. CategoryTotalWeek >= 7 ~ 1
  577. ),
  578. MIND_other_veg =
  579. case_when(
  580. FoodCategory == "Other vegetables" & CategoryTotalWeek < 5 ~ 0,
  581. FoodCategory == "Other vegetables" &
  582. CategoryTotalWeek >= 5 & CategoryTotalWeek < 7 ~ 0.5,
  583. FoodCategory == "Other vegetables" &
  584. CategoryTotalWeek >= 7 ~ 1
  585. ),
  586. MIND_nuts =
  587. case_when(
  588. FoodCategory == "Nuts" & CategoryTotalWeek < 1 ~ 0,
  589. FoodCategory == "Nuts" &
  590. CategoryTotalWeek >= 1 & CategoryTotalWeek < 5 ~ 0.5,
  591. FoodCategory == "Nuts" & CategoryTotalWeek >= 5 ~ 1
  592. ),
  593. MIND_berries =
  594. case_when(
  595. FoodCategory == "Berries" & CategoryTotalWeek < 1 ~ 0,
  596. FoodCategory == "Berries" &
  597. CategoryTotalWeek >= 1 & CategoryTotalWeek < 5 ~ 0.5,
  598. FoodCategory == "Berries" & CategoryTotalWeek >= 5 ~ 1
  599. ),
  600. MIND_beans_legumes =
  601. case_when(
  602. FoodCategory == "Beans/legumes" & CategoryTotalWeek < 1 ~ 0,
  603. FoodCategory == "Beans/legumes" &
  604. CategoryTotalWeek >= 1 & CategoryTotalWeek < 3 ~ 0.5,
  605. FoodCategory == "Beans/legumes" &
  606. CategoryTotalWeek >= 3 ~ 1
  607. ),
  608. MIND_whole_grains =
  609. case_when(
  610. FoodCategory == "Whole grains" & CategoryTotalWeek < 7 ~ 0,
  611. FoodCategory == "Whole grains" &
  612. CategoryTotalWeek >= 7 & CategoryTotalWeek < 21 ~ 0.5,
  613. FoodCategory == "Whole grains" &
  614. CategoryTotalWeek >= 21 ~ 1
  615. ),
  616. MIND_fish =
  617. case_when(
  618. FoodCategory == "Fish" & CategoryTotalWeek < 0.25 ~ 0,
  619. FoodCategory == "Fish" &
  620. CategoryTotalWeek >= 0.25 & CategoryTotalWeek < 1 ~ 0.5,
  621. FoodCategory == "Fish" & CategoryTotalWeek >= 1 ~ 1
  622. ),
  623. MIND_poultry =
  624. case_when(
  625. FoodCategory == "Poultry" & CategoryTotalWeek < 1 ~ 0,
  626. FoodCategory == "Poultry" &
  627. CategoryTotalWeek >= 1 & CategoryTotalWeek < 2 ~ 0.5,
  628. FoodCategory == "Poultry" & CategoryTotalWeek >= 2 ~ 1
  629. ),
  630. MIND_olive_oil =
  631. case_when(
  632. FoodCategory == "Extra Virgin Olive Oil" &
  633. CategoryTotalWeek < 7 ~ 0,
  634. FoodCategory == "Extra Virgin Olive Oil" &
  635. CategoryTotalWeek >= 7 & CategoryTotalWeek < 14 ~ 0.5,
  636. FoodCategory == "Extra Virgin Olive Oil" &
  637. CategoryTotalWeek >= 14 ~ 1
  638. ),
  639. MIND_wine =
  640. case_when(
  641. FoodCategory == "Wine" &
  642. (CategoryTotalWeek < 0.25 | CategoryTotalWeek > 7) ~ 0,
  643. FoodCategory == "Wine" &
  644. CategoryTotalWeek >= 0.25 &
  645. CategoryTotalWeek <= 1 ~ 0.5,
  646. FoodCategory == "Wine" &
  647. CategoryTotalWeek > 1 & CategoryTotalWeek <= 7 ~ 1
  648. ),
  649. # 5 'unhealthy' foods, reverse scoring
  650. MIND_red_processed_meat =
  651. case_when(
  652. FoodCategory == "Red and processed meats" &
  653. CategoryTotalWeek >= 7 ~ 0,
  654. FoodCategory == "Red and processed meats" &
  655. CategoryTotalWeek >= 4 & CategoryTotalWeek < 7 ~ 0.5,
  656. FoodCategory == "Red and processed meats" &
  657. CategoryTotalWeek < 4 ~ 1
  658. ),
  659. MIND_butter_margarine =
  660. case_when(
  661. FoodCategory == "Butter and margarine" &
  662. CategoryTotalWeek >= 14 ~ 0,
  663. FoodCategory == "Butter and margarine" &
  664. CategoryTotalWeek > 7 & CategoryTotalWeek < 14 ~ 0.5,
  665. FoodCategory == "Butter and margarine" &
  666. CategoryTotalWeek <= 7 ~ 1
  667. ),
  668. MIND_cheese =
  669. case_when(
  670. FoodCategory == "Cheese" & CategoryTotalWeek >= 7 ~ 0,
  671. FoodCategory == "Cheese" &
  672. CategoryTotalWeek > 2 & CategoryTotalWeek < 7 ~ 0.5,
  673. FoodCategory == "Cheese" & CategoryTotalWeek <= 2 ~ 1
  674. ),
  675. MIND_pastries_sweets =
  676. case_when(
  677. FoodCategory == "Pastries and sweets" & CategoryTotalWeek >= 7 ~ 0,
  678. FoodCategory == "Pastries and sweets" &
  679. CategoryTotalWeek >= 5 & CategoryTotalWeek < 7 ~ 0.5,
  680. FoodCategory == "Pastries and sweets" &
  681. CategoryTotalWeek < 5 ~ 1
  682. ),
  683. MIND_fried_fast_foods =
  684. case_when(
  685. FoodCategory == "Fried/fast foods" & CategoryTotalWeek >= 4 ~ 0,
  686. FoodCategory == "Fried/fast foods" &
  687. CategoryTotalWeek > 1 & CategoryTotalWeek < 4 ~ 0.5,
  688. FoodCategory == "Fried/fast foods" &
  689. CategoryTotalWeek <= 1 ~ 1
  690. )
  691. )
  692. # view results (ordered by ID and food category)
  693. # diet_standardized %>%
  694. # select(UserId,
  695. # FoodCategory,
  696. # CategoryTotalWeek,
  697. # MIND_green_leafy_veg, MIND_other_veg, MIND_nuts, MIND_berries,
  698. # MIND_beans_legumes, MIND_whole_grains, MIND_fish, MIND_poultry,
  699. # MIND_olive_oil, MIND_wine, MIND_red_processed_meat, MIND_butter_margarine,
  700. # MIND_cheese, MIND_pastries_sweets, MIND_fried_fast_foods) %>%
  701. # arrange(UserId, FoodCategory) %>%
  702. # View
  703. # Because there are multiple rows for the same food category, we can't easily sum across the assigned MIND values for each
  704. # category to give a combined score (because each category would be counted multiple times for each row)...
  705. # Instead we'll create a reduced dataset that only has one entry for each food category for each person:
  706. reduced_mind_data <-
  707. diet_standardized %>%
  708. group_by(UserId, FoodCategory) %>% # perform the below separately by each person and category combination
  709. filter(row_number() == 1) %>% # take the first instance (so that we just have one row for each unique person/category combination)
  710. select(
  711. UserId,
  712. FoodCategory,
  713. MIND_green_leafy_veg,
  714. MIND_other_veg,
  715. MIND_nuts,
  716. MIND_berries,
  717. MIND_beans_legumes,
  718. MIND_whole_grains,
  719. MIND_fish,
  720. MIND_poultry,
  721. MIND_olive_oil,
  722. MIND_wine,
  723. MIND_red_processed_meat,
  724. MIND_butter_margarine,
  725. MIND_cheese,
  726. MIND_pastries_sweets,
  727. MIND_fried_fast_foods
  728. ) %>% # keep the variables we're interested in
  729. ungroup # if we don't ungroup anything we do this database will also be applied separately by ID and category
  730. # reduced_mind_data %>% View
  731. ### ASSIGN VALUES TO THOSE THAT DID NOT EAT ANY FOODS IN THE FOOD CATEGORIES AND THEREFORE CURRENRLY HAVE NA VALUES
  732. # For this FFQ, if the person does not eat a food, the food will not appear in the Food Consumption file.
  733. # Some currently have NA category values, so we will assign them a score, assuming they did not eat any of the foods in the category.
  734. # For the 'healthy' food categories, if they did not eat it (value is NA), give them a 0. Otherwise, leave it as is.
  735. # For the 'unhealthy' food categories, if they did not eat it (value is NA), give them a 1. Otherwise, leave it as is. (unhealthy foods are reverse scored)
  736. # Define the healthy and unhealthy food categories
  737. healthy_foods <- c(
  738. "MIND_green_leafy_veg",
  739. "MIND_other_veg",
  740. "MIND_nuts",
  741. "MIND_berries",
  742. "MIND_beans_legumes",
  743. "MIND_whole_grains",
  744. "MIND_fish",
  745. "MIND_poultry",
  746. "MIND_olive_oil",
  747. "MIND_wine"
  748. )
  749. unhealthy_foods <- c(
  750. "MIND_red_processed_meat",
  751. "MIND_butter_margarine",
  752. "MIND_cheese",
  753. "MIND_pastries_sweets",
  754. "MIND_fried_fast_foods"
  755. )
  756. # We want to create category-specific MIND subscore tables with one row per person
  757. # The way the reduced dataset was set up means that each person has NAs in the category score for all rows that aren't that category
  758. # so we're just taking the row that is not NA [!is.na()] and keeping the user ID and category total
  759. # Use mutate to replace NAs with 0s for healthy foods and 1 for unhealthy foods.
  760. # This processes all food categories without losing any non-NA values.
  761. mind_scores <- reduced_mind_data %>% # Start with reduced_mind_data (ID and all scores, multiple rows per person)
  762. group_by(UserId) %>% # Group by UserId to process each person individually
  763. # Process healthy foods by applying the function across each column in the 'healthy_foods' list
  764. mutate(across(all_of(healthy_foods), ~ {
  765. if (all(is.na(.)))
  766. return(0) # If all values are NA, assign 0
  767. first_non_na <- na.omit(.)[1] # Get the first non-NA value
  768. if (length(first_non_na) > 0)
  769. return(first_non_na)
  770. else
  771. return(0) # If a non-NA value exists, return it. Otherwise assign a 0.
  772. })) %>%
  773. # Process unhealthy foods by applying the function across each column in the 'unhealthy_foods' list
  774. mutate(across(all_of(unhealthy_foods), ~ {
  775. if (all(is.na(.)))
  776. return(1) # If all values are NA, assign 1
  777. first_non_na <- na.omit(.)[1] # Get the first non-NA value
  778. if (length(first_non_na) > 0)
  779. return(first_non_na)
  780. else
  781. return(1) # If a non-NA value exists, return it. Otherwise assign a 1.
  782. })) %>%
  783. ungroup() # Ungroup the data
  784. # Now mind_scores has the processed columns with 0s or 1s where appropriate for missing values
  785. # mind_scores %>% View
  786. # At this point, 'mind_scores' contains the processed scores for all food categories with NA values
  787. # replaced by 0 for healthy food categories and 1 for unhealthy food categories.
  788. # Make sure there are no NA values in `mind_scores`. They should all have a count of 0.
  789. # mind_scores %>%
  790. # select(all_of(c(healthy_foods, unhealthy_foods))) %>%
  791. # summarise(across(everything(), ~ sum(is.na(.)))) %>%
  792. # View()
  793. # mind_scores now has all the subscores, but each person still has multiple rows.
  794. # Collapse the dataset, removing FoodCategory, to remove the multiple rows, and present only the subscores for each person.
  795. mind_score_all <- mind_scores %>%
  796. select(-FoodCategory) %>% # Remove FoodCategory
  797. distinct() # Keep only unique rows per UserId (there should only be one row per person, but I'd keep anyway)
  798. # mind_score_all %>% View
  799. # Now there is only one row per person, and all of their subscores are shown!
  800. # The number of entries should match your original sample size
  801. # ---- STEP 7: CALCULATE THE TOTAL MIND DIET SCORE ----
  802. # mind_score_all now has all the scores with a single row for each person.
  803. # Create a new column which sums the subscores (by row) in a new column named MIND_sum:
  804. mind_score_all$MIND_sum <- NA # create an NA column to put the result into
  805. # Now compute the total MIND sum:
  806. mind_score_all$MIND_sum <- rowSums(
  807. # the new column (in mind_score_all) is called MIND_sum # it's calculated by summing each row
  808. mind_score_all[, !names(mind_score_all) %in% c("UserId", "MIND_sum")],
  809. # the sum column adds everything except the user ID and the sum column (if you've run this line before and it already exists). Writing it this way means you don't have to list every column name
  810. na.rm = TRUE # this line means that NAs are ignored (otherwise if there is a missing value for one entry the total becomes NA). You shouldn't have any NAs but I'd still keep it
  811. )
  812. # view the data and admire :D
  813. # mind_score_all %>% View
  814. # If you want to also export the category total weekly servings
  815. # category_week_total %>% View
  816. # ---- Merge MIND diet scores into summary sheet ----
  817. # Merge the MIND subscores and total score with the VioScreen summary output file by UserId
  818. # Merge mind_score_all with summary_data based on UserId
  819. merged_data <- summary_data %>%
  820. left_join(category_week_total, by = "UserId") %>%
  821. left_join(mind_score_all, by = "UserId")
  822. # View the final data
  823. # merged_data %>% View
  824. # Write the final merged data to .CSV or .xlsx file
  825. write.csv(merged_data, opt$output_csv_path, row.names = FALSE)
  826. cat("\nFile", opt$output_csv_path, "written")
  827. write.xlsx(merged_data, opt$output_xlsx_path, rowNames = FALSE)
  828. cat("\nFile", opt$output_xlsx_path, "written")
  829. cat("\nComplete")
  830. }
  831. # ---- END! ----

MIND_diet_scoring_code_SF.R at commit e0fe8ae, no license · at the source

Overview

Authors: Desarae A Dempsey1,2,3, Frederick W Unverzagt1,4, Huiping Xu5,6, Lyndsi Moser4, Sujuan Gao1,6, Andrea Avena-Koenigsberger1,2, Evgeny J Chumin1,2, Karmen K Yoder2,3, Puja Agarwal7,8,9, Christy C Tangney9,10, Daniel O Clark5,11, Andrew J Saykin1,2,3,4,12,13, Shannon L Risacher1,2,14,15
ORCID iDs: Puja Agarwal
15 affiliations
  1. Indiana Alzheimer’s Disease Research Center, Indiana University School of Medicine, Indianapolis, IN, United States
  2. Department of Radiology and Imaging Sciences, Indiana University School of Medicine, Indianapolis, IN, United States
  3. Stark Neurosciences Research Institute, Indiana University School of Medicine, Indianapolis, IN, United States
  4. Department of Psychiatry, Indiana University School of Medicine, Indianapolis, IN, United States
  5. Indiana University Center for Aging Research at Regenstrief Institute, Indianapolis, IN, United States
  6. Department of Biostatistics and Health Data Science, Indiana University School of Medicine, Indianapolis, IN, United States
  7. Rush Alzheimer’s Disease Research Center, Rush University Medical Center, Chicago, IL, United States
  8. Department of Internal Medicine, Rush University Medical Center, Chicago, IL, United States
  9. Department of Clinical Nutrition, Rush University Medical Center, Chicago, IL, United States
  10. Department of Family and Preventive Medicine, Rush University Medical Center, Chicago, IL, United States
  11. Division of General Internal Medicine and Geriatrics, Department of Medicine, Indiana University School of Medicine, Indianapolis, IN, United States
  12. Department of Neurology, Indiana University School of Medicine, Indianapolis, IN, United States
  13. Department of Medical and Molecular Genetics, Indiana University School of Medicine, Medical Research and Library Building, Indianapolis, IN, United States
  14. Wake Forest University School of Medicine, Winston-Salem, NC, United States
  15. Wake Forest Alzheimer’s Disease Research Center, Winston-Salem, NC, United States
Journal: Frontiers in nutrition, volume 13, article 1837406
Dates: received 24 March 2026; accepted 27 April 2026; published online 13 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.3389/fnut.2026.1837406 · PMID 42211091 · PMCID PMC13212213 · OpenAlex W7161009412
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: structural MRI / diffusion (modality), human (organism), other condition (population), Alzheimer's / dementia (population), stroke (population), cognitive (subfield)
Methods: Statistics, Preprocessing, Connectivity
Keywords: Alzheimer’s disease, cerebrovascular disease, cognitive resilience, dementia, Mediterranean-DASH intervention for neurodegenerative delay (MIND) diet, nutrition, plant-based diet
Topic: Nutritional Studies and Diet (Public Health, Environmental and Occupational Health, Medicine), according to OpenAlex
Citations: cited by 1 paper (Europe PMC); 107 references in the paper

Abstract

Introduction: The Mediterranean-Dietary Approaches to Stop Hypertension Intervention for Neurodegenerative Delay (MIND) diet is associated with reduced dementia risk, but its role in moderating pathology–cognition relationships in high-risk populations remains unclear. This study examined associations of the MIND diet and Healthy Eating Index (HEI) with cognition and tested whether diet quality modifies the impact of brain pathology on cognitive performance.

Methods: Sixty-six older adults (aged 60–82 years; mean education of 12 years, 65% Black, 73% female) completed MRI and the VioScreen food frequency questionnaire (FFQ). Multivariable linear regression models examined associations between diet scores (MIND, HEI-2020) and cognitive outcomes (cognition composite, memory, executive function), adjusting for age, sex, and education level. Interaction analyses cross-sectionally tested whether diet moderated relationships between structural brain pathology–white matter hyperintensity (WMH), hippocampal, and cortical volumes–and cognition, followed by post-hoc simple slopes analyses.

Results: Higher MIND diet scores were independently associated with better memory performance (p < 0.05). These were significant interactions between WMH volume and MIND diet score across cognitive outcomes (all p-interactions < 0.05). Greater WMH volume was associated with worse cognitive performance at low (all p < 0.01), but not mean or high MIND diet scores (all p > 0.05). Similarly, cortical volume–cognition associations were present in those with low MIND diet scores and attenuated in those with mean or high scores. In contrast, the HEI-2020 score did not modify the effects of brain pathology on cognition, and neither diet quality measure modified hippocampal volume–cognition relationships.

Conclusion: The MIND diet may buffer the cognitive consequences of cerebrovascular pathology and cortical atrophy in older adults at elevated dementia risk and promote cognitive resilience over general healthy eating guidelines.

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

desdemps/VioScreen-MIND-scoring-R

License: none: the authors keep all their rights
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: e0fe8ae5756e234fc6e19e49b8a3c00ba6f2e796, 9 October 2025
Languages: R (2)
Size: 5 files, 2 scripts
Software Heritage: not archived
Found in: the text, “Dietary information”
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: tidyverse (2 files)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
3 files

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 2 scripts, each with its path and the digest of its content;
  • 2 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 datasets presented in this study are available upon reasonable request to the corresponding author. Requests to access these datasets should be directed to ; ; .

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

Recorded: type, language, journal, volume, pages, dates, 13 authors, 7 keywords, 95 references.

Cite

This paper

Dempsey, D. A., Unverzagt, F. W., Xu, H., Moser, L., Gao, S., Avena-Koenigsberger, A., Chumin, E. J., Yoder, K. K., Agarwal, P., Tangney, C. C., Clark, D. O., Saykin, A. J., & Risacher, S. L. (2026). MIND diet moderates the associations between cerebrovascular and neurodegenerative disease burden and cognition. Frontiers in nutrition, 13, 1837406. https://doi.org/10.3389/fnut.2026.1837406

BibTeX

@article{dempsey2026mind,
author = {Dempsey, Desarae A and Unverzagt, Frederick W and Xu, Huiping and Moser, Lyndsi and Gao, Sujuan and Avena-Koenigsberger, Andrea and Chumin, Evgeny J and Yoder, Karmen K and Agarwal, Puja and Tangney, Christy C and Clark, Daniel O and Saykin, Andrew J and Risacher, Shannon L},
title = {{MIND diet moderates the associations between cerebrovascular and neurodegenerative disease burden and cognition}},
journal = {Frontiers in nutrition},
year = {2026},
month = may,
volume = {13},
pages = {1837406},
publisher = {Frontiers Media SA},
issn = {2296-861X},
doi = {10.3389/fnut.2026.1837406},
url = {https://doi.org/10.3389/fnut.2026.1837406},
pmid = {42211091},
pmcid = {PMC13212213}
}

RIS

TY - JOUR
AU - Dempsey, Desarae A
AU - Unverzagt, Frederick W
AU - Xu, Huiping
AU - Moser, Lyndsi
AU - Gao, Sujuan
AU - Avena-Koenigsberger, Andrea
AU - Chumin, Evgeny J
AU - Yoder, Karmen K
AU - Agarwal, Puja
AU - Tangney, Christy C
AU - Clark, Daniel O
AU - Saykin, Andrew J
AU - Risacher, Shannon L
TI - MIND diet moderates the associations between cerebrovascular and neurodegenerative disease burden and cognition
T2 - Frontiers in nutrition
J2 - Front Nutr
PY - 2026
DA - 2026/05/13
VL - 13
SP - 1837406
SN - 2296-861X
PB - Frontiers Media SA
DO - 10.3389/fnut.2026.1837406
UR - https://doi.org/10.3389/fnut.2026.1837406
LA - en
ER -

CSL-JSON

{
"id": "10.3389/fnut.2026.1837406",
"type": "article-journal",
"title": "MIND diet moderates the associations between cerebrovascular and neurodegenerative disease burden and cognition",
"container-title": "Frontiers in nutrition",
"author": [
{
"family": "Dempsey",
"given": "Desarae A"
},
{
"family": "Unverzagt",
"given": "Frederick W"
},
{
"family": "Xu",
"given": "Huiping"
},
{
"family": "Moser",
"given": "Lyndsi"
},
{
"family": "Gao",
"given": "Sujuan"
},
{
"family": "Avena-Koenigsberger",
"given": "Andrea"
},
{
"family": "Chumin",
"given": "Evgeny J"
},
{
"family": "Yoder",
"given": "Karmen K"
},
{
"family": "Agarwal",
"given": "Puja"
},
{
"family": "Tangney",
"given": "Christy C"
},
{
"family": "Clark",
"given": "Daniel O"
},
{
"family": "Saykin",
"given": "Andrew J"
},
{
"family": "Risacher",
"given": "Shannon L"
}
],
"container-title-short": "Front Nutr",
"volume": "13",
"page": "1837406",
"DOI": "10.3389/fnut.2026.1837406",
"PMID": "42211091",
"PMCID": "PMC13212213",
"ISSN": "2296-861X",
"publisher": "Frontiers Media SA",
"URL": "https://doi.org/10.3389/fnut.2026.1837406",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
13
]
]
}
}

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.1002/hbm.70508 [code]
Cyclic 2.5D Perceptual Loss for Cross-Modal 3D Medical Image Synthesis: T1w MRI to Tau PET.
Journal: Human brain mapping
In common: Alzheimer's / dementia, structural MRI / diffusion, cognitive, 7 references
[2] doi:10.1186/s13195-026-02054-z [code]
Pathways to resilience: relationships between cognitive reserve, psychological debt, and Alzheimer's disease biomarkers.
Journal: Alzheimer's research & therapy
In common: tidyverse, Alzheimer's / dementia, 5 references
[3] doi:10.1038/s41467-026-74957-2 [code]
Joint trajectories of brain atrophy, white matter hyperintensities and cognition quantify brain maintenance.
Journal: Nature communications
In common: stroke, Alzheimer's / dementia, structural MRI / diffusion, 1 other category, 5 references
[4] doi:10.1162/imag.a.1235 [code]
Intracranial volume: To adjust or not to adjust? It is not a matter of if, but how.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: tidyverse, structural MRI / diffusion, 5 references
[5] doi:10.3389/fnut.2026.1830204
Bias-reduced Regression Analysis in Nutrition (BRAiN) index: self-reported diet and predicted cognitive function.
Journal: Frontiers in nutrition
In common: Alzheimer's / dementia, cognitive, 4 references
[6] doi:10.1002/alz.71822 [code]
SynthPET: A 3D generative AI approach for FDG-PET image synthesis from T1-weighted MRI and ASL CBF in Alzheimer's disease.
Journal: Alzheimer's & dementia : the journal of the Alzheimer's Association
In common: stroke, Alzheimer's / dementia, structural MRI / diffusion, 5 references
[7] doi:10.1016/j.tjpad.2026.100622 [code]
The time interval from amyloid to tau PET positivity varies by age, sex and APOE-ε4 status.
Journal: The journal of prevention of Alzheimer's disease
In common: tidyverse, Alzheimer's / dementia, 4 references
[8] doi:10.1186/s13024-026-00942-4 [code]
Regional diffusion imaging measures to disentangle SVD-related hypertensive arteriopathy versus cerebral amyloid angiopathy.
Journal: Molecular neurodegeneration
In common: stroke, Alzheimer's / dementia, structural MRI / diffusion, 2 other categories, 3 references
[9] doi:10.1212/wnl.0000000000218472 [code]
Lesion-Level Subtypes of White Matter Hyperintensity Evolution Beyond Spatial Location.
Journal: Neurology
In common: stroke, Alzheimer's / dementia, structural MRI / diffusion, 3 references
[10] doi:10.3389/fnagi.2026.1847611 [code]
APOE ε4-associated hippocampal atrophy trajectories across the Alzheimer's disease continuum: a systematic review, meta-analysis, and longitudinal validation.
Journal: Frontiers in aging neuroscience
In common: tidyverse, Alzheimer's / dementia, structural MRI / diffusion, 4 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.