Accuracy Analyses for Categorization Task
Libraries and Data Files
#load libraries
library(dplyr)
library(sciplot)
library(plotrix)
library(emmeans)
library(mgcv)
library(itsadug)
#Load data
data<- read.csv("AllData_Categorization.csv", header = TRUE)
Data Preprocessing
# Rename useful variables
data$acc <- data$Accuracy
data$sbj <- data$participant
data$block <- data$block.thisN + 1
# Convert variables to factors
data <- mutate_if(data, is.character, as.factor)
data$sbj <- as.factor(data$sbj)
data$group <- as.factor(data$group)
# Exclude only the participant who did not follow instructions
data <- droplevels(data[data$sbj != "20335", ])
# Create trial number
data$trial <- data$block.thisN * 80 + data$trials.thisN + 1
# Check number of participants per group
data %>%
distinct(sbj, group) %>%
count(group)
## group n
## 1 1100 15
## 2 1600 17
## 3 600 18
## 4 RD 16
RD Exposure Duration
rt_by_sbj_RD <- aggregate(RT ~ sbj, data = data[data$group == "RD", ], FUN = mean, na.rm = TRUE)
#descriptives
mean(rt_by_sbj_RD$RT)
## [1] 0.844926
sd(rt_by_sbj_RD$RT)
## [1] 0.210926
t.test(rt_by_sbj_RD$RT)$conf.int
## [1] 0.7325314 0.9573205
## attr(,"conf.level")
## [1] 0.95
Descriptive Statistics
#calculate participant's average accuracy
data_av<-aggregate(data$acc, list(data$sbj, data$group), mean)
colnames(data_av) <-c("sbj","group" ,"acc")
#write data frame, to use it in analysis examining correlation between learning accuracy and perceptual change
write.csv(data_av, "d_cat.csv", row.names = FALSE)
#by-group accuracy
#"600"
mean(data_av[data_av$group=="600",]$acc)
## [1] 0.8303819
sd(data_av[data_av$group=="600",]$acc)
## [1] 0.08761026
#"1100"
mean(data_av[data_av$group=="1100",]$acc)
## [1] 0.8670833
sd(data_av[data_av$group=="1100",]$acc)
## [1] 0.03201882
"#1600"
## [1] "#1600"
mean(data_av[data_av$group=="1600",]$acc)
## [1] 0.8689338
sd(data_av[data_av$group=="1600",]$acc)
## [1] 0.04216537
#"RD"
mean(data_av[data_av$group=="RD",]$acc)
## [1] 0.8714844
sd(data_av[data_av$group=="RD",]$acc)
## [1] 0.03289177
Learning-Curves Plot
##################
# Learning Curves
##################
bins <- 16 #thus, 16 bins of 20 trials (320 trials overall)
data <- data %>%
group_by(sbj) %>%
mutate(trial_bin = ntile(trial, bins)) %>%
ungroup()
data_tb<-aggregate(data$acc, list(data$sbj, data$group, data$trial_bin), mean)
colnames(data_tb) <-c("sbj","group","trial_bin","acc")
data_gr<-aggregate(data_tb$acc, list(data_tb$group, data_tb$trial_bin), mean)
colnames(data_gr)<-c("group","trial_bin", "acc")
temp<- aggregate(data_tb$acc, list(data_tb$group, data_tb$trial_bin), se)
data_gr$se<-temp$x
rm(temp)
data_gr<-data_gr[order(data_gr$group, data_gr$trial_bin),]
# Labels
xlb="Bins of 20 Trials"
ylb="Proportion Correct"
mn="Categorization Accuracy"
off=0.10
pch=c(15,16,17,18)
lty=c(2,3,4,5)
col=c("grey70","grey60","grey50", "grey40" )
x0 <- 1:bins
#"600"
plotCI(x=x0, y=data_gr[data_gr$group=="600",]$acc,
uiw=data_gr[data_gr$group=="600",]$se,
bty="n", ylim=c(0.5,1),xlim=c(1, bins+0.6),
xlab=xlb, ylab=ylb, main=mn, las=1, xaxt="n", yaxt="n",
pch=pch[1], col=col[1], gap=0, cex=1.5)
lines(x=x0, y=data_gr[data_gr$group=="600",]$acc, lty=lty[1], col=col[1], lwd=2)
#"1100"
plotCI(x=x0+off, y=data_gr[data_gr$group=="1100",]$acc,
uiw=data_gr[data_gr$group=="1100",]$se,
add=T, pch=pch[2], col=col[2], gap=0, cex=1.5)
lines(x=x0+off, y=data_gr[data_gr$group=="1100",]$acc, lty=lty[2], col=col[2], lwd=2)
#"1600"
plotCI(x=x0+2*off, y=data_gr[data_gr$group=="1600",]$acc,
uiw=data_gr[data_gr$group=="1600",]$se,
add=T, pch=pch[3], col=col[3], gap=0, cex=1.5)
lines(x=x0+2*off, y=data_gr[data_gr$group=="1600",]$acc, lty=lty[3], col=col[3], lwd=2)
#"RD"
plotCI(x=x0+3*off, y=data_gr[data_gr$group=="RD",]$acc,
uiw=data_gr[data_gr$group=="RD",]$se,
add=T, pch=pch[4], col=col[4], gap=0, cex=1.5)
lines(x=x0+3*off, y=data_gr[data_gr$group=="RD",]$acc, lty=lty[4], col=col[4], lwd=2)
axis(side=1, at=1:bins, labels=1:bins)
axis(side=2, at=c(0.5, 0.6, 0.7, 0.8, 0.9, 1.0),labels=c("0.0", "0.6", "0.7", "0.8", "0.9", "1.0") , las=2)
axis.break(2, 0.55, style="slash")
legend(x=round(bins*0.60), y=0.8, legend=c("600 ms", "1100 ms", "1600 ms", "RD"),
col=col, lty=lty, pch=pch, bty="n", seg.len=4, lwd=2, pt.cex=1.5)

