analyse_08_pictureword_rt.R 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. library(dplyr)
  2. library(readr)
  3. library(purrr)
  4. library(tidyr)
  5. library(brms)
  6. library(ggdist)
  7. library(ggplot2)
  8. theme_set(theme_classic() + theme(strip.background = element_rect(fill = "white"), plot.background = element_blank()))
  9. library(cowplot)
  10. cong_cols <- c("#E69F00", "#009E73")
  11. norm01 <- function(x, ...) (x-min(x, ...)) / (max(x, ...) - min(x, ...))
  12. norm01_manual <- function(x, min_x, max_x) (x-min_x) / (max_x - min_x)
  13. # summarise posteriors from behavioural validation experiment -------------
  14. # valid_m <- readRDS(file.path("..", "01 Validation", "02 Analysis", "mods", "m_bme.rds"))
  15. #
  16. # valid_m_ests <- valid_m %>%
  17. # as_draws_df("^b\\_|^sd\\_|^cor\\_", regex=TRUE) %>%
  18. # select(-starts_with(".")) %>%
  19. # pivot_longer(cols=everything(), names_to="par", values_to="est")
  20. #
  21. # lapply(unique(valid_m_ests$par), function(p) {
  22. # d_i <- filter(valid_m_ests, par == p)
  23. #
  24. # ggplot(d_i, aes(est)) +
  25. # geom_function(fun=dnorm, args=list(mean=mean(d_i$est), sd=sd(d_i$est)), colour="red") +
  26. # geom_density() +
  27. # geom_vline(xintercept = median(d_i$est), colour="blue") +
  28. # facet_wrap(vars(par), scales="free") +
  29. # labs(x=NULL, y=NULL)
  30. # }) %>%
  31. # wrap_plots()
  32. #
  33. # valid_m_norm <- valid_m_ests %>%
  34. # group_by(par) %>%
  35. # summarise(
  36. # median_est = median(est),
  37. # mean_est = mean(est),
  38. # sd_est = sd(est),
  39. # sd_est10 = sd_est*10
  40. # )
  41. #
  42. # rm(valid_m)
  43. # gc()
  44. # import data -------------------------------------------------------------
  45. # get the stimuli's percentage of name agreement values
  46. stim <- read_csv("boss.csv", col_types = cols(perc_name_agree_denom_fq_inputs = col_number())) %>%
  47. select(filename, perc_name_agree_denom_fq_inputs) %>%
  48. rename(perc_name_agree = perc_name_agree_denom_fq_inputs)
  49. d <- file.path("raw_data", "stim-pc", "data", "pictureword") %>%
  50. list.files(pattern = "^.*\\.csv$", full.names = TRUE) %>%
  51. map_df(read_csv, col_types = cols(sex="c")) %>%
  52. filter(acc == 1) %>%
  53. left_join(stim, by=c("image" = "filename")) %>%
  54. mutate(
  55. prop_agree = perc_name_agree/100,
  56. pred_norm = norm01(prop_agree),
  57. cong_dev = scale(if_else(condition == "A1", 1, 0), center = TRUE, scale = FALSE)
  58. )
  59. # setup priors for RT model -----------------------------------------------
  60. priors <- c(
  61. # FIXED EFFECTS
  62. # mu
  63. set_prior("normal(5.75, 0.71)", class = "b", coef = "Intercept"),
  64. set_prior("normal(0.472, 0.875)", class = "b", coef = "cong_dev"),
  65. set_prior("normal(-0.543, 0.78)", class = "b", coef = "pred_norm"),
  66. set_prior("normal(-0.671, 1.29)", class = "b", coef = "cong_dev:pred_norm"),
  67. # sigma
  68. set_prior("normal(-0.85, 0.535)", class = "b", coef = "Intercept", dpar="sigma"),
  69. set_prior("normal(0.0404, 0.94)", class = "b", coef = "cong_dev", dpar="sigma"),
  70. set_prior("normal(0.229, 0.755)", class = "b", coef = "pred_norm", dpar="sigma"),
  71. set_prior("normal(0.142, 1.345)", class = "b", coef = "cong_dev:pred_norm", dpar="sigma"),
  72. # delta
  73. set_prior("normal(0, 7.5)", class = "b", coef = "Intercept", dpar="ndt"), # wider than other priors, and equivalent to a delay of just exp(3) = 20 ms rather than the exp(5.63) from the validation posterior, because I expected the forced delay of response (until colour change) to greatly reduce non-decision time, but I'm not sure by how much
  74. set_prior("normal(-0.4, 7.5)", class = "b", coef = "cong_dev", dpar="ndt"),
  75. set_prior("normal(0.132, 7.5)", class = "b", coef = "pred_norm", dpar="ndt"),
  76. set_prior("normal(-0.671, 7.5)", class = "b", coef = "cong_dev:pred_norm", dpar="ndt"),
  77. # STANDARD DEVIATIONS OF RANDOM EFFECT DISTRIBUTIONS
  78. # mu
  79. # -subj_id
  80. set_prior("student_t(10, 0.29, 0.1)", class = "sd", coef = "Intercept", group = "subj_id"),
  81. set_prior("student_t(10, 0.079, 0.1)", class = "sd", coef = "cong_dev", group = "subj_id"),
  82. set_prior("student_t(10, 0.128, 0.1)", class = "sd", coef = "pred_norm", group = "subj_id"),
  83. set_prior("student_t(10, 0.077, 0.25)", class = "sd", coef = "cong_dev:pred_norm", group = "subj_id"),
  84. # -image
  85. set_prior("student_t(10, 0.116, 0.05)", class = "sd", coef = "Intercept", group = "image"),
  86. set_prior("student_t(10, 0.137, 0.1)", class = "sd", coef = "cong_dev", group = "image"),
  87. # -string
  88. set_prior("student_t(10, 0.379, 0.05)", class = "sd", coef = "Intercept", group = "string"),
  89. # sigma
  90. # -subj_id
  91. set_prior("student_t(10, 0.98, 0.1)", class = "sd", coef = "Intercept", group = "subj_id", dpar = "sigma"),
  92. set_prior("student_t(10, 0.121, 0.1)", class = "sd", coef = "cong_dev", group = "subj_id", dpar = "sigma"),
  93. set_prior("student_t(10, 0.075, 0.1)", class = "sd", coef = "pred_norm", group = "subj_id", dpar = "sigma"),
  94. set_prior("student_t(10, 0.084, 0.25)", class = "sd", coef = "cong_dev:pred_norm", group = "subj_id", dpar = "sigma"),
  95. # -image
  96. set_prior("student_t(10, 0.068, 0.05)", class = "sd", coef = "Intercept", group = "image", dpar = "sigma"),
  97. set_prior("student_t(10, 0.1, 0.1)", class = "sd", coef = "cong_dev", group = "image", dpar = "sigma"),
  98. # -string
  99. set_prior("student_t(10, 0.039, 0.05)", class = "sd", coef = "Intercept", group = "string", dpar = "sigma"),
  100. # delta
  101. set_prior("student_t(10, 0.096, 0.1)", class = "sd", coef = "Intercept", group = "subj_id", dpar = "ndt"),
  102. set_prior("student_t(10, 0.071, 0.1)", class = "sd", coef = "cong_dev", group = "subj_id", dpar = "ndt"),
  103. set_prior("student_t(10, 0.028, 0.1)", class = "sd", coef = "pred_norm", group = "subj_id", dpar = "ndt"),
  104. set_prior("student_t(10, 0.038, 0.25)", class = "sd", coef = "cong_dev:pred_norm", group = "subj_id", dpar = "ndt"),
  105. # -image
  106. set_prior("student_t(10, 0.245, 0.05)", class = "sd", coef = "Intercept", group = "image", dpar = "ndt"),
  107. set_prior("student_t(10, 0.023, 0.1)", class = "sd", coef = "cong_dev", group = "image", dpar = "ndt"),
  108. # -string
  109. set_prior("student_t(10, 0.015, 0.05)", class = "sd", coef = "Intercept", group = "string", dpar = "ndt")
  110. )
  111. n_cores <- 7
  112. seed <- 3101
  113. n_iter <- 10000
  114. n_warmup <- 7500
  115. adapt_delta <- 0.99
  116. max_treedepth <- 10
  117. n_chains <- 5
  118. refresh <- 100
  119. f <- brmsformula(
  120. rt ~ 0 + Intercept + cong_dev * pred_norm +
  121. (cong_dev * pred_norm | subj_id) +
  122. (cong_dev | image) +
  123. (1 | string),
  124. sigma ~ 0 + Intercept + cong_dev * pred_norm +
  125. (cong_dev * pred_norm | subj_id) +
  126. (cong_dev | image) +
  127. (1 | string),
  128. ndt ~ 0 + Intercept + cong_dev * pred_norm +
  129. (cong_dev * pred_norm | subj_id) +
  130. (cong_dev | image) +
  131. (1 | string)
  132. )
  133. m_rt <- brm(
  134. formula = f,
  135. data = d,
  136. family = shifted_lognormal(),
  137. prior = priors,
  138. iter = n_iter,
  139. warmup = n_warmup,
  140. chains = n_chains,
  141. control = list(
  142. adapt_delta = adapt_delta,
  143. max_treedepth = max_treedepth
  144. ),
  145. init = replicate(
  146. n_chains,
  147. list(b_ndt = as.array(rep(-5, 4))),
  148. simplify=FALSE
  149. ),
  150. sample_prior = "no",
  151. silent = TRUE,
  152. cores = n_cores,
  153. seed = seed,
  154. thin = 1,
  155. file = file.path("mods", "m_rt.rds"),
  156. refresh = refresh
  157. )
  158. # plot results ------------------------------------------------------------
  159. # get predicted densities
  160. coding_lookup <- d %>%
  161. group_by(condition) %>%
  162. summarise(cong_dev = unique(cong_dev))
  163. props <- 1:10/10
  164. fe_tidy <- fixef(m_rt, robust=TRUE) %>%
  165. as_tibble(rownames="term")
  166. fe <- sapply(fe_tidy$term, function(term_i) {
  167. fe_tidy %>%
  168. filter(term==term_i) %>%
  169. pull(Estimate)
  170. })
  171. fe_preds <- tibble(
  172. condition = rep(c("A1", "A2"), each = length(props)),
  173. condition_label = if_else(condition=="A1", "Congruent", "Incongruent"),
  174. prop_agree = rep(props, 2)
  175. ) %>%
  176. left_join(coding_lookup, by = "condition") %>%
  177. mutate(
  178. pred_norm = norm01_manual(prop_agree, min(d$prop_agree), max(d$prop_agree)),
  179. int_mu = fe["Intercept"],
  180. int_sigma = fe["sigma_Intercept"],
  181. int_ndt = fe["ndt_Intercept"],
  182. cong_mu = fe["cong_dev"],
  183. cong_sigma = fe["sigma_cong_dev"],
  184. cong_ndt = fe["ndt_cong_dev"],
  185. pred_norm_mu = fe["pred_norm"],
  186. pred_norm_sigma = fe["sigma_pred_norm"],
  187. pred_norm_ndt = fe["ndt_pred_norm"],
  188. interact_mu = fe["cong_dev:pred_norm"],
  189. interact_sigma = fe["sigma_cong_dev:pred_norm"],
  190. interact_ndt = fe["ndt_cong_dev:pred_norm"],
  191. pred_mu = int_mu + cong_dev*cong_mu + pred_norm*pred_norm_mu + cong_dev*pred_norm*interact_mu,
  192. pred_sigma = int_sigma + cong_dev*cong_sigma + pred_norm*pred_norm_sigma + cong_dev*pred_norm*interact_sigma,
  193. pred_ndt = int_ndt + cong_dev*cong_ndt + pred_norm*pred_norm_ndt + cong_dev*pred_norm*interact_ndt
  194. )
  195. quantities <- 0:1000
  196. fe_cond_dens <- map_dfr(quantities, function(q) mutate(fe_preds, rt = q)) %>%
  197. mutate(
  198. pred_dens = dshifted_lnorm(
  199. x = rt,
  200. meanlog = pred_mu,
  201. sdlog = exp(pred_sigma),
  202. shift = exp(pred_ndt)
  203. )
  204. )
  205. # build panel A
  206. panel_A_margin <- theme_get()$plot.margin
  207. panel_A_margin[[2]] <- unit(0.2, "npc")
  208. pub_panel_A <- fe_cond_dens %>%
  209. mutate(condition_label = sprintf("Picture-%s", condition_label)) %>%
  210. ggplot(aes(rt, pred_dens, colour = prop_agree)) +
  211. geom_line(aes(group = as.factor(prop_agree))) +
  212. facet_wrap(~condition_label) +
  213. labs(x = "Response Time (ms)", y = "Predicted Density", colour = "Predictability", tag="a") +
  214. scale_colour_continuous(
  215. type="viridis", breaks=sort(unique(fe_cond_dens$prop_agree)),
  216. labels=sprintf("%s%%", sort(unique(fe_cond_dens$prop_agree))*100),
  217. # guide=guide_colourbar(barheight = 7.175)
  218. guide = guide_legend(override.aes = list(linewidth=1), reverse = TRUE)
  219. ) +
  220. theme_classic() +
  221. theme(
  222. plot.margin = panel_A_margin,
  223. legend.position = c(1.15, 0.5875),
  224. legend.key.height = unit(11, "pt"),
  225. legend.text.align = 1,
  226. text=element_text(size=12),
  227. axis.text.x = element_text(angle=0, hjust=0.5, vjust=0.5),
  228. legend.title.align = 0,
  229. legend.spacing.y = unit(1, "pt"),
  230. # plot.title = element_text(hjust=-0.05),
  231. axis.text.y=element_blank(),
  232. axis.ticks.y=element_blank(),
  233. strip.background = element_rect(fill = "white")
  234. )
  235. # get uncertainty in predictions for panel B
  236. # draw all samples from posteriors
  237. draws_spr <- as_draws_df(m_rt, "^b\\_.*", regex=TRUE)
  238. # function for calculating uncertainty around predictions for a given vector of response times
  239. get_pred_cr_i <- function(rt_i) {
  240. cat(sprintf("\rCalculating densities %s - %s", min(rt_i), max(rt_i)))
  241. expand_grid(
  242. .draw = unique(draws_spr$.draw),
  243. val_cong = unique(d$cong_dev),
  244. prop_agree = 1:10/10,
  245. rt = rt_i
  246. ) %>%
  247. left_join(draws_spr, by=".draw") %>%
  248. mutate(
  249. val_pred = norm01_manual(prop_agree, min(d$prop_agree), max(d$prop_agree)),
  250. mu = b_Intercept +
  251. (val_cong * b_cong_dev) +
  252. (val_pred * b_pred_norm) +
  253. (val_cong * val_pred * `b_cong_dev:pred_norm`),
  254. sigma = b_sigma_Intercept +
  255. (val_cong * b_sigma_cong_dev) +
  256. (val_pred * b_sigma_pred_norm) +
  257. (val_cong * val_pred * `b_sigma_cong_dev:pred_norm`),
  258. delta = b_ndt_Intercept +
  259. (val_cong * b_ndt_cong_dev) +
  260. (val_pred * b_ndt_pred_norm) +
  261. (val_cong * val_pred * `b_ndt_cong_dev:pred_norm`),
  262. samp_dens = dshifted_lnorm(
  263. x = rt,
  264. meanlog = mu,
  265. sdlog = exp(sigma),
  266. shift = exp(delta)
  267. )
  268. ) %>%
  269. group_by(rt, val_cong, val_pred, prop_agree) %>%
  270. summarise(
  271. pred_dens = median(samp_dens),
  272. cr_i_low = hdi(samp_dens, .width=.89)[1],
  273. cr_i_high = hdi(samp_dens, .width=.89)[2],
  274. .groups = "drop"
  275. )
  276. }
  277. # get relative likelihoods (chunked into groups of size 25)
  278. draws_pred_ci <- quantities[quantities>0] %>%
  279. split(., ceiling(seq_along(.)/25)) %>%
  280. map_dfr(get_pred_cr_i)
  281. # join panel A and panel B
  282. max_y_uncertainty <- round(max(draws_pred_ci$cr_i_high)+.00005, 5)
  283. pub_panel_A_uncertainty <- pub_panel_A +
  284. lims(y = c(0, max_y_uncertainty))
  285. pub_panel_B_uncertainty <- draws_pred_ci %>%
  286. left_join(coding_lookup, by=c("val_cong" = "cong_dev")) %>%
  287. mutate(
  288. condition_label = ifelse(condition=="A1", "Congruent", "Incongruent"),
  289. pred_label = factor(sprintf("%s%%", prop_agree*100), levels = sprintf("%s%%", seq(10, 100, 10)))
  290. ) %>%
  291. ggplot(aes(rt, pred_dens, colour = condition_label, fill = condition_label)) +
  292. geom_ribbon(aes(ymin = cr_i_low, ymax = cr_i_high), alpha=0.4) +
  293. facet_wrap(vars(pred_label), nrow=2) +
  294. scale_colour_manual(values = cong_cols) +
  295. scale_fill_manual(values = cong_cols) +
  296. guides(fill = guide_legend(override.aes = list(alpha = 0.5))) +
  297. lims(y = c(0, max_y_uncertainty)) +
  298. labs(
  299. x = "Response Time (ms)",
  300. y = "Predicted Density",
  301. colour = "Picture-Word Congruency",
  302. fill = "Picture-Word Congruency",
  303. tag = "b"
  304. ) +
  305. theme(
  306. legend.position = "bottom",
  307. legend.key.height = unit(4, "pt"),
  308. axis.text.y=element_blank(),
  309. axis.ticks.y=element_blank(),
  310. axis.text.x = element_text(angle=22.5, hjust=1, vjust=1),
  311. # legend.key.height = grid::unit(0.1, "lines"),
  312. # plot.title = element_text(hjust=-0.04),
  313. strip.background = element_rect(fill = "white"),
  314. legend.margin = margin()
  315. )
  316. pub_fig_uncertainty <- plot_grid(pub_panel_A_uncertainty, pub_panel_B_uncertainty, nrow=2, rel_heights=c(2.5, 3.5))
  317. ggsave(file.path("figs", "08_rt_fixed_effects_uncertainty.pdf"), pub_fig_uncertainty, device = "pdf", units = "in", width = 6.5, height=6)
  318. ggsave(file.path("figs", "08_rt_fixed_effects_uncertainty.png"), pub_fig_uncertainty, device = "png", type="cairo", units = "in", width = 6.5, height=6)
  319. # compare priors and posteriors -------------------------------------------
  320. m_rt_prior_samps <- brm(
  321. formula = f,
  322. data = d,
  323. family = shifted_lognormal(),
  324. prior = priors,
  325. iter = n_iter,
  326. warmup = n_warmup,
  327. chains = n_chains,
  328. control = list(
  329. adapt_delta = adapt_delta,
  330. max_treedepth = max_treedepth
  331. ),
  332. inits = replicate(
  333. n_chains,
  334. list(b_ndt = as.array(rep(-5, 4))),
  335. simplify=FALSE
  336. ),
  337. sample_prior = "only",
  338. silent = TRUE,
  339. cores = n_cores,
  340. seed = seed,
  341. thin = 1,
  342. refresh = 2500
  343. )
  344. rm(draws_spr)
  345. gc()
  346. draws_joined <- bind_rows(
  347. as_draws_df(m_rt, "^b\\_.*|^sd\\_.*", regex=TRUE) %>%
  348. select(-.chain, -.iteration, -.draw) %>%
  349. pivot_longer(cols=everything(), names_to="par", values_to="est") %>%
  350. mutate(source="posterior"),
  351. as_draws_df(m_rt_prior_samps, "^b\\_.*|^sd\\_.*", regex=TRUE) %>%
  352. select(-.chain, -.iteration, -.draw) %>%
  353. pivot_longer(cols=everything(), names_to="par", values_to="est") %>%
  354. mutate(source="prior")
  355. ) %>%
  356. mutate(source = factor(source, levels = c("prior", "posterior")))
  357. pl_prior_post_fe_ints <- draws_joined %>%
  358. filter(grepl("^b\\_", par), grepl("Intercept", par, fixed=TRUE)) %>%
  359. mutate(
  360. par_lab = factor(recode(
  361. par,
  362. b_Intercept = "mu",
  363. b_sigma_Intercept = "sigma",
  364. b_ndt_Intercept = "delta"
  365. ), levels = c("mu", "sigma", "delta"))
  366. ) %>%
  367. ggplot(aes(est, "Intercept", colour=source)) +
  368. stat_pointinterval(point_interval = "median_hdi", .width=.89, position=position_dodge(width=-0.4)) +
  369. facet_wrap(vars(par_lab), scales = "free_x", labeller = label_parsed) +
  370. scale_y_discrete(expand = expansion(0.1, 0)) +
  371. scale_colour_manual(values = c("black", "red")) +
  372. labs(
  373. x = NULL,
  374. y = NULL
  375. ) +
  376. theme(legend.position = "none")
  377. pl_prior_post_fe_slopes <- draws_joined %>%
  378. filter(grepl("^b\\_", par), !grepl("Intercept", par, fixed=TRUE)) %>%
  379. mutate(
  380. par_lab = factor(case_when(
  381. grepl("sigma", par, fixed=TRUE) ~ "sigma",
  382. grepl("ndt", par, fixed=TRUE) ~ "delta",
  383. TRUE ~ "mu"
  384. ), levels = c("mu", "sigma", "delta")),
  385. eff = factor(case_when(
  386. grepl("cong_dev:pred_norm", par, fixed=TRUE) ~ "Congruency\n* Predictability",
  387. grepl("cong_dev", par, fixed=TRUE) ~ "Congruency",
  388. grepl("pred_norm", par, fixed=TRUE) ~ "Predictability"
  389. ), levels = c("Congruency", "Predictability", "Congruency\n* Predictability"))
  390. ) %>%
  391. ggplot(aes(est, reorder(eff, desc(eff)), colour=source)) +
  392. stat_pointinterval(point_interval = "median_hdi", .width=.89, position=position_dodge(width=-0.4)) +
  393. facet_wrap(vars(par_lab), scales = "free_x", labeller = label_parsed) +
  394. scale_y_discrete(expand = expansion(0.1, 0)) +
  395. scale_colour_manual(values = c("black", "red"), labels = c("Prior", "Posterior")) +
  396. labs(
  397. x = "Estimate",
  398. y = NULL,
  399. colour = NULL
  400. ) +
  401. theme(
  402. legend.position = "bottom",
  403. legend.margin = margin(),
  404. strip.background = element_blank(),
  405. strip.text.x = element_blank()
  406. )
  407. pl_prior_post_fe <- plot_grid(pl_prior_post_fe_ints, pl_prior_post_fe_slopes, align="hv", axis="l", ncol=1, rel_heights=c(1.25, 2.85))
  408. ggsave(file.path("figs", "08_rt_prior_post_fixed_effects.pdf"), pl_prior_post_fe, width=6.5, height=3.5)
  409. ggsave(file.path("figs", "08_rt_prior_post_fixed_effects.png"), pl_prior_post_fe, width=6.5, height=3.5, device="png", type="cairo")
  410. # random effects plot
  411. # subject random effects SDs
  412. pl_prior_post_re_subj_ints <- draws_joined %>%
  413. filter(grepl("^sd\\_subj\\_id", par), grepl("Intercept", par, fixed=TRUE)) %>%
  414. mutate(
  415. par_lab = factor(case_when(
  416. grepl("sigma", par, fixed=TRUE) ~ "sigma",
  417. grepl("ndt", par, fixed=TRUE) ~ "delta",
  418. TRUE ~ "mu"
  419. ), levels = c("mu", "sigma", "delta"))
  420. ) %>%
  421. ggplot(aes(est, "Intercept", colour=source)) +
  422. stat_pointinterval(point_interval = "median_hdi", .width=.89, position=position_dodge(width=-0.4)) +
  423. facet_wrap(vars(par_lab), scales = "free_x", labeller = label_parsed) +
  424. scale_y_discrete(expand = expansion(0.1, 0)) +
  425. scale_colour_manual(values = c("black", "red")) +
  426. labs(
  427. x = NULL,
  428. y = NULL,
  429. title = "Participant Random Effects SDs",
  430. tag = "a"
  431. ) +
  432. theme(legend.position = "none")
  433. pl_prior_post_re_subj_slopes <- draws_joined %>%
  434. filter(grepl("^sd\\_subj\\_id", par), !grepl("Intercept", par, fixed=TRUE)) %>%
  435. mutate(
  436. par_lab = factor(case_when(
  437. grepl("sigma", par, fixed=TRUE) ~ "sigma",
  438. grepl("ndt", par, fixed=TRUE) ~ "delta",
  439. TRUE ~ "mu"
  440. ), levels = c("mu", "sigma", "delta")),
  441. eff = factor(case_when(
  442. grepl("cong_dev:pred_norm", par, fixed=TRUE) ~ "Congruency\n* Predictability",
  443. grepl("cong_dev", par, fixed=TRUE) ~ "Congruency",
  444. grepl("pred_norm", par, fixed=TRUE) ~ "Predictability"
  445. ), levels = c("Congruency", "Predictability", "Congruency\n* Predictability"))
  446. ) %>%
  447. ggplot(aes(est, reorder(eff, desc(eff)), colour=source)) +
  448. stat_pointinterval(point_interval = "median_hdi", .width=.89, position=position_dodge(width=-0.4)) +
  449. facet_wrap(vars(par_lab), scales = "free_x", labeller = label_parsed) +
  450. scale_y_discrete(expand = expansion(0.1, 0)) +
  451. scale_colour_manual(values = c("black", "red"), labels = c("Prior", "Posterior")) +
  452. labs(
  453. x = NULL,
  454. y = NULL,
  455. colour = NULL
  456. ) +
  457. theme(
  458. legend.position = "none",
  459. strip.background = element_blank(),
  460. strip.text.x = element_blank()
  461. )
  462. # image random effects SDs
  463. pl_prior_post_re_image_ints <- draws_joined %>%
  464. filter(grepl("^sd\\_image", par), grepl("Intercept", par, fixed=TRUE)) %>%
  465. mutate(
  466. par_lab = factor(case_when(
  467. grepl("sigma", par, fixed=TRUE) ~ "sigma",
  468. grepl("ndt", par, fixed=TRUE) ~ "delta",
  469. TRUE ~ "mu"
  470. ), levels = c("mu", "sigma", "delta"))
  471. ) %>%
  472. ggplot(aes(est, "Intercept", colour=source)) +
  473. stat_pointinterval(point_interval = "median_hdi", .width=.89, position=position_dodge(width=-0.4)) +
  474. facet_wrap(vars(par_lab), scales = "free_x", labeller = label_parsed) +
  475. scale_y_discrete(expand = expansion(0.1, 0)) +
  476. scale_colour_manual(values = c("black", "red")) +
  477. labs(
  478. x = NULL,
  479. y = NULL,
  480. title = "Image Random Effects SDs",
  481. tag = "b"
  482. ) +
  483. theme(legend.position = "none")
  484. pl_prior_post_re_image_slopes <- draws_joined %>%
  485. filter(grepl("^sd\\_image", par), !grepl("Intercept", par, fixed=TRUE)) %>%
  486. mutate(
  487. par_lab = factor(case_when(
  488. grepl("sigma", par, fixed=TRUE) ~ "sigma",
  489. grepl("ndt", par, fixed=TRUE) ~ "delta",
  490. TRUE ~ "mu"
  491. ), levels = c("mu", "sigma", "delta"))
  492. ) %>%
  493. ggplot(aes(est, "Congruency", colour=source)) +
  494. stat_pointinterval(point_interval = "median_hdi", .width=.89, position=position_dodge(width=-0.4)) +
  495. facet_wrap(vars(par_lab), scales = "free_x", labeller = label_parsed) +
  496. scale_y_discrete(expand = expansion(0.1, 0)) +
  497. scale_colour_manual(values = c("black", "red"), labels = c("Prior", "Posterior")) +
  498. labs(
  499. x = NULL,
  500. y = NULL,
  501. colour = NULL
  502. ) +
  503. theme(
  504. legend.position = "none",
  505. strip.background = element_blank(),
  506. strip.text.x = element_blank()
  507. )
  508. # word random effects SDs
  509. pl_prior_post_re_string_ints <- draws_joined %>%
  510. filter(grepl("^sd\\_string", par), grepl("Intercept", par, fixed=TRUE)) %>%
  511. mutate(
  512. par_lab = factor(case_when(
  513. grepl("sigma", par, fixed=TRUE) ~ "sigma",
  514. grepl("ndt", par, fixed=TRUE) ~ "delta",
  515. TRUE ~ "mu"
  516. ), levels = c("mu", "sigma", "delta"))
  517. ) %>%
  518. ggplot(aes(est, "Intercept", colour=source)) +
  519. stat_pointinterval(point_interval = "median_hdi", .width=.89, position=position_dodge(width=-0.4)) +
  520. facet_wrap(vars(par_lab), scales = "free_x", labeller = label_parsed) +
  521. scale_y_discrete(expand = expansion(0.1, 0)) +
  522. scale_colour_manual(values = c("black", "red"), labels=c("Prior", "Posterior")) +
  523. labs(
  524. x = "Estimate",
  525. y = NULL,
  526. title = "Word Random Effects SDs",
  527. tag = "c",
  528. colour = NULL
  529. ) +
  530. theme(legend.position = "bottom", legend.margin = margin())
  531. # join random effects SDs plots
  532. pl_prior_post_re <- plot_grid(
  533. pl_prior_post_re_subj_ints, pl_prior_post_re_subj_slopes,
  534. pl_prior_post_re_image_ints, pl_prior_post_re_image_slopes,
  535. pl_prior_post_re_string_ints,
  536. align="hv", axis="l", ncol=1, rel_heights=c(0.9, 1.2, 0.9, 0.5, 1.255)
  537. )
  538. ggsave(file.path("figs", "08_rt_prior_post_random_effects.pdf"), pl_prior_post_re, width=6.5, height=7.5)
  539. ggsave(file.path("figs", "08_rt_prior_post_random_effects.png"), pl_prior_post_re, width=6.5, height=7.5, device="png", type="cairo")