Preliminaries.
rm(list=ls())
suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(langcog))
suppressPackageStartupMessages(library(lme4))
suppressPackageStartupMessages(library(lmerTest))
library(ggplot2)
library(magrittr)
library(knitr)
library(tidyr)
##
## Attaching package: 'tidyr'
## The following object is masked from 'package:magrittr':
##
## extract
## The following object is masked from 'package:Matrix':
##
## expand
library(BayesFactor)
## Loading required package: coda
## ************
## Welcome to BayesFactor 0.9.12-2. If you have questions, please contact Richard Morey (richarddmorey@gmail.com).
##
## Type BFManual() to open the manual.
## ************
opts_chunk$set(fig.width=8, fig.height=5,
echo=TRUE, warning=FALSE, message=FALSE, cache=TRUE)
theme_set(theme_bw())
Read data. Coding info from Katie.
dual_experts_raw <- read.csv("data/Upright dual data experts w. subject IDs and order.csv")
names(dual_experts_raw) <- c("bead_type", "condition", "number_requested",
"X_pos","Y_pos","search_correct","RT",
"abacus_val","abacus_correct","n_col",
"subnum","outlier","trial_type",
"subid","n_conditions","order","subid_xexpts")
dual_experts_raw %<>%
mutate(bead_type = factor(bead_type,
levels = c(0,1),
labels = c("heaven","earth")),
condition = factor(condition,
levels = c(1,2,3,4),
labels = c("in play", "out of play",
"leading","trailing")))
Exclusions. Filter pilot participants.
pilot_subs <- dual_experts_raw %>%
group_by(subnum) %>%
summarise(pilot = any(n_col == 0)) %>%
filter(pilot)
dual_experts <- filter(dual_experts_raw,
!subnum %in% pilot_subs$subnum)
dual_experts %<>%
group_by(subnum) %>%
mutate(trial_num = 1:n())
Check to make sure we have a consistent number of trials, no training trials.
qplot(subnum, trial_num, data = dual_experts)
In this dataset we appear to be missing the end of a few participants.
Next, RT exclusions. Note that there are a few 0 RTs. What’s the deal with these?
sum(dual_experts$RT == 0)
## [1] 37
dual_experts %<>% filter(RT > 0,
!is.na(RT))
Linear space.
qplot(RT, data = dual_experts,
fill = RT > mean(RT) + 3*sd(RT))
mean(dual_experts$RT)
## [1] 3.860437
median(dual_experts$RT)
## [1] 3.31
Log space looks better.
qplot(log(RT), data = dual_experts,
fill = log(RT) > mean(log(RT)) + 3*sd(log(RT)) |
log(RT) < mean(log(RT)) - 3*sd(log(RT)))
Clip these.
lmean <- mean(log(dual_experts$RT))
lsd <- sd(log(dual_experts$RT))
dual_experts$RT[log(dual_experts$RT) > lmean + 3*lsd |
log(dual_experts$RT) < lmean - 3*lsd] <- NA
Replot in linear space just to check.
qplot(RT, data = dual_experts)
Looks good.
kable(dual_experts %>%
group_by(subnum) %>%
summarise(n = n()) %>%
summarise(n = n()))
63
kable(dual_experts %>%
group_by(subnum) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
mutate(condition = "all") %>% group_by(condition) %>%
multi_boot_standard(col = "RT"))
condition | mean | ci_lower | ci_upper |
---|---|---|---|
all | 3.756448 | 3.548135 | 3.984962 |
Basic analyses.
ms <- dual_experts %>%
filter(abacus_correct == 1,
search_correct == 1) %>%
group_by(subnum, condition) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition) %>%
multi_boot_standard(col = "RT")
kable(ms, digits = 2)
condition | mean | ci_lower | ci_upper |
---|---|---|---|
in play | 3.63 | 3.40 | 3.86 |
out of play | 3.88 | 3.66 | 4.10 |
leading | 3.86 | 3.63 | 4.09 |
trailing | 3.66 | 3.43 | 3.89 |
ggplot(ms,aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper))
Add two other variables: bead type and number of columns.
ms <- dual_experts %>%
filter(abacus_correct == 1,
search_correct == 1) %>%
group_by(subnum, condition, bead_type, n_col) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition, bead_type, n_col) %>%
multi_boot_standard(col = "RT")
kable(ms, digits = 2)
condition | bead_type | n_col | mean | ci_lower | ci_upper |
---|---|---|---|---|---|
in play | heaven | 2 | 3.39 | 3.13 | 3.69 |
in play | heaven | 3 | 4.40 | 4.00 | 4.90 |
in play | earth | 2 | 3.07 | 2.87 | 3.31 |
in play | earth | 3 | 4.03 | 3.75 | 4.32 |
out of play | heaven | 2 | 3.74 | 3.45 | 4.06 |
out of play | heaven | 3 | 4.46 | 4.15 | 4.80 |
out of play | earth | 2 | 3.44 | 3.24 | 3.65 |
out of play | earth | 3 | 4.18 | 3.91 | 4.44 |
leading | heaven | 2 | 3.97 | 3.66 | 4.29 |
leading | heaven | 3 | 4.41 | 4.12 | 4.71 |
leading | earth | 2 | 3.51 | 3.29 | 3.75 |
leading | earth | 3 | 4.00 | 3.77 | 4.27 |
trailing | heaven | 2 | 3.71 | 3.43 | 4.04 |
trailing | heaven | 3 | 4.36 | 4.04 | 4.69 |
trailing | earth | 2 | 3.16 | 2.98 | 3.33 |
trailing | earth | 3 | 3.91 | 3.64 | 4.21 |
ggplot(ms,aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid(bead_type ~ n_col)
It’s clear that the effects are being driven by the 2-column displays, and especiallywith the earthly beads. (Though there are probably fewer heavenly bead trials, no?).
Order effects.
ms <- dual_experts %>%
filter(abacus_correct == 1,
search_correct == 1) %>%
mutate(second_half = trial_num > 64) %>%
group_by(subnum, condition, second_half) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition, second_half) %>%
multi_boot_standard(col = "RT")
kable(ms, digits = 2)
condition | second_half | mean | ci_lower | ci_upper |
---|---|---|---|---|
in play | FALSE | 3.88 | 3.60 | 4.14 |
in play | TRUE | 3.37 | 3.12 | 3.61 |
out of play | FALSE | 4.12 | 3.88 | 4.38 |
out of play | TRUE | 3.69 | 3.46 | 3.95 |
leading | FALSE | 4.14 | 3.92 | 4.39 |
leading | TRUE | 3.59 | 3.36 | 3.83 |
trailing | FALSE | 3.97 | 3.72 | 4.24 |
trailing | TRUE | 3.35 | 3.15 | 3.57 |
ggplot(ms,aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
facet_wrap(~second_half) +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper))
Basic LMER confirms highly significant effects for in/out of play, and leading/trailing. Could do better parameterization, but this is still very clear. More random effects don’t converge.
kable(summary(lmer(log(RT) ~ trial_num + condition +
(condition | subnum),
data = filter(dual_experts,
search_correct == 1,
abacus_correct == 1)))$coefficients, digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.330 | 0.035 | 68.048 | 38.550 | 0.000 |
trial_num | -0.003 | 0.000 | 7345.036 | -22.050 | 0.000 |
conditionout of play | 0.092 | 0.015 | 64.573 | 6.158 | 0.000 |
conditionleading | 0.087 | 0.014 | 68.677 | 6.018 | 0.000 |
conditiontrailing | 0.028 | 0.014 | 65.692 | 2.013 | 0.048 |
Now add number of columns. Doesn’t converge with number of columns in random effects. This is also strong and clear, and the interactions suggest that all of this gets essentially canceled out in the three-column condition.
kable(summary(lmer(log(RT) ~ trial_num + condition * factor(n_col) +
(condition | subnum),
data = filter(dual_experts,
search_correct == 1,
abacus_correct == 1)))$coefficients, digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.201 | 0.035 | 75.790 | 34.014 | 0.000 |
trial_num | -0.003 | 0.000 | 7337.382 | -22.346 | 0.000 |
conditionout of play | 0.120 | 0.019 | 161.625 | 6.378 | 0.000 |
conditionleading | 0.154 | 0.018 | 179.412 | 8.408 | 0.000 |
conditiontrailing | 0.064 | 0.018 | 187.765 | 3.569 | 0.000 |
factor(n_col)3 | 0.253 | 0.017 | 7249.594 | 15.336 | 0.000 |
conditionout of play:factor(n_col)3 | -0.059 | 0.023 | 7243.509 | -2.536 | 0.011 |
conditionleading:factor(n_col)3 | -0.135 | 0.023 | 7246.326 | -5.775 | 0.000 |
conditiontrailing:factor(n_col)3 | -0.073 | 0.023 | 7250.239 | -3.106 | 0.002 |
Is there an order effect?
dual_experts$second_half <- dual_experts$trial_num > 64
kable(summary(lmer(log(RT) ~ trial_num + condition * factor(n_col) * second_half +
(condition | subnum),
data = filter(dual_experts,
search_correct == 1,
abacus_correct == 1)))$coefficients, digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.208 | 0.037 | 93.170 | 32.477 | 0.000 |
trial_num | -0.003 | 0.000 | 7333.356 | -12.595 | 0.000 |
conditionout of play | 0.102 | 0.025 | 488.360 | 4.060 | 0.000 |
conditionleading | 0.151 | 0.025 | 554.449 | 6.104 | 0.000 |
conditiontrailing | 0.059 | 0.025 | 619.098 | 2.406 | 0.016 |
factor(n_col)3 | 0.254 | 0.023 | 7274.846 | 10.983 | 0.000 |
second_halfTRUE | 0.029 | 0.028 | 7276.300 | 1.065 | 0.287 |
conditionout of play:factor(n_col)3 | -0.039 | 0.033 | 7285.226 | -1.172 | 0.241 |
conditionleading:factor(n_col)3 | -0.123 | 0.033 | 7290.802 | -3.729 | 0.000 |
conditiontrailing:factor(n_col)3 | -0.050 | 0.033 | 7314.139 | -1.513 | 0.130 |
conditionout of play:second_halfTRUE | 0.037 | 0.033 | 7289.411 | 1.112 | 0.266 |
conditionleading:second_halfTRUE | 0.007 | 0.033 | 7304.564 | 0.198 | 0.843 |
conditiontrailing:second_halfTRUE | 0.009 | 0.033 | 7313.240 | 0.261 | 0.794 |
factor(n_col)3:second_halfTRUE | -0.003 | 0.033 | 7148.447 | -0.092 | 0.927 |
conditionout of play:factor(n_col)3:second_halfTRUE | -0.040 | 0.047 | 7275.376 | -0.858 | 0.391 |
conditionleading:factor(n_col)3:second_halfTRUE | -0.022 | 0.047 | 7299.465 | -0.470 | 0.638 |
conditiontrailing:factor(n_col)3:second_halfTRUE | -0.044 | 0.047 | 7275.484 | -0.930 | 0.353 |
Read data.
single_experts_raw <- read.csv("data/Upright Single Task Expert Data w. subject IDs and order.csv")
names(single_experts_raw) <- c("bead_type", "condition", "number_requested",
"X_pos","Y_pos","search_correct","RT",
"abacus_val","abacus_correct","n_col",
"subnum","outlier","trial_type",
"subid","n_conditions","order","subid_xexpts")
single_experts_raw %<>%
mutate(bead_type = factor(bead_type,
levels = c(0,1),
labels = c("heaven","earth")),
condition = factor(condition,
levels = c(1,2,3,4),
labels = c("in play", "out of play",
"leading","trailing")))
Exclusions. Filter pilot participants.
pilot_subs <- single_experts_raw %>%
group_by(subnum) %>%
summarise(pilot = any(n_col == 0)) %>%
filter(pilot)
single_experts <- filter(single_experts_raw,
!subnum %in% pilot_subs$subnum)
single_experts %<>%
group_by(subnum) %>%
mutate(trial_num = 1:n())
Check to make sure we have a consistent number of trials, no training trials.
qplot(subnum, trial_num, data = single_experts)
All participants have full data.
RT exclusions. Note that there are a few 0 RTs. What’s the deal with these?
sum(single_experts$RT == 0)
## [1] 43
single_experts %<>% filter(RT > 0,
!is.na(RT))
Again clip in log space.
qplot(log(RT), data = single_experts,
fill = log(RT) > mean(log(RT)) + 3*sd(log(RT)) |
log(RT) < mean(log(RT)) - 3*sd(log(RT)))
Clip these.
lmean <- mean(log(single_experts$RT))
lsd <- sd(log(single_experts$RT))
single_experts$RT[log(single_experts$RT) > lmean + 3*lsd |
log(single_experts$RT) < lmean - 3*lsd] <- NA
Replot in linear space just to check.
qplot(RT, data = single_experts)
Looks good.
kable(single_experts %>%
group_by(subnum) %>%
summarise(n = n()) %>%
summarise(n = n()))
67
kable(single_experts %>%
group_by(subnum) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
mutate(condition = "all") %>% group_by(condition) %>%
multi_boot_standard(col = "RT"))
condition | mean | ci_lower | ci_upper |
---|---|---|---|
all | 1.969064 | 1.847767 | 2.100203 |
Basic analyses.
ms <- single_experts %>%
filter(search_correct == 1) %>%
group_by(subnum, condition) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition) %>%
multi_boot_standard(col = "RT")
kable(ms, digits = 2)
condition | mean | ci_lower | ci_upper |
---|---|---|---|
in play | 1.88 | 1.76 | 2.01 |
out of play | 2.09 | 1.96 | 2.22 |
leading | 2.05 | 1.91 | 2.18 |
trailing | 1.89 | 1.76 | 2.01 |
ggplot(ms,aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper))
Add two other variables: bead type and number of columns.
ms <- single_experts %>%
filter(search_correct == 1) %>%
group_by(subnum, condition, bead_type, n_col) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition, bead_type, n_col) %>%
multi_boot_standard(col = "RT")
kable(ms, digits = 2)
condition | bead_type | n_col | mean | ci_lower | ci_upper |
---|---|---|---|---|---|
in play | heaven | 2 | 1.78 | 1.66 | 1.92 |
in play | heaven | 3 | 2.10 | 1.92 | 2.28 |
in play | earth | 2 | 1.68 | 1.57 | 1.79 |
in play | earth | 3 | 2.04 | 1.88 | 2.20 |
out of play | heaven | 2 | 2.14 | 2.00 | 2.29 |
out of play | heaven | 3 | 2.48 | 2.30 | 2.67 |
out of play | earth | 2 | 1.82 | 1.70 | 1.94 |
out of play | earth | 3 | 2.22 | 2.05 | 2.39 |
leading | heaven | 2 | 2.10 | 1.94 | 2.29 |
leading | heaven | 3 | 2.57 | 2.37 | 2.78 |
leading | earth | 2 | 1.80 | 1.68 | 1.93 |
leading | earth | 3 | 2.09 | 1.93 | 2.26 |
trailing | heaven | 2 | 2.00 | 1.85 | 2.18 |
trailing | heaven | 3 | 2.39 | 2.20 | 2.59 |
trailing | earth | 2 | 1.64 | 1.53 | 1.75 |
trailing | earth | 3 | 1.94 | 1.80 | 2.10 |
ggplot(ms, aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid(bead_type ~ n_col)
Now in this experiment, we’re actually seeing effects in the three-column case. That suggests that it was the load of the three-column abacus reading that was suppressing the attentional effects, which is actually kind of nice and interesting.
Same LMER as before. This time the model didn’t converge with random condition effects.
kable(summary(lmer(log(RT) ~ trial_num + condition +
(1 | subnum),
data = filter(single_experts,
search_correct == 1)))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.533 | 0.033 | 86.563 | 16.301 | 0.000 |
trial_num | -0.001 | 0.000 | 8045.513 | -4.481 | 0.000 |
conditionout of play | 0.118 | 0.014 | 8044.111 | 8.729 | 0.000 |
conditionleading | 0.085 | 0.014 | 8044.108 | 6.276 | 0.000 |
conditiontrailing | 0.013 | 0.013 | 8044.112 | 0.928 | 0.353 |
Now add number of columns again. Here there are no interactions, which is clear and nice. Interestingly, now the model will converge with condition in the random effects.
kable(summary(lmer(log(RT) ~ trial_num + condition * factor(n_col) +
(condition | subnum),
data = filter(single_experts,
search_correct == 1)))$coefficients, digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.452 | 0.035 | 85.814 | 12.792 | 0.000 |
trial_num | -0.001 | 0.000 | 8028.483 | -4.533 | 0.000 |
conditionout of play | 0.119 | 0.020 | 209.993 | 6.011 | 0.000 |
conditionleading | 0.092 | 0.019 | 401.992 | 4.819 | 0.000 |
conditiontrailing | 0.019 | 0.020 | 202.561 | 0.953 | 0.342 |
factor(n_col)3 | 0.163 | 0.019 | 7915.599 | 8.705 | 0.000 |
conditionout of play:factor(n_col)3 | -0.003 | 0.027 | 7915.755 | -0.107 | 0.914 |
conditionleading:factor(n_col)3 | -0.016 | 0.027 | 7914.997 | -0.599 | 0.549 |
conditiontrailing:factor(n_col)3 | -0.014 | 0.026 | 7918.387 | -0.535 | 0.593 |
Bind everything together. Note that we filter correct search trials here rather than in models below.
experts <- bind_rows(filter(single_experts,
search_correct ==1) %>%
mutate(expt = "single task",
group = "experts"),
filter(dual_experts,
search_correct == 1,
abacus_correct == 1) %>%
mutate(expt = "dual task",
group = "experts")) %>%
mutate(subid_xexpts = as.numeric(as.character(subid_xexpts)),
order = ifelse(order == "1", 1, ifelse(order == "N/A", NA, 2)))
We don’t learn much more this way, but we can plot everything together
ms <- experts %>%
group_by(subnum, condition, expt) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition, expt) %>%
multi_boot_standard(col = "RT")
ggplot(ms,aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid(~expt)
Model the whole thing together.
kable(summary(lmer(log(RT) ~ expt * trial_num + expt * condition +
(condition | subnum),
data = filter(experts)))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.330 | 0.035 | 142.996 | 38.151 | 0.000 |
exptsingle task | -0.797 | 0.049 | 142.599 | -16.416 | 0.000 |
trial_num | -0.003 | 0.000 | 15381.100 | -20.279 | 0.000 |
conditionout of play | 0.092 | 0.015 | 133.803 | 6.064 | 0.000 |
conditionleading | 0.087 | 0.014 | 156.398 | 6.080 | 0.000 |
conditiontrailing | 0.028 | 0.015 | 138.986 | 1.887 | 0.061 |
exptsingle task:trial_num | 0.002 | 0.000 | 15383.058 | 11.321 | 0.000 |
exptsingle task:conditionout of play | 0.026 | 0.021 | 131.410 | 1.259 | 0.210 |
exptsingle task:conditionleading | -0.002 | 0.020 | 154.793 | -0.087 | 0.931 |
exptsingle task:conditiontrailing | -0.016 | 0.021 | 135.491 | -0.760 | 0.449 |
This is very interpretable:
Awesome.
Because there is no interaction of conditon and task, we interpret as similar attentional biases. But this is technically an inference from null.
Thus, we move to a Bayesian framework to quantify evidence for null. First we shift to a (frequentist) ANOVA (over condition means) and then compute BFs.
anova_data <- experts %>%
ungroup %>%
mutate(subnum = factor(subnum),
expt = factor(expt)) %>%
group_by(expt, condition, subnum) %>%
summarise(log_rt = mean(log(RT), na.rm=TRUE))
aov_mod <- aov(log_rt ~ expt * condition + Error(subnum), data = anova_data)
summary(aov_mod)
##
## Error: subnum
## Df Sum Sq Mean Sq F value Pr(>F)
## expt 1 57.77 57.77 238.6 <2e-16 ***
## Residuals 128 30.99 0.24
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Error: Within
## Df Sum Sq Mean Sq F value Pr(>F)
## condition 3 1.0092 0.3364 50.761 <2e-16 ***
## expt:condition 3 0.0257 0.0086 1.291 0.277
## Residuals 384 2.5448 0.0066
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Interpretation is identical, there are main effects of experiment and condition, with no interaction. Now for BF. (Note BayesFactor
package not compatible with tibble
).
anovaBF(log_rt ~ expt * condition + subnum,
data = as.data.frame(anova_data),
whichRandom = "subnum",
whichModels = "top")
## Bayes factor top-down analysis
## --------------
## When effect is omitted from expt + condition + expt:condition + subnum , BF is...
## [1] Omit condition:expt : 10.69676 ±3.88%
## [2] Omit condition : 4.00624e-25 ±3.72%
## [3] Omit expt : 4.409979e-28 ±3.82%
##
## Against denominator:
## log_rt ~ expt + condition + expt:condition + subnum
## ---
## Bayes factor type: BFlinearModel, JZS
We are seeing substantial evidence in this analysis FOR the omission of condition:experiment
(BF > 10).
Let’s try this in the lmBF
framework as well.
lmbf_data <- experts %>%
ungroup %>%
mutate(subnum = factor(subnum),
expt = factor(expt),
log_rt = log(RT)) %>%
filter(!is.na(log_rt))
lm_mod <- lmBF(log_rt ~ expt * trial_num + expt * condition,
data = as.data.frame(lmbf_data),
whichRandom = "subnum")
lm_mod
## Bayes factor analysis
## --------------
## [1] expt * trial_num + expt * condition : 2.970735e+1420 ±1.69%
##
## Against denominator:
## Intercept only
## ---
## Bayes factor type: BFlinearModel, JZS
lm_mod_nointeraction <- lmBF(log_rt ~ expt * trial_num + expt + condition,
data = as.data.frame(lmbf_data),
whichRandom = "subnum")
lm_mod_nointeraction
## Bayes factor analysis
## --------------
## [1] expt * trial_num + expt + condition : 3.589481e+1423 ±3.17%
##
## Against denominator:
## Intercept only
## ---
## Bayes factor type: BFlinearModel, JZS
lm_mod / lm_mod_nointeraction
## Bayes factor analysis
## --------------
## [1] expt * trial_num + expt * condition : 0.0008276226 ±3.59%
##
## Against denominator:
## log_rt ~ expt * trial_num + expt + condition
## ---
## Bayes factor type: BFlinearModel, JZS
Very consistent.
First figure out who participated in both. You only got a subid_xexpt if you participated in both?
xexpts <- unique(experts$subid_xexpts)
length(xexpts[!is.na(xexpts)])
## [1] 17
Next, check the stats for this group. First same model as above.
kable(summary(lmer(log(RT) ~ expt * trial_num + expt * condition +
(condition | subnum),
data = filter(experts, !is.na(subid_xexpts))))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.160 | 0.073 | 34.815 | 15.989 | 0.000 |
exptsingle task | -0.663 | 0.103 | 34.843 | -6.459 | 0.000 |
trial_num | -0.003 | 0.000 | 4032.570 | -10.684 | 0.000 |
conditionout of play | 0.122 | 0.029 | 32.523 | 4.209 | 0.000 |
conditionleading | 0.115 | 0.027 | 52.434 | 4.266 | 0.000 |
conditiontrailing | 0.061 | 0.028 | 40.645 | 2.152 | 0.037 |
exptsingle task:trial_num | 0.002 | 0.000 | 4033.188 | 5.102 | 0.000 |
exptsingle task:conditionout of play | 0.008 | 0.041 | 32.214 | 0.208 | 0.837 |
exptsingle task:conditionleading | -0.029 | 0.038 | 52.243 | -0.746 | 0.459 |
exptsingle task:conditiontrailing | -0.048 | 0.040 | 39.763 | -1.220 | 0.230 |
Next, add interactions of order.
print("foo")
## [1] "foo"
kable(summary(lmer(log(RT) ~ expt * trial_num + expt * condition * order +
(condition | subnum),
data = filter(experts, !is.na(subid_xexpts))))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.306 | 0.282 | 30.338 | 4.633 | 0.000 |
exptsingle task | -0.675 | 0.357 | 30.317 | -1.894 | 0.068 |
trial_num | -0.003 | 0.000 | 4027.067 | -10.681 | 0.000 |
conditionout of play | 0.173 | 0.117 | 32.449 | 1.477 | 0.149 |
conditionleading | 0.121 | 0.109 | 45.933 | 1.111 | 0.272 |
conditiontrailing | 0.186 | 0.111 | 40.012 | 1.685 | 0.100 |
order | -0.086 | 0.159 | 30.156 | -0.537 | 0.595 |
exptsingle task:trial_num | 0.002 | 0.000 | 4027.813 | 5.090 | 0.000 |
exptsingle task:conditionout of play | -0.081 | 0.147 | 31.484 | -0.555 | 0.583 |
exptsingle task:conditionleading | 0.012 | 0.137 | 44.967 | 0.087 | 0.931 |
exptsingle task:conditiontrailing | -0.116 | 0.139 | 38.774 | -0.837 | 0.408 |
exptsingle task:order | -0.013 | 0.220 | 30.116 | -0.057 | 0.955 |
conditionout of play:order | -0.030 | 0.066 | 31.854 | -0.450 | 0.656 |
conditionleading:order | -0.003 | 0.062 | 45.218 | -0.053 | 0.958 |
conditiontrailing:order | -0.073 | 0.062 | 39.456 | -1.176 | 0.247 |
exptsingle task:conditionout of play:order | 0.058 | 0.090 | 31.166 | 0.643 | 0.525 |
exptsingle task:conditionleading:order | -0.031 | 0.085 | 44.773 | -0.370 | 0.713 |
exptsingle task:conditiontrailing:order | 0.030 | 0.086 | 38.591 | 0.353 | 0.726 |
Hard to conclude anything from this. Let’s look at the plot.
ms <- experts %>%
filter(!is.na(subid_xexpts)) %>%
group_by(subnum, condition, expt, order) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition, expt, order) %>%
multi_boot_standard(col = "RT")
ggplot(ms,aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid(order~expt)
Read data.
naive_raw <- read.csv("data/UprightAdultData.csv")
names(naive_raw) <- c("bead_type", "condition", "number_requested",
"X_pos","Y_pos","search_correct","RT",
"abacus_val","abacus_correct","n_col",
"subnum","outlier","trial_type", "expertise")
naive_raw %<>%
mutate(bead_type = factor(bead_type,
levels = c(0,1),
labels = c("heaven","earth")),
condition = factor(condition,
levels = c(1,2,3,4),
labels = c("in play", "out of play",
"leading","trailing")))
Exclusions. Filter pilot participants.
pilot_subs <- naive_raw %>%
group_by(subnum) %>%
summarise(pilot = any(n_col == 0)) %>%
filter(pilot)
naive <- filter(naive_raw,
!subnum %in% pilot_subs$subnum)
naive %<>%
group_by(subnum) %>%
mutate(trial_num = 1:n())
Check to make sure we have a consistent number of trials, no training trials.
qplot(subnum, trial_num, data = naive)
All participants have full data.
RT exclusions. Again clip in log space.
qplot(log(RT), data = naive,
fill = log(RT) > mean(log(RT)) + 3*sd(log(RT)) |
log(RT) < mean(log(RT)) - 3*sd(log(RT)))
Clip these.
lmean <- mean(log(naive$RT))
lsd <- sd(log(naive$RT))
naive$RT[log(naive$RT) > lmean + 3*lsd |
log(naive$RT) < lmean - 3*lsd] <- NA
Replot in linear space just to check.
qplot(RT, data = naive)
Looks good.
kable(naive %>%
group_by(subnum) %>%
summarise(n = n()) %>%
summarise(n = n()))
56
kable(naive %>%
group_by(subnum) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
mutate(condition = "all") %>% group_by(condition) %>%
multi_boot_standard(col = "RT"))
condition | mean | ci_lower | ci_upper |
---|---|---|---|
all | 1.195807 | 1.118873 | 1.274794 |
Basic analyses. Summary: In this experiment, the effects are smaller, but still present, at all column levels.
ms <- naive %>%
filter(search_correct == 1) %>%
group_by(subnum, condition) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition) %>%
multi_boot_standard(col = "RT")
kable(ms, digits = 2)
condition | mean | ci_lower | ci_upper |
---|---|---|---|
in play | 1.15 | 1.07 | 1.24 |
out of play | 1.23 | 1.16 | 1.31 |
leading | 1.23 | 1.15 | 1.31 |
trailing | 1.16 | 1.09 | 1.25 |
ggplot(ms,aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper))
Add two other variables: bead type and number of columns.
ms <- naive %>%
filter(search_correct == 1) %>%
group_by(subnum, condition, bead_type, n_col) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition, bead_type, n_col) %>%
multi_boot_standard(col = "RT")
kable(ms, digits = 2)
condition | bead_type | n_col | mean | ci_lower | ci_upper |
---|---|---|---|---|---|
in play | heaven | 2 | 1.09 | 1.01 | 1.18 |
in play | heaven | 3 | 1.22 | 1.12 | 1.34 |
in play | earth | 2 | 1.10 | 1.02 | 1.20 |
in play | earth | 3 | 1.20 | 1.11 | 1.30 |
out of play | heaven | 2 | 1.22 | 1.13 | 1.32 |
out of play | heaven | 3 | 1.35 | 1.24 | 1.47 |
out of play | earth | 2 | 1.14 | 1.07 | 1.22 |
out of play | earth | 3 | 1.29 | 1.20 | 1.38 |
leading | heaven | 2 | 1.22 | 1.12 | 1.31 |
leading | heaven | 3 | 1.35 | 1.25 | 1.46 |
leading | earth | 2 | 1.14 | 1.07 | 1.22 |
leading | earth | 3 | 1.29 | 1.20 | 1.38 |
trailing | heaven | 2 | 1.19 | 1.11 | 1.29 |
trailing | heaven | 3 | 1.33 | 1.22 | 1.45 |
trailing | earth | 2 | 1.08 | 1.00 | 1.16 |
trailing | earth | 3 | 1.19 | 1.11 | 1.28 |
ggplot(ms, aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid(bead_type ~ n_col)
Add abacus expertise instead.
ms <- naive %>%
filter(search_correct == 1) %>%
group_by(subnum, condition, expertise) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition, expertise) %>%
multi_boot_standard(col = "RT")
kable(ms, digits = 2)
condition | expertise | mean | ci_lower | ci_upper |
---|---|---|---|---|
in play | 0 | 1.20 | 1.08 | 1.32 |
in play | 1 | 1.06 | 0.96 | 1.17 |
in play | 2 | 1.21 | 0.93 | 1.56 |
out of play | 0 | 1.27 | 1.16 | 1.38 |
out of play | 1 | 1.14 | 1.05 | 1.24 |
out of play | 2 | 1.30 | 1.10 | 1.50 |
leading | 0 | 1.25 | 1.15 | 1.36 |
leading | 1 | 1.14 | 1.03 | 1.26 |
leading | 2 | 1.40 | 1.16 | 1.64 |
trailing | 0 | 1.21 | 1.11 | 1.32 |
trailing | 1 | 1.07 | 0.98 | 1.16 |
trailing | 2 | 1.22 | 0.99 | 1.55 |
ggplot(ms, aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid(. ~ expertise)
Same LMER as in the previous two, with the full random effects structure. This model shows both effects, as before.
kable(summary(lmer(log(RT) ~ trial_num + condition +
(condition | subnum),
data = filter(naive,
search_correct == 1)))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.118 | 0.034 | 59.745 | 3.459 | 0.001 |
trial_num | -0.001 | 0.000 | 6891.010 | -10.368 | 0.000 |
conditionout of play | 0.081 | 0.012 | 133.951 | 6.520 | 0.000 |
conditionleading | 0.077 | 0.014 | 64.863 | 5.671 | 0.000 |
conditiontrailing | 0.023 | 0.013 | 107.088 | 1.764 | 0.081 |
Now add number of columns again. Here again there are no interactions, suggesting that column didn’t affect matters.
kable(summary(lmer(log(RT) ~ trial_num + condition * factor(n_col) +
(condition | subnum),
data = filter(naive,
search_correct == 1)))$coefficients, digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.083 | 0.035 | 66.218 | 2.367 | 0.021 |
trial_num | -0.001 | 0.000 | 6885.169 | -10.529 | 0.000 |
conditionout of play | 0.067 | 0.017 | 405.167 | 4.048 | 0.000 |
conditionleading | 0.063 | 0.018 | 153.058 | 3.567 | 0.000 |
conditiontrailing | 0.011 | 0.017 | 181.253 | 0.676 | 0.500 |
factor(n_col)3 | 0.071 | 0.016 | 6794.703 | 4.542 | 0.000 |
conditionout of play:factor(n_col)3 | 0.029 | 0.022 | 6792.594 | 1.292 | 0.196 |
conditionleading:factor(n_col)3 | 0.030 | 0.022 | 6795.768 | 1.350 | 0.177 |
conditiontrailing:factor(n_col)3 | 0.022 | 0.022 | 6795.111 | 1.011 | 0.312 |
And check for interactions of expertise level. First with expertise as a continuous variable.
kable(summary(lmer(log(RT) ~ trial_num + condition * expertise +
(condition | subnum),
data = filter(naive,
search_correct == 1)))$coefficients, digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.136 | 0.043 | 56.867 | 3.138 | 0.003 |
trial_num | -0.001 | 0.000 | 6889.146 | -10.387 | 0.000 |
conditionout of play | 0.075 | 0.016 | 134.303 | 4.712 | 0.000 |
conditionleading | 0.051 | 0.017 | 70.439 | 3.093 | 0.003 |
conditiontrailing | 0.022 | 0.016 | 95.912 | 1.339 | 0.184 |
expertise | -0.033 | 0.049 | 54.030 | -0.670 | 0.505 |
conditionout of play:expertise | 0.013 | 0.018 | 134.600 | 0.686 | 0.494 |
conditionleading:expertise | 0.049 | 0.019 | 70.380 | 2.535 | 0.013 |
conditiontrailing:expertise | 0.001 | 0.019 | 95.103 | 0.054 | 0.957 |
Now with expertise as a factor.
kable(summary(lmer(log(RT) ~ trial_num + condition * factor(expertise) +
(condition | subnum),
data = filter(naive,
search_correct == 1)))$coefficients, digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.152 | 0.045 | 55.637 | 3.398 | 0.001 |
trial_num | -0.001 | 0.000 | 6886.050 | -10.400 | 0.000 |
conditionout of play | 0.077 | 0.017 | 126.736 | 4.655 | 0.000 |
conditionleading | 0.056 | 0.017 | 70.759 | 3.206 | 0.002 |
conditiontrailing | 0.023 | 0.017 | 88.689 | 1.323 | 0.189 |
factor(expertise)1 | -0.105 | 0.073 | 53.019 | -1.435 | 0.157 |
factor(expertise)2 | 0.003 | 0.111 | 53.036 | 0.024 | 0.981 |
conditionout of play:factor(expertise)1 | 0.000 | 0.028 | 125.384 | -0.005 | 0.996 |
conditionleading:factor(expertise)1 | 0.029 | 0.029 | 70.489 | 1.011 | 0.315 |
conditiontrailing:factor(expertise)1 | -0.003 | 0.029 | 87.583 | -0.107 | 0.915 |
conditionout of play:factor(expertise)2 | 0.037 | 0.042 | 127.671 | 0.895 | 0.372 |
conditionleading:factor(expertise)2 | 0.116 | 0.044 | 70.735 | 2.651 | 0.010 |
conditiontrailing:factor(expertise)2 | 0.006 | 0.043 | 87.705 | 0.140 | 0.889 |
In both cases, we see a slightly bigger effect of leading zeros being slower for the participants with more abacus exposure. This is not totally unreasonable, but it’s a small effect.
Finally, check a followup model for only zero expertise subjects. Does not converge with random slope.
kable(summary(lmer(log(RT) ~ trial_num + condition +
(1 | subnum),
data = filter(naive,
expertise == 0,
search_correct == 1)))$coefficients, digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.164 | 0.043 | 37.349 | 3.833 | 0.000 |
trial_num | -0.001 | 0.000 | 3930.019 | -9.279 | 0.000 |
conditionout of play | 0.078 | 0.015 | 3930.005 | 5.264 | 0.000 |
conditionleading | 0.056 | 0.015 | 3930.008 | 3.768 | 0.000 |
conditiontrailing | 0.023 | 0.015 | 3930.013 | 1.570 | 0.116 |
We focus here on the question of expertise interactions.
# model of interest
# log(RT) ~ trial_num + condition * expertise +
# (condition | subnum),
# data = filter(naive,
# search_correct == 1)
lmbf_data <- naive %>%
filter(search_correct == 1) %>%
ungroup %>%
mutate(subnum = factor(subnum),
log_rt = log(RT)) %>%
filter(!is.na(log_rt))
lm_mod <- lmBF(log_rt ~ trial_num + condition * expertise,
data = as.data.frame(lmbf_data),
whichRandom = "subnum")
lm_mod
## Bayes factor analysis
## --------------
## [1] trial_num + condition * expertise : 2.643381e+19 ±0.81%
##
## Against denominator:
## Intercept only
## ---
## Bayes factor type: BFlinearModel, JZS
lm_mod_nointeraction <- lmBF(log_rt ~ trial_num + condition + expertise,
data = as.data.frame(lmbf_data),
whichRandom = "subnum")
lm_mod_nointeraction
## Bayes factor analysis
## --------------
## [1] trial_num + condition + expertise : 1.957686e+21 ±0.86%
##
## Against denominator:
## Intercept only
## ---
## Bayes factor type: BFlinearModel, JZS
lm_mod / lm_mod_nointeraction
## Bayes factor analysis
## --------------
## [1] trial_num + condition * expertise : 0.01350258 ±1.18%
##
## Against denominator:
## log_rt ~ trial_num + condition + expertise
## ---
## Bayes factor type: BFlinearModel, JZS
Bind all data.
d <- bind_rows(filter(naive,
search_correct == 1) %>%
mutate(expt = "single task",
group = "naive"),
experts)
Now plot.
ms <- d %>%
filter(expt == "single task") %>%
group_by(subnum, condition, group) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition, group) %>%
multi_boot_standard(col = "RT")
ggplot(ms, aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid( ~ group)
And a statistical model.
kable(summary(lmer(log(RT) ~ trial_num + condition * group +
(condition | subnum),
data = filter(d,
expt == "single task")))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.549 | 0.032 | 128.397 | 16.937 | 0.000 |
trial_num | -0.001 | 0.000 | 14930.532 | -9.702 | 0.000 |
conditionout of play | 0.118 | 0.013 | 163.223 | 9.056 | 0.000 |
conditionleading | 0.085 | 0.013 | 133.027 | 6.493 | 0.000 |
conditiontrailing | 0.013 | 0.014 | 124.919 | 0.930 | 0.354 |
groupnaive | -0.450 | 0.047 | 120.917 | -9.499 | 0.000 |
conditionout of play:groupnaive | -0.037 | 0.019 | 158.820 | -1.950 | 0.053 |
conditionleading:groupnaive | -0.009 | 0.019 | 129.612 | -0.444 | 0.658 |
conditiontrailing:groupnaive | 0.009 | 0.020 | 121.782 | 0.469 | 0.640 |
Summary - experts are way slower than naive participants, even when they don’t have the dual task. That’s interesting, I think - they are still processing the abacus somehow prior to searching.
There’s not much in the way of interactions of the effects with group, with one exception. The naive participants don’t show as big an “out of play” effect as the experts, trending with p = 0.0511761. So there may be some small difference there.
# model of interest
# lmer(log(RT) ~ trial_num + condition * group +
# (condition | subnum),
# data = filter(d,
# expt == "single task")
lmbf_data <- d %>%
filter(expt == "single task") %>%
ungroup %>%
mutate(subnum = factor(subnum),
log_rt = log(RT),
group = factor(group)) %>%
filter(!is.na(log_rt))
lm_mod <- lmBF(log_rt ~ trial_num + condition * group,
data = as.data.frame(lmbf_data),
whichRandom = "subnum")
lm_mod
## Bayes factor analysis
## --------------
## [1] trial_num + condition * group : 6.93877e+772 ±4.26%
##
## Against denominator:
## Intercept only
## ---
## Bayes factor type: BFlinearModel, JZS
lm_mod_nointeraction <- lmBF(log_rt ~ trial_num + condition + group,
data = as.data.frame(lmbf_data),
whichRandom = "subnum")
lm_mod_nointeraction
## Bayes factor analysis
## --------------
## [1] trial_num + condition + group : 2.199482e+775 ±6.33%
##
## Against denominator:
## Intercept only
## ---
## Bayes factor type: BFlinearModel, JZS
lm_mod / lm_mod_nointeraction
## Bayes factor analysis
## --------------
## [1] trial_num + condition * group : 0.003154729 ±7.63%
##
## Against denominator:
## log_rt ~ trial_num + condition + group
## ---
## Bayes factor type: BFlinearModel, JZS
ms <- d %>%
group_by(subnum, condition, expt, expertise, group) %>%
summarise(RT = mean(RT, na.rm=TRUE)) %>%
group_by(condition, expt, expertise, group) %>%
multi_boot_standard(col = "RT")
First in-play/out-of-play.
ggplot(filter(ms, group=="experts",
condition == "in play" | condition == "out of play"),
aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid( ~ expt) +
theme_mikabr() +
scale_fill_solarized()
Then trailing/leading.
ggplot(filter(ms, group=="experts",
condition == "leading" | condition == "trailing"),
aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid( ~ expt) +
theme_mikabr() +
scale_fill_solarized()
Then the same in/out of play by expertise.
ggplot(filter(ms, group=="naive",
condition == "in play" | condition == "out of play"),
aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid( ~ expertise) +
theme_mikabr() +
scale_fill_solarized()
and leading/trailing by expertise.
ms$expertise <- factor(ms$expertise, levels = c(0, 1, 2), labels = c("No experience","Recognition only","Experience using"))
ggplot(filter(ms, group=="naive",
condition == "leading" | condition == "trailing"),
aes(x = condition, y = mean, fill = condition)) +
geom_bar(stat = "identity") +
geom_linerange(aes(ymin = ci_lower, ymax = ci_upper)) +
facet_grid( ~ expertise) +
theme_mikabr() +
scale_fill_solarized()
Consolidate all data into a single model.
kable(summary(lmer(log(RT) ~ trial_num * group * expt +
condition * group * expt +
(condition | subnum),
data = d))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.330 | 0.034 | 203.446 | 39.045 | 0.000 |
trial_num | -0.003 | 0.000 | 22271.939 | -21.355 | 0.000 |
groupnaive | -0.416 | 0.049 | 201.474 | -8.514 | 0.000 |
exptsingle task | -0.797 | 0.047 | 202.911 | -16.801 | 0.000 |
conditionout of play | 0.092 | 0.014 | 214.582 | 6.555 | 0.000 |
conditionleading | 0.087 | 0.014 | 207.265 | 6.248 | 0.000 |
conditiontrailing | 0.028 | 0.014 | 198.718 | 1.992 | 0.048 |
trial_num:groupnaive | -0.001 | 0.000 | 22278.563 | -3.150 | 0.002 |
trial_num:exptsingle task | 0.002 | 0.000 | 22273.093 | 11.929 | 0.000 |
groupnaive:conditionout of play | -0.037 | 0.020 | 201.129 | -1.860 | 0.064 |
groupnaive:conditionleading | -0.008 | 0.020 | 198.235 | -0.391 | 0.696 |
groupnaive:conditiontrailing | 0.010 | 0.020 | 183.728 | 0.499 | 0.618 |
exptsingle task:conditionout of play | 0.026 | 0.019 | 210.530 | 1.364 | 0.174 |
exptsingle task:conditionleading | -0.002 | 0.019 | 205.236 | -0.089 | 0.929 |
exptsingle task:conditiontrailing | -0.016 | 0.020 | 193.654 | -0.805 | 0.422 |
In the full model we see all the effects holding up, with not much evidence for interactions of expertise or experiment type. That’s pretty much exactly what we thought was going on.
Does position mediate the “in play/out of play” effect?
First, the baseline model for this analysis: only earthly beads (since heavenly bead position and “in play” is confounded.
There’s an interesting decision to make here in the random effects. I think it’s best to go with no condition or Y_pos random effect both for convergence reasons and because it’s hard theoretically to interpret when you have all the interactions here.
kable(summary(lmer(log(RT) ~ trial_num * group * expt +
condition * group * expt +
(1 | subnum),
data = filter(d,
condition %in% c("in play","out of play"),
bead_type == "earth")))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.300 | 0.035 | 270.637 | 37.549 | 0.000 |
trial_num | -0.002 | 0.000 | 8269.966 | -12.262 | 0.000 |
groupnaive | -0.400 | 0.049 | 264.586 | -8.083 | 0.000 |
exptsingle task | -0.784 | 0.048 | 268.799 | -16.288 | 0.000 |
conditionout of play | 0.091 | 0.014 | 8255.969 | 6.263 | 0.000 |
trial_num:groupnaive | -0.001 | 0.000 | 8264.927 | -2.063 | 0.039 |
trial_num:exptsingle task | 0.002 | 0.000 | 8268.280 | 7.002 | 0.000 |
groupnaive:conditionout of play | -0.020 | 0.020 | 8254.536 | -0.971 | 0.331 |
exptsingle task:conditionout of play | -0.001 | 0.020 | 8255.449 | -0.025 | 0.980 |
Next, add vertical position as a predictor.
kable(summary(lmer(log(RT) ~ trial_num * group * expt +
condition * group * expt +
Y_pos * group * expt +
(1 | subnum),
data = filter(d,
condition %in% c("in play","out of play"),
bead_type == "earth")))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.177 | 0.045 | 757.722 | 26.232 | 0.000 |
trial_num | -0.002 | 0.000 | 8267.064 | -12.377 | 0.000 |
groupnaive | -0.457 | 0.064 | 723.261 | -7.178 | 0.000 |
exptsingle task | -0.790 | 0.062 | 743.118 | -12.712 | 0.000 |
conditionout of play | 0.019 | 0.022 | 8266.453 | 0.842 | 0.400 |
Y_pos | 0.032 | 0.007 | 8276.033 | 4.294 | 0.000 |
trial_num:groupnaive | -0.001 | 0.000 | 8261.886 | -2.083 | 0.037 |
trial_num:exptsingle task | 0.002 | 0.000 | 8265.250 | 6.958 | 0.000 |
groupnaive:conditionout of play | -0.056 | 0.032 | 8260.536 | -1.764 | 0.078 |
exptsingle task:conditionout of play | -0.006 | 0.031 | 8262.576 | -0.194 | 0.846 |
groupnaive:Y_pos | 0.015 | 0.011 | 8266.453 | 1.412 | 0.158 |
exptsingle task:Y_pos | 0.002 | 0.010 | 8269.996 | 0.196 | 0.845 |
Now we see a significant effect of Y position with no remaining effect of “out of play.” Check for interactions?
kable(summary(lmer(log(RT) ~ trial_num * group * expt +
Y_pos * group * expt * condition +
(1 | subnum),
data = filter(d,
condition %in% c("in play","out of play"),
bead_type == "earth")))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.186 | 0.053 | 1451.318 | 22.177 | 0.000 |
trial_num | -0.002 | 0.000 | 8264.037 | -12.389 | 0.000 |
groupnaive | -0.554 | 0.076 | 1395.006 | -7.292 | 0.000 |
exptsingle task | -0.684 | 0.074 | 1435.486 | -9.215 | 0.000 |
Y_pos | 0.030 | 0.011 | 8272.173 | 2.795 | 0.005 |
conditionout of play | -0.005 | 0.077 | 8270.315 | -0.070 | 0.944 |
trial_num:groupnaive | -0.001 | 0.000 | 8258.967 | -2.093 | 0.036 |
trial_num:exptsingle task | 0.002 | 0.000 | 8262.229 | 6.953 | 0.000 |
groupnaive:Y_pos | 0.040 | 0.015 | 8264.475 | 2.671 | 0.008 |
exptsingle task:Y_pos | -0.025 | 0.015 | 8268.709 | -1.719 | 0.086 |
Y_pos:conditionout of play | 0.005 | 0.015 | 8270.444 | 0.324 | 0.746 |
groupnaive:conditionout of play | 0.188 | 0.111 | 8264.227 | 1.696 | 0.090 |
exptsingle task:conditionout of play | -0.273 | 0.108 | 8268.957 | -2.535 | 0.011 |
groupnaive:Y_pos:conditionout of play | -0.049 | 0.021 | 8264.941 | -2.310 | 0.021 |
exptsingle task:Y_pos:conditionout of play | 0.054 | 0.021 | 8269.564 | 2.591 | 0.010 |
Interestingly, we are seeing some three-way interactions, but these are a bit hard to interpret. Let’s subset to Experiments 1, 2, and 3.
kable(summary(lmer(log(RT) ~ trial_num +
Y_pos * condition +
(1 | subnum),
data = filter(d,
group == "experts",
expt == "dual task",
condition %in% c("in play","out of play"),
bead_type == "earth")))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 1.186 | 0.053 | 493.180 | 22.201 | 0.000 |
trial_num | -0.002 | 0.000 | 2727.389 | -12.390 | 0.000 |
Y_pos | 0.030 | 0.011 | 2730.094 | 2.796 | 0.005 |
conditionout of play | -0.005 | 0.077 | 2729.476 | -0.070 | 0.944 |
Y_pos:conditionout of play | 0.005 | 0.015 | 2729.519 | 0.324 | 0.746 |
kable(summary(lmer(log(RT) ~ trial_num +
Y_pos * condition +
(1 | subnum),
data = filter(d,
group == "experts",
expt == "single task",
condition %in% c("in play","out of play"),
bead_type == "earth")))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.502 | 0.057 | 580.806 | 8.882 | 0.000 |
trial_num | -0.001 | 0.000 | 2967.937 | -2.613 | 0.009 |
Y_pos | 0.004 | 0.011 | 2969.837 | 0.366 | 0.714 |
conditionout of play | -0.279 | 0.084 | 2970.836 | -3.336 | 0.001 |
Y_pos:conditionout of play | 0.059 | 0.016 | 2971.285 | 3.639 | 0.000 |
kable(summary(lmer(log(RT) ~ trial_num +
Y_pos * condition +
(1 | subnum),
data = filter(d,
group == "naive",
expt == "single task",
condition %in% c("in play","out of play"),
bead_type == "earth")))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | -0.052 | 0.049 | 333.905 | -1.056 | 0.292 |
trial_num | -0.001 | 0.000 | 2565.454 | -6.595 | 0.000 |
Y_pos | 0.044 | 0.009 | 2567.042 | 4.763 | 0.000 |
conditionout of play | -0.090 | 0.069 | 2566.383 | -1.308 | 0.191 |
Y_pos:conditionout of play | 0.009 | 0.013 | 2566.463 | 0.715 | 0.475 |
So we see the same unpredicted effect in Experiment 2 as in the previous analysis.
X_pos
is 1 for left-most position. VF
is a variable that maps further right displays to higher numbers.
d$VF <- d$X_pos - ((d$n_col / 2) + .5)
ggplot(d,
aes(x = VF, y = log(RT), col = factor(n_col))) +
geom_jitter(alpha = .02) +
geom_smooth(method = "lm") +
facet_grid(condition ~ expt) +
ylim(c(0,2)) +
theme_mikabr()
Model.
xpos_data <- d %>%
filter(group == "experts",
expt == "single task",
condition %in% c("in play",
"out of play")) %>%
mutate(x_pos_normalized = -X_pos / n_col)
kable(summary(lmer(log(RT) ~ trial_num +
VF * factor(n_col) +
(1 | subnum), data = xpos_data))$coefficients,
digits = 3)
Estimate | Std. Error | df | t value | Pr(>|t|) | |
---|---|---|---|---|---|
(Intercept) | 0.495 | 0.034 | 93.594 | 14.754 | 0.000 |
trial_num | 0.000 | 0.000 | 3982.112 | -1.820 | 0.069 |
VF | -0.069 | 0.019 | 3983.625 | -3.668 | 0.000 |
factor(n_col)3 | 0.162 | 0.013 | 3979.257 | 12.248 | 0.000 |
VF:factor(n_col)3 | 0.018 | 0.022 | 3983.358 | 0.819 | 0.413 |