### pixels: 1000 x 650
GAMMs - Inferential Analyses
# Set group order
data$group <- factor(
data$group,
levels = c("600", "1100", "1600", "RD")
)
# Standardize trial number
data$trial_s <- as.numeric(scale(data$trial))
# Create factor for difference smooths
data$group_diff <- ordered(data$group, levels = c("600", "1100", "1600", "RD"))
###############################
# Learning-curve model comparison
###############################
# Fit the shared-curve model using ML.
# ML is used here only to compare this model with a model
# allowing group-specific deviations in the learning curve.
m1_ML <- bam(
acc ~ group +
s(trial_s, k = 10) +
s(trial_s, sbj, bs = "fs", m = 1, k = 10),
data = data,
family = binomial(link = "logit"),
method = "ML",
discrete = FALSE
)
## Warning in gam.side(sm, X, tol = .Machine$double.eps^0.5): model has repeated
## 1-d smooths of same variable.
summary(m1_ML)
##
## Family: binomial
## Link function: logit
##
## Formula:
## acc ~ group + s(trial_s, k = 10) + s(trial_s, sbj, bs = "fs",
## m = 1, k = 10)
##
## Parametric coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.66701 0.08651 19.271 <2e-16 ***
## group1100 0.25303 0.12929 1.957 0.0503 .
## group1600 0.27525 0.12515 2.199 0.0279 *
## groupRD 0.28667 0.12719 2.254 0.0242 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Approximate significance of smooth terms:
## edf Ref.df Chi.sq p-value
## s(trial_s) 7.948 8.69 149.8 <2e-16 ***
## s(trial_s,sbj) 126.064 656.00 487.1 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## R-sq.(adj) = 0.0413 Deviance explained = 4.79%
## -ML = 8380.1 Scale est. = 1 n = 21120
###############################
# Group-specific curve model: ML estimation
###############################
# Fit the group-specific curve model using ML.
# This model will be compared with m1_ML to determine whether
# group-specific deviations improve the learning-curve model.
m2_ML <- bam(
acc ~ group +
s(trial_s, k = 10) +
s(trial_s, by = group_diff, k = 10) +
s(trial_s, sbj, bs = "fs", m = 1, k = 10),
data = data,
family = binomial(link = "logit"),
method = "ML",
discrete = FALSE
)
## Warning in gam.side(sm, X, tol = .Machine$double.eps^0.5): model has repeated
## 1-d smooths of same variable.
summary(m2_ML)
##
## Family: binomial
## Link function: logit
##
## Formula:
## acc ~ group + s(trial_s, k = 10) + s(trial_s, by = group_diff,
## k = 10) + s(trial_s, sbj, bs = "fs", m = 1, k = 10)
##
## Parametric coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.66642 0.08654 19.256 <2e-16 ***
## group1100 0.25527 0.12940 1.973 0.0485 *
## group1600 0.27784 0.12526 2.218 0.0265 *
## groupRD 0.28542 0.12723 2.243 0.0249 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Approximate significance of smooth terms:
## edf Ref.df Chi.sq p-value
## s(trial_s) 7.949 8.691 127.946 <2e-16 ***
## s(trial_s):group_diff1100 1.005 1.010 0.355 0.560
## s(trial_s):group_diff1600 1.004 1.007 0.407 0.526
## s(trial_s):group_diffRD 1.006 1.010 0.422 0.521
## s(trial_s,sbj) 122.164 656.000 481.029 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## R-sq.(adj) = 0.0411 Deviance explained = 4.77%
## -ML = 8379.1 Scale est. = 1 n = 21120
AIC(m1_ML, m2_ML)
## df AIC
## m1_ML 140.6691 16667.71
## m2_ML 140.0348 16670.12
delta_AIC <- AIC(m2_ML) - AIC(m1_ML)
delta_AIC
## [1] 2.410365
anova(m1_ML, m2_ML, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: acc ~ group + s(trial_s, k = 10) + s(trial_s, sbj, bs = "fs",
## m = 1, k = 10)
## Model 2: acc ~ group + s(trial_s, k = 10) + s(trial_s, by = group_diff,
## k = 10) + s(trial_s, sbj, bs = "fs", m = 1, k = 10)
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 20920 16386
## 2 20922 16390 -2.3279 -3.6789 0.2017
# Model 1 had modestly lower AIC than Model 2 (Delta AIC = 2.41).
# The addition of group-specific smooth deviations was therefore
# not sufficiently supported to prefer the more complex structure.
# Model 1 was retained as the more parsimonious model.
###############################
# Final model: shared learning curve
###############################
m1_fREML <- bam(
acc ~ group +
s(trial_s, k = 10) +
s(trial_s, sbj, bs = "fs", m = 1, k = 10),
data = data,
family = binomial(link = "logit"),
method = "fREML",
discrete = TRUE,
nthreads = 10
)
## Warning in gam.side(sm, X, tol = .Machine$double.eps^0.5): model has repeated
## 1-d smooths of same variable.
summary(m1_fREML)
##
## Family: binomial
## Link function: logit
##
## Formula:
## acc ~ group + s(trial_s, k = 10) + s(trial_s, sbj, bs = "fs",
## m = 1, k = 10)
##
## Parametric coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.66809 0.08913 18.716 <2e-16 ***
## group1100 0.25297 0.13315 1.900 0.0575 .
## group1600 0.27513 0.12889 2.135 0.0328 *
## groupRD 0.28667 0.13098 2.189 0.0286 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Approximate significance of smooth terms:
## edf Ref.df Chi.sq p-value
## s(trial_s) 7.983 8.708 150.3 <2e-16 ***
## s(trial_s,sbj) 126.796 656.000 490.8 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## R-sq.(adj) = 0.0413 Deviance explained = 4.8%
## fREML = 8390.5 Scale est. = 1 n = 21120
# Check model
set.seed(1234)
gam.check(m1_fREML,k.rep = 1000)

##
## Method: fREML Optimizer: perf chol
## $grad
## [1] -1.846125e-07 -2.521784e-05 -4.960516e-06
##
## $hess
## [,1] [,2] [,3]
## [1,] 2.56007093 -0.05002208 -0.03164658
## [2,] -0.05002208 11.58980420 0.08810668
## [3,] -0.03164658 0.08810668 21.92688559
##
## Model rank = 673 / 673
##
## Basis dimension (k) checking results. Low p-value (k-index<1) may
## indicate that k is too low, especially if edf is close to k'.
##
## k' edf k-index p-value
## s(trial_s) 9.00 7.98 0.94 0.31
## s(trial_s,sbj) 660.00 126.80 0.94 0.32
###############################
# Primary contrast
###############################
group_emm <- emmeans(m1_fREML, ~ group, at = list(trial_s = 0))
planned_contrast <- contrast( group_emm, method = list("Longer - 600" = c(-1, 1/3, 1/3, 1/3)), adjust = "none")
summary(planned_contrast,infer = c(TRUE, TRUE), type = "response",df = Inf)
## contrast odds.ratio SE df asymp.LCL asymp.UCL null z.ratio p.value
## Longer / 600 1.31 0.138 Inf 1.07 1.61 1 2.588 0.0097
##
## Degrees-of-freedom method: user-specified
## Confidence level used: 0.95
## Intervals are back-transformed from the log odds ratio scale
## Tests are performed on the log odds ratio scale
###############################
# Fixed-duration robustness contrast
###############################
fixed_contrast <- contrast(group_emm, method = list("Fixed longer - 600" = c(-1, 1/2, 1/2, 0)), adjust = "none")
summary(fixed_contrast, infer = c(TRUE, TRUE), type = "response", df = Inf)
## contrast odds.ratio SE df asymp.LCL asymp.UCL null z.ratio
## Fixed longer / 600 1.3 0.146 Inf 1.05 1.62 1 2.356
## p.value
## 0.0184
##
## Degrees-of-freedom method: user-specified
## Confidence level used: 0.95
## Intervals are back-transformed from the log odds ratio scale
## Tests are performed on the log odds ratio scale
###############################
# Supplementary omnibus group test
###############################
# Test whether the four groups differ overall.
omnibus_group <- anova(m1_fREML, freq = FALSE)
omnibus_group
##
## Family: binomial
## Link function: logit
##
## Formula:
## acc ~ group + s(trial_s, k = 10) + s(trial_s, sbj, bs = "fs",
## m = 1, k = 10)
##
## Parametric Terms:
## df Chi.sq p-value
## group 3 6.784 0.0791
##
## Approximate significance of smooth terms:
## edf Ref.df Chi.sq p-value
## s(trial_s) 7.983 8.708 150.3 <2e-16
## s(trial_s,sbj) 126.796 656.000 490.8 <2e-16
##############################
# Secondary comparisons with the 600-ms group
###############################
# Compare each longer viewing regime with the 600-ms reference group.
# The three comparisons constitute one family of tests.
dunnett_group <- contrast(group_emm, method = "trt.vs.ctrl", ref = "600")
# Report log-odds differences with multiplicity-adjusted
# confidence intervals and p values.
set.seed(1234)
summary(dunnett_group, infer = c(TRUE, TRUE), adjust = "mvt", df = Inf)
## contrast estimate SE df asymp.LCL asymp.UCL z.ratio p.value
## 1100 - 600 0.253 0.133 Inf -0.0607 0.567 1.900 0.1456
## 1600 - 600 0.275 0.129 Inf -0.0284 0.579 2.135 0.0860
## RD - 600 0.287 0.131 Inf -0.0218 0.595 2.189 0.0756
##
## Degrees-of-freedom method: user-specified
## Results are given on the log odds ratio (not the response) scale.
## Confidence level used: 0.95
## Conf-level adjustment: mvt method for 3 estimates
## P value adjustment: mvt method for 3 tests
# Report the same comparisons as odds ratios.
set.seed(1234)
summary(dunnett_group, infer = c(TRUE, TRUE), type = "response", adjust = "mvt", df = Inf)
## contrast odds.ratio SE df asymp.LCL asymp.UCL null z.ratio p.value
## 1100 / 600 1.29 0.171 Inf 0.941 1.76 1 1.900 0.1456
## 1600 / 600 1.32 0.170 Inf 0.972 1.78 1 2.135 0.0860
## RD / 600 1.33 0.174 Inf 0.978 1.81 1 2.189 0.0756
##
## Degrees-of-freedom method: user-specified
## Confidence level used: 0.95
## Conf-level adjustment: mvt method for 3 estimates
## Intervals are back-transformed from the log odds ratio scale
## P value adjustment: mvt method for 3 tests
## Tests are performed on the log odds ratio scale
Model-Predictions Plot
fm <- m1_fREML
labx="Trial"
#labx="Trial\n Error Bands: 95% CI"
main="Categorization Accuracy - Model Predictions"
col=c("grey70","grey60","grey50", "grey40" )
lty=c(2,3,4,5)
alpha_shade <- 0.4
# draw band (transparent) + redraw line (opaque)
plot_group <- function(g, i, first = FALSE) {
col_band <- adjustcolor(col[i], alpha.f = alpha_shade)
# 1) band (and faint line)
plot_smooth(
fm, view="trial_s", cond=list(group=g),
rm.ranef=T,
shade=TRUE, se=1.96,
print.summary=FALSE,
ylim=c(0.5,1),
transform=plogis,
xlab=if (first) labx else "",
ylab=if (first) "Proportion Correct" else "",
lwd=2, las=2, rug=FALSE,
col=col_band, lty=lty[i],
hide.label=TRUE,
main=if (first) main else "",
yaxs="i", xaxt=if (first) "n" else "n", yaxt=if (first) "n" else "n",
add = !first
)
# 2) line only (opaque)
plot_smooth(
fm, view="trial_s", cond=list(group=g),
rm.ranef=T,
shade=FALSE, se=0,
print.summary=FALSE,
transform=plogis,
lwd=2, rug=FALSE,
col=col[i], lty=lty[i],
hide.label=TRUE,
add=TRUE
)
}
plot_group("600", 1, first=TRUE)
plot_group("1100", 2)
plot_group("1600", 3)
plot_group("RD", 4)
mu <- attr(scale(data$trial), "scaled:center")
sd <- attr(scale(data$trial), "scaled:scale")
ticks_raw <- c(0,50,100,150,200,250,300,320)
ticks_s <- (ticks_raw - mu) / sd
axis(side=1, at=ticks_s, labels=ticks_raw)
axis(side=2, at=c(0.5, 0.6, 0.7, 0.8, 0.9, 1.0),labels=c("0.0", "0.6", "0.7", "0.8", "0.9", "1.0") , las=2)
axis.break(2, 0.55, style="slash")
legend(x=(200-mu)/sd, y=0.75, legend=c("600 ms", "1100 ms", "1600 ms", "RD"), col=col, lty=lty, bty="n", seg.len=4, lwd=2, pt.cex=1.5)

# graph for paper 1000 x 650
Common Sample - Sensitivity Analysis
###############################
# Common-sample exclusions
###############################
# Participants excluded for not meeting the learning criterion.
accuracy_exclusions <- c("43423", "48888", "63018", "77337", "77623")
# Learning-criterion failure rates across groups
learning_status <- data %>%
distinct(sbj, group) %>%
mutate(nonlearner = as.character(sbj) %in% accuracy_exclusions)
# Rows: groups; columns: learners (FALSE), nonlearners (TRUE)
learning_table <- with(learning_status, table(group, nonlearner))
learning_table
## nonlearner
## group FALSE TRUE
## 600 16 2
## 1100 15 0
## 1600 15 2
## RD 15 1
# Percentage of nonlearners within each group
round(100 * prop.table(learning_table, margin = 1)[, "TRUE"], 1)
## 600 1100 1600 RD
## 11.1 0.0 11.8 6.2
# Fisher's exact test for the 4 × 2 table
fisher.test(learning_table, simulate.p.value = FALSE)
##
## Fisher's Exact Test for Count Data
##
## data: learning_table
## p-value = 0.7453
## alternative hypothesis: two.sided
# Participants excluded because they received the initial
# similarity-rating instructions.
instruction_exclusions <- c("17202", "57393", "94372", "40242", "89443")
data_common <- data %>% filter(!as.character(sbj) %in% c(accuracy_exclusions, instruction_exclusions)) %>% droplevels()
###############################
# Common-sample sensitivity model
###############################
# Fit the selected shared-curve model to the common sample.
# The model structure is held constant relative to the primary analysis.
m1_common_fREML <- bam(acc ~ group + s(trial_s, k = 10) + s(trial_s, sbj, bs = "fs", m = 1, k = 10), data = data_common, family = binomial(link = "logit"), method = "fREML", discrete = TRUE, nthreads = 10)
## Warning in gam.side(sm, X, tol = .Machine$double.eps^0.5): model has repeated
## 1-d smooths of same variable.
summary(m1_common_fREML)
##
## Family: binomial
## Link function: logit
##
## Formula:
## acc ~ group + s(trial_s, k = 10) + s(trial_s, sbj, bs = "fs",
## m = 1, k = 10)
##
## Parametric coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.74073 0.06940 25.082 < 2e-16 ***
## group1100 0.16044 0.09915 1.618 0.10561
## group1600 0.30010 0.10020 2.995 0.00274 **
## groupRD 0.25104 0.09979 2.516 0.01188 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Approximate significance of smooth terms:
## edf Ref.df Chi.sq p-value
## s(trial_s) 7.945 8.685 131.8 <2e-16 ***
## s(trial_s,sbj) 102.756 556.000 219.1 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## R-sq.(adj) = 0.0277 Deviance explained = 3.61%
## fREML = 6921.1 Scale est. = 1 n = 17920
# Check convergence and whether the basis dimensions are adequate.
set.seed(1234)
gam.check(m1_common_fREML, k.rep = 1000)

##
## Method: fREML Optimizer: perf chol
## $grad
## [1] -2.932397e-08 -3.376176e-06 -1.117799e-06
##
## $hess
## [,1] [,2] [,3]
## [1,] 2.46715363 -0.05305422 -0.0175836
## [2,] -0.05305422 11.56434835 0.4206303
## [3,] -0.01758360 0.42063033 9.3625120
##
## Model rank = 573 / 573
##
## Basis dimension (k) checking results. Low p-value (k-index<1) may
## indicate that k is too low, especially if edf is close to k'.
##
## k' edf k-index p-value
## s(trial_s) 9.00 7.94 0.96 0.57
## s(trial_s,sbj) 560.00 102.76 0.96 0.58
###############################
# Common-sample contrast
###############################
# Estimate group means at the midpoint of the experiment.
group_emm_common <- emmeans(m1_common_fREML, ~ group, at = list(trial_s = 0))
# Compare the 600-ms group with the average of the three longer viewing regimes.
planned_contrast_common <- contrast(group_emm_common, method = list("Longer - 600" = c(-1, 1/3, 1/3, 1/3)), adjust = "none")
# Report the contrast as an odds ratio with its confidence interval.
summary(planned_contrast_common, infer = c(TRUE, TRUE), type = "response", df = Inf)
## contrast odds.ratio SE df asymp.LCL asymp.UCL null z.ratio p.value
## Longer / 600 1.27 0.102 Inf 1.08 1.49 1 2.937 0.0033
##
## Degrees-of-freedom method: user-specified
## Confidence level used: 0.95
## Intervals are back-transformed from the log odds ratio scale
## Tests are performed on the log odds ratio scale
###############################
# Common-sample fixed-duration robustness contrast
###############################
# Test the same fixed-duration contrast in the common sample.
fixed_contrast_common <- contrast(
group_emm_common,
method = list("Fixed longer - 600" = c(-1, 1/2, 1/2, 0)),
adjust = "none"
)
summary(fixed_contrast_common, infer = c(TRUE, TRUE), type = "response", df = Inf)
## contrast odds.ratio SE df asymp.LCL asymp.UCL null z.ratio
## Fixed longer / 600 1.26 0.108 Inf 1.06 1.49 1 2.682
## p.value
## 0.0073
##
## Degrees-of-freedom method: user-specified
## Confidence level used: 0.95
## Intervals are back-transformed from the log odds ratio scale
## Tests are performed on the log odds ratio scale
###############################
# Common-sample omnibus group test
###############################
# Test whether the four groups differ overall in the common sample.
omnibus_group_common <- anova(m1_common_fREML, freq = FALSE)
omnibus_group_common
##
## Family: binomial
## Link function: logit
##
## Formula:
## acc ~ group + s(trial_s, k = 10) + s(trial_s, sbj, bs = "fs",
## m = 1, k = 10)
##
## Parametric Terms:
## df Chi.sq p-value
## group 3 10.52 0.0146
##
## Approximate significance of smooth terms:
## edf Ref.df Chi.sq p-value
## s(trial_s) 7.945 8.685 131.8 <2e-16
## s(trial_s,sbj) 102.756 556.000 219.1 <2e-16
###############################
# Common-sample Dunnett comparisons
###############################
# Compare each longer viewing regime with the 600-ms reference group.
dunnett_group_common <- contrast(group_emm_common, method = "trt.vs.ctrl", ref = "600")
# Report log-odds differences with multiplicity-adjusted
# confidence intervals and p values.
set.seed(1234)
summary(dunnett_group_common, infer = c(TRUE, TRUE), adjust = "mvt", df = Inf)
## contrast estimate SE df asymp.LCL asymp.UCL z.ratio p.value
## 1100 - 600 0.160 0.0991 Inf -0.0727 0.394 1.618 0.2506
## 1600 - 600 0.300 0.1000 Inf 0.0644 0.536 2.995 0.0078
## RD - 600 0.251 0.0998 Inf 0.0163 0.486 2.516 0.0322
##
## Degrees-of-freedom method: user-specified
## Results are given on the log odds ratio (not the response) scale.
## Confidence level used: 0.95
## Conf-level adjustment: mvt method for 3 estimates
## P value adjustment: mvt method for 3 tests
# Report the Dunnett-adjusted comparisons as odds ratios.
set.seed(1234)
summary(dunnett_group_common, infer = c(TRUE, TRUE), type = "response", adjust = "mvt", df = Inf)
## contrast odds.ratio SE df asymp.LCL asymp.UCL null z.ratio p.value
## 1100 / 600 1.17 0.116 Inf 0.93 1.48 1 1.618 0.2506
## 1600 / 600 1.35 0.135 Inf 1.07 1.71 1 2.995 0.0078
## RD / 600 1.29 0.128 Inf 1.02 1.63 1 2.516 0.0322
##
## Degrees-of-freedom method: user-specified
## Confidence level used: 0.95
## Conf-level adjustment: mvt method for 3 estimates
## Intervals are back-transformed from the log odds ratio scale
## P value adjustment: mvt method for 3 tests
## Tests are performed on the log odds ratio scale
Session Information
sessionInfo()
## R version 4.6.1 (2026-06-24 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26200)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=English_United States.utf8
## [2] LC_CTYPE=English_United States.utf8
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C
## [5] LC_TIME=English_United States.utf8
##
## time zone: Europe/Athens
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] itsadug_2.5 plotfunctions_1.5 mgcv_1.9-4 nlme_3.1-169
## [5] emmeans_2.0.4 plotrix_3.8-14 sciplot_1.2-0 dplyr_1.2.1
##
## loaded via a namespace (and not attached):
## [1] Matrix_1.7-5 jsonlite_2.0.0 compiler_4.6.1 tidyselect_1.2.1
## [5] jquerylib_0.1.4 splines_4.6.1 yaml_2.3.12 fastmap_1.2.0
## [9] lattice_0.22-9 R6_2.6.1 generics_0.1.4 knitr_1.51
## [13] tibble_3.3.1 bslib_0.11.0 pillar_1.11.1 rlang_1.3.0
## [17] cachem_1.1.0 xfun_0.60 sass_0.4.10 estimability_2.0.0
## [21] cli_3.6.6 withr_3.0.3 magrittr_2.0.5 digest_0.6.39
## [25] grid_4.6.1 rstudioapi_0.19.0 mvtnorm_1.4-2 lifecycle_1.0.5
## [29] vctrs_0.7.3 evaluate_1.0.5 glue_1.8.1 stats4_4.6.1
## [33] rmarkdown_2.31 tools_4.6.1 pkgconfig_2.0.3 htmltools_0.5.9