Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

analyse_13_sample_picture_word_topo.R 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # This script takes the sample-level data from analyse_02, analyse_11, and analyse_12, fits linear mixed-effects models, and saves the fixed effects
  2. library(lme4)
  3. library(dplyr)
  4. library(purrr)
  5. library(readr)
  6. library(parallel)
  7. n_cores <- parallel::detectCores(all.tests=FALSE, logical=TRUE) - 2
  8. # n_cores <- 7
  9. # function to normalise between 0 and 1
  10. norm01 <- function(x, ...) (x-min(x, ...))/(max(x, ...)-min(x, ...))
  11. # get the stimuli's percentage of name agreement values
  12. stim <- read_csv("boss.csv", col_types = cols(perc_name_agree_denom_fq_inputs = col_number())) %>%
  13. select(filename, perc_name_agree_denom_fq_inputs) %>%
  14. rename(perc_name_agree = perc_name_agree_denom_fq_inputs)
  15. # import the max electrode data from the preprocessing, and set up the variables for the model
  16. get_sample_data <- function(path="sample_data", ch_i = NA) {
  17. list.files(path, pattern=".+\\.csv$", full.names=TRUE) %>%
  18. map_dfr(function(f) {
  19. message(sprintf(" - importing %s", f))
  20. x <- read_csv(
  21. f,
  22. col_types=cols(
  23. subj_id = col_character(),
  24. stim_grp = col_integer(),
  25. resp_grp = col_integer(),
  26. item_nr = col_integer(),
  27. ch_name = col_character(),
  28. time = col_double(),
  29. uV = col_double(),
  30. condition = col_character(),
  31. image = col_character(),
  32. string = col_character(),
  33. .default = col_double()
  34. ),
  35. progress = FALSE
  36. ) %>%
  37. select(-stim_grp, -resp_grp, -item_nr)
  38. if (all(!is.na(ch_i))) x <- filter(x, ch_name %in% ch_i)
  39. x
  40. }) %>%
  41. left_join(stim, by=c("image" = "filename")) |>
  42. mutate(
  43. prop_agree = perc_name_agree/100,
  44. pred_norm = norm01(prop_agree, na.rm=TRUE),
  45. # as factors for size efficiency
  46. ch_name = factor(ch_name),
  47. image = factor(image),
  48. string = factor(string),
  49. time = factor(time),
  50. subj_id = factor(subj_id)
  51. ) |>
  52. select(
  53. time, condition, pred_norm,
  54. subj_id, ch_name, image, string,
  55. uV
  56. )
  57. }
  58. # get models for each timepoint, for each electrode, and extract fixed effects, for each time locked event
  59. paths <- c("sample_data", "sample_data_picture", "sample_data_response")
  60. for (p in paths) {
  61. message(sprintf("Modelling time points and channels individually for %s", p))
  62. # get list of data frames for each time point
  63. d_list <- get_sample_data(path=p) |>
  64. mutate(cong_dev = as.numeric(scale(ifelse(condition=="A2", 0, 1), center=TRUE, scale=FALSE))) |>
  65. group_split(time, ch_name)
  66. gc_out <- gc()
  67. message(sprintf(" - fitting models on %g cores", n_cores))
  68. # fit models in parallel
  69. cl <- makeCluster(n_cores)
  70. cl_packages <- clusterEvalQ(cl, {
  71. library(dplyr)
  72. library(lme4)
  73. })
  74. fe_res <- parLapply(cl, d_list, function(d_i) {
  75. # m <- lme4::lmer(
  76. # uV ~ cong_dev * pred_norm +
  77. # (cong_dev * pred_norm | subj_id) +
  78. # (cong_dev | image) +
  79. # (1 | string),
  80. # REML=FALSE,
  81. # control = lmerControl(optimizer="bobyqa"),
  82. # data=d_i
  83. # )
  84. m <- lme4::lmer(
  85. uV ~ cong_dev * pred_norm +
  86. (1 | subj_id) +
  87. (1 | image) +
  88. (1 | string),
  89. REML=FALSE,
  90. control = lmerControl(optimizer="bobyqa"),
  91. data=d_i
  92. )
  93. m |>
  94. summary() |>
  95. with(coefficients) |>
  96. as_tibble(rownames = "fe") |>
  97. mutate(
  98. time = unique(d_i$time),
  99. ch_name = unique(d_i$ch_name)
  100. )
  101. }) |>
  102. reduce(bind_rows)
  103. stopCluster(cl)
  104. fe_res_tidy <- fe_res |>
  105. mutate(
  106. fe_lab = factor(recode(
  107. fe,
  108. `(Intercept)` = "Intercept",
  109. cong_dev = "Congruency",
  110. pred_norm = "Predictability",
  111. `cong_dev:pred_norm` = "Congruency * Predictability"
  112. ), levels = c("Intercept", "Congruency", "Predictability", "Congruency * Predictability")),
  113. fe_lab_newline = factor(fe_lab, labels = c("Intercept", "Congruency", "Predictability", "Congruency\n* Predictability")),
  114. bound_lower = Estimate - 1.96 * `Std. Error`,
  115. bound_upper = Estimate + 1.96 * `Std. Error`
  116. )
  117. p_short <- sub("_data", "", p, fixed=TRUE)
  118. write_csv(fe_res_tidy, sprintf("analyse_13_%s_res.csv", p_short))
  119. rm("d_list")
  120. gc_out <- gc()
  121. }