# This setup chunk loads the packages needed for the analysis.
# Packages should be installed in the Console before knitting, not inside this file.
library(readxl) # reads Excel files
library(janitor) # cleans column names
library(tidyverse) # data cleaning and visualization
library(lme4) # mixed-effects models
library(lmerTest) # p-values for lmer models
library(glmmTMB) # negative binomial mixed-effects model for count data
library(performance) # model checks, especially overdispersion
library(emmeans) # estimated marginal means, useful for follow-up comparisons
Research question
This analysis examines infant exploration of 2D versus 3D
stimuli. The main research question is:
Which factors significantly predict infant exploration of 2D and 3D
stimuli?
Infant exploration is measured using three dependent variables:
- Touch duration: how long the infant touched the
stimulus.
- Touch latency: how quickly the infant first touched
the stimulus.
- Touch frequency: how many times the infant touched
the stimulus.
The main independent variables are:
- Object type: 2D versus 3D stimulus. In this
dataset,
block = 2 is coded as 2D and
block = 3 is coded as 3D.
- Condition: neutral versus negative social
information condition.
- Age: infant age converted into numeric months.
- Sex: infant sex.
- Trial ordinal: trial order, included to control for
practice, fatigue, or order effects across the task.
Because the same infants contributed multiple trials and the same
stimulus items appeared across trials, mixed-effects models were used.
This is important because repeated observations from the same infant are
not independent.
Fixed and random effects
In these models, the fixed effects are the
predictors being tested directly:
object_type
condition
age_numeric
sex
trial_ordinal
object_type:condition
object_type:age_numeric
The random effects control for natural variation due
to repeated measurements:
(1 | subject_id): controls for baseline differences
between infants.
(1 | item): controls for baseline differences between
stimulus items.
The variable socinf was not included in the final models
because it codes the same manipulation as condition.
Including both caused redundancy/rank-deficiency, so
condition was kept because it is easier to interpret.
The variable block was also not included as a predictor
after creating object_type, because
object_type is directly created from block.
Including both would test the same information twice.
Load data
# The Excel file has an extra title row, so skip = 1 is used to make the actual column names the headers.
df <- read_excel("~/Downloads/touch_data.xlsx", skip = 1) %>%
clean_names()
# Check that the file loaded correctly.
names(df)
## [1] "file" "subject_id"
## [3] "sex" "age"
## [5] "condition" "block"
## [7] "trial_ordinal" "exp"
## [9] "socinf" "item"
## [11] "trial_onset" "trial_offset"
## [13] "trial_duration_ms" "n_touches_total"
## [15] "n_touches_top" "n_touches_bottom"
## [17] "n_touches_screen_holder" "add_touch"
## [19] "ratio_top" "ratio_bottom"
## [21] "ratio_screen_holder" "first_touch_part"
## [23] "first_touch_onset" "latency_first_touch"
## [25] "first_top_touch_onset" "latency_first_top"
## [27] "total_touch_duration" "top_touch_duration"
head(df)
## # A tibble: 6 × 28
## file subject_id sex age condition block trial_ordinal exp socinf item
## <chr> <dbl> <chr> <chr> <chr> <dbl> <dbl> <chr> <chr> <chr>
## 1 D3_01… 15 fema… 16m … neutral 2 1 s a kn
## 2 D3_01… 15 fema… 16m … neutral 2 2 s a sn
## 3 D3_01… 15 fema… 16m … neutral 2 3 s a ge
## 4 D3_01… 15 fema… 16m … neutral 2 4 s a sa
## 5 D3_01… 15 fema… 16m … neutral 2 5 s a oa
## 6 D3_01… 15 fema… 16m … neutral 2 6 s a ba
## # ℹ 18 more variables: trial_onset <dbl>, trial_offset <dbl>,
## # trial_duration_ms <dbl>, n_touches_total <dbl>, n_touches_top <dbl>,
## # n_touches_bottom <dbl>, n_touches_screen_holder <dbl>, add_touch <dbl>,
## # ratio_top <dbl>, ratio_bottom <dbl>, ratio_screen_holder <dbl>,
## # first_touch_part <chr>, first_touch_onset <dbl>, latency_first_touch <dbl>,
## # first_top_touch_onset <dbl>, latency_first_top <dbl>,
## # total_touch_duration <dbl>, top_touch_duration <dbl>
Clean and prepare variables
df_clean <- df %>%
mutate(
# Convert grouping and categorical variables to factors.
subject_id = as.factor(subject_id),
sex = as.factor(sex),
condition = as.factor(condition),
block = as.factor(block),
item = as.factor(item),
exp = as.factor(exp),
# In this dataset, block 2 is 2D and block 3 is 3D.
# This creates the main predictor for the 2D vs. 3D comparison.
object_type = case_when(
block == 2 ~ "2D",
block == 3 ~ "3D",
block == "2" ~ "2D",
block == "3" ~ "3D",
TRUE ~ NA_character_
),
object_type = as.factor(object_type),
# Convert age from a string like "16m 3d" into numeric months.
age_months = as.numeric(str_extract(age, "\\d+(?=m)")),
age_days = as.numeric(str_extract(age, "\\d+(?=d)")),
age_days = ifelse(is.na(age_days), 0, age_days),
age_numeric = age_months + age_days / 30.44,
# Create clearer names for the dependent variables.
n_touch = as.numeric(n_touches_total),
touch_duration = as.numeric(total_touch_duration),
touch_latency = as.numeric(latency_first_touch),
# There was one impossible negative touch duration value in the data.
# A negative duration cannot be interpreted as real behavior, so it is treated as missing.
touch_duration = ifelse(touch_duration < 0, NA, touch_duration),
# Duration and latency are right-skewed, so log-transformations are used.
# Adding 1 allows the log transform to handle zero values.
log_duration = log(touch_duration + 1),
log_latency = log(touch_latency + 1)
)
# Check that object_type was created correctly.
table(df_clean$block, df_clean$object_type, useNA = "ifany")
##
## 2D 3D
## 2 404 0
## 3 0 401
# Summary of cleaned data.
summary(df_clean)
## file subject_id sex age
## Length:805 41 : 17 female:409 Length:805
## Class :character 59 : 17 male :396 Class :character
## Mode :character 63 : 17 Mode :character
## 2 : 16
## 4 : 16
## 5 : 16
## (Other):706
## condition block trial_ordinal exp socinf
## negative:356 2:404 Min. :1.000 k:378 Length:805
## neutral :434 3:401 1st Qu.:2.000 s:427 Class :character
## NA's : 15 Median :4.000 Mode :character
## Mean :4.453
## 3rd Qu.:6.000
## Max. :9.000
##
## item trial_onset trial_offset trial_duration_ms
## bc : 52 Min. : 11968 Min. : 17750 Min. : 4184
## ge : 52 1st Qu.: 75718 1st Qu.: 93706 1st Qu.: 5986
## sc : 52 Median :150212 Median :163644 Median :11290
## gp : 51 Mean :155201 Mean :171668 Mean :16467
## oa : 51 3rd Qu.:220524 3rd Qu.:237662 3rd Qu.:30000
## ro : 51 Max. :439314 Max. :459828 Max. :42580
## (Other):496
## n_touches_total n_touches_top n_touches_bottom n_touches_screen_holder
## Min. : 0.00 Min. :0.00 Min. : 0.0000 Min. : 0.000
## 1st Qu.: 1.00 1st Qu.:0.00 1st Qu.: 0.0000 1st Qu.: 0.000
## Median : 3.00 Median :1.00 Median : 0.0000 Median : 0.000
## Mean : 4.19 Mean :1.27 Mean : 0.8211 Mean : 2.099
## 3rd Qu.: 6.00 3rd Qu.:2.00 3rd Qu.: 1.0000 3rd Qu.: 4.000
## Max. :28.00 Max. :9.00 Max. :11.0000 Max. :21.000
##
## add_touch ratio_top ratio_bottom ratio_screen_holder
## Min. :1.000 Min. :0.0000 Min. :0.0000 Min. :0.0000
## 1st Qu.:1.000 1st Qu.:0.1111 1st Qu.:0.0000 1st Qu.:0.0000
## Median :1.000 Median :0.3750 Median :0.0000 Median :0.0000
## Mean :1.147 Mean :0.4557 Mean :0.2094 Mean :0.3348
## 3rd Qu.:1.000 3rd Qu.:1.0000 3rd Qu.:0.3875 3rd Qu.:0.7143
## Max. :2.000 Max. :1.0000 Max. :1.0000 Max. :1.0000
## NA's :118 NA's :118 NA's :118
## first_touch_part first_touch_onset latency_first_touch first_top_touch_onset
## Length:805 Min. : 12660 Min. : 0 Min. : 12750
## Class :character 1st Qu.: 80739 1st Qu.: 476 1st Qu.: 85340
## Mode :character Median :152388 Median : 987 Median :152388
## Mean :157582 Mean : 3328 Mean :157727
## 3rd Qu.:221081 3rd Qu.: 2822 3rd Qu.:222156
## Max. :440164 Max. :31180 Max. :440164
## NA's :118 NA's :118 NA's :268
## latency_first_top total_touch_duration top_touch_duration object_type
## Min. : 0 Min. :-203320 Min. : 0 2D:404
## 1st Qu.: 680 1st Qu.: 2076 1st Qu.: 0 3D:401
## Median : 1972 Median : 6052 Median : 816
## Mean : 4964 Mean : 8987 Mean : 2456
## 3rd Qu.: 6360 3rd Qu.: 13090 3rd Qu.: 3332
## Max. :37580 Max. : 88774 Max. :30702
## NA's :268
## age_months age_days age_numeric n_touch
## Min. : 1.00 Min. : 0.00 Min. : 1.394 Min. : 0.00
## 1st Qu.:14.00 1st Qu.:10.00 1st Qu.:14.821 1st Qu.: 1.00
## Median :15.00 Median :20.00 Median :15.624 Median : 3.00
## Mean :14.65 Mean :17.36 Mean :15.216 Mean : 4.19
## 3rd Qu.:15.00 3rd Qu.:25.00 3rd Qu.:15.986 3rd Qu.: 6.00
## Max. :16.00 Max. :30.00 Max. :16.460 Max. :28.00
##
## touch_duration touch_latency log_duration log_latency
## Min. : 0 Min. : 0 Min. : 0.000 Min. : 0.000
## 1st Qu.: 2094 1st Qu.: 476 1st Qu.: 7.647 1st Qu.: 6.168
## Median : 6086 Median : 987 Median : 8.714 Median : 6.896
## Mean : 9251 Mean : 3328 Mean : 7.528 Mean : 6.742
## 3rd Qu.:13092 3rd Qu.: 2822 3rd Qu.: 9.480 3rd Qu.: 7.946
## Max. :88774 Max. :31180 Max. :11.394 Max. :10.348
## NA's :1 NA's :118 NA's :1 NA's :118
Model 1: Touch duration
Touch duration is continuous and right-skewed, so the outcome used
here is log_duration.
The model tests whether touch duration differs by object type,
condition, age, sex, trial order, and whether the 2D/3D difference
changes by condition or age.
duration_model <- lmer(
log_duration ~ object_type * condition + object_type * age_numeric +
sex + trial_ordinal +
(1 | subject_id) + (1 | item),
data = df_clean,
na.action = na.omit
)
summary(duration_model)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: log_duration ~ object_type * condition + object_type * age_numeric +
## sex + trial_ordinal + (1 | subject_id) + (1 | item)
## Data: df_clean
##
## REML criterion at convergence: 3891.1
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.5459 -0.3008 0.1212 0.5204 3.0815
##
## Random effects:
## Groups Name Variance Std.Dev.
## subject_id (Intercept) 4.2027 2.0500
## item (Intercept) 0.1115 0.3339
## Residual 6.8836 2.6237
## Number of obs: 789, groups: subject_id, 51; item, 16
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 7.40467 2.39044 55.96230 3.098 0.003048
## object_type3D 1.02837 1.39127 724.49376 0.739 0.460050
## conditionneutral -0.10553 0.63988 56.26933 -0.165 0.869596
## age_numeric -0.05216 0.15832 55.00312 -0.329 0.743039
## sexmale 0.31966 0.61340 46.63865 0.521 0.604746
## trial_ordinal 0.15736 0.04088 721.65571 3.849 0.000129
## object_type3D:conditionneutral 1.17691 0.38343 726.19079 3.069 0.002225
## object_type3D:age_numeric -0.09811 0.09145 722.45189 -1.073 0.283715
##
## (Intercept) **
## object_type3D
## conditionneutral
## age_numeric
## sexmale
## trial_ordinal ***
## object_type3D:conditionneutral **
## object_type3D:age_numeric
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) obj_3D cndtnn ag_nmr sexmal trl_rd ob_3D:
## objct_typ3D -0.291
## conditnntrl -0.021 0.007
## age_numeric -0.969 0.283 -0.126
## sexmale 0.031 -0.001 0.040 -0.162
## trial_ordnl -0.077 -0.001 -0.004 0.001 0.006
## objct_ty3D: 0.008 -0.022 -0.300 0.039 -0.012 -0.007
## objct_t3D:_ 0.284 -0.979 0.039 -0.289 0.005 0.003 -0.133
anova(duration_model)
## Type III Analysis of Variance Table with Satterthwaite's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## object_type 9.177 9.177 1 724.09 1.3332 0.248622
## condition 4.307 4.307 1 46.70 0.6257 0.432929
## age_numeric 3.070 3.070 1 46.22 0.4460 0.507558
## sex 1.869 1.869 1 46.64 0.2716 0.604746
## trial_ordinal 101.989 101.989 1 721.66 14.8163 0.000129 ***
## object_type:condition 64.851 64.851 1 726.19 9.4212 0.002225 **
## object_type:age_numeric 7.922 7.922 1 722.45 1.1509 0.283715
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Touch duration interpretation
Based on the current model output:
trial_ordinal was significant, p = 0.000129.
This suggests that touch duration changed across trial order.
object_type:condition was significant, p =
0.002225. This suggests that the difference between 2D and 3D touch
duration depended on whether the trial was in the neutral or negative
condition.
object_type alone was not significant, p =
0.248622.
condition alone was not significant, p =
0.432929.
age_numeric was not significant, p =
0.507558.
sex was not significant, p = 0.604746.
object_type:age_numeric was not significant, p
= 0.283715.
Overall, the duration model suggests that trial
order and the interaction between object type and
condition are the strongest predictors of touch duration.
Model 2: Touch latency
Touch latency is also continuous and right-skewed, so the outcome
used here is log_latency.
This model tests whether infants touched faster or slower depending
on object type, condition, age, sex, trial order, and the object type
interactions.
latency_model <- lmer(
log_latency ~ object_type * condition + object_type * age_numeric +
sex + trial_ordinal +
(1 | subject_id) + (1 | item),
data = df_clean,
na.action = na.omit
)
## boundary (singular) fit: see help('isSingular')
summary(latency_model)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: log_latency ~ object_type * condition + object_type * age_numeric +
## sex + trial_ordinal + (1 | subject_id) + (1 | item)
## Data: df_clean
##
## REML criterion at convergence: 2783.1
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.5943 -0.4273 0.0462 0.5370 3.0970
##
## Random effects:
## Groups Name Variance Std.Dev.
## subject_id (Intercept) 2.341 1.530
## item (Intercept) 0.000 0.000
## Residual 3.048 1.746
## Number of obs: 672, groups: subject_id, 51; item, 16
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 6.39901 1.75318 49.61301 3.650 0.000630
## object_type3D 0.73852 0.92814 615.34618 0.796 0.426514
## conditionneutral 0.53454 0.47987 54.01921 1.114 0.270241
## age_numeric 0.06831 0.11628 48.99984 0.587 0.559596
## sexmale -0.45992 0.45963 44.68530 -1.001 0.322392
## trial_ordinal -0.11504 0.02953 618.18804 -3.895 0.000109
## object_type3D:conditionneutral -0.72150 0.28363 628.57464 -2.544 0.011203
## object_type3D:age_numeric -0.03911 0.06124 616.01846 -0.639 0.523312
##
## (Intercept) ***
## object_type3D
## conditionneutral
## age_numeric
## sexmale
## trial_ordinal ***
## object_type3D:conditionneutral *
## object_type3D:age_numeric
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) obj_3D cndtnn ag_nmr sexmal trl_rd ob_3D:
## objct_typ3D -0.266
## conditnntrl -0.023 0.012
## age_numeric -0.968 0.257 -0.129
## sexmale 0.030 0.001 0.054 -0.166
## trial_ordnl -0.078 0.001 -0.010 0.001 0.005
## objct_ty3D: 0.010 -0.027 -0.301 0.038 -0.035 0.014
## objct_t3D:_ 0.258 -0.974 0.038 -0.263 0.007 0.000 -0.144
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
anova(latency_model)
## Type III Analysis of Variance Table with Satterthwaite's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## object_type 0.497 0.497 1 615.48 0.1632 0.6863631
## condition 0.439 0.439 1 44.82 0.1442 0.7059355
## age_numeric 0.576 0.576 1 42.44 0.1889 0.6660435
## sex 3.051 3.051 1 44.69 1.0013 0.3223919
## trial_ordinal 46.243 46.243 1 618.19 15.1739 0.0001087 ***
## object_type:condition 19.721 19.721 1 628.57 6.4711 0.0112026 *
## object_type:age_numeric 1.243 1.243 1 616.02 0.4078 0.5233121
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Touch latency interpretation
Based on the current model output:
trial_ordinal was significant, p = 0.0001087.
This suggests that latency changed across trial order.
object_type:condition was significant, p =
0.0112026. This suggests that the difference between 2D and 3D latency
depended on condition.
object_type alone was not significant, p =
0.6863631.
condition alone was not significant, p =
0.7059355.
age_numeric was not significant, p =
0.6660435.
sex was not significant, p = 0.3223919.
object_type:age_numeric was not significant, p
= 0.5233121.
The latency model produced a singular fit warning because the
random-effect variance for item was estimated as 0. This
means item did not explain much additional variability in latency. This
is not unusual, but it should be mentioned to the professor as a
model-diagnostic point.
Overall, the latency model suggests that trial order
and the object type by condition interaction
significantly predict how quickly infants first touch the stimulus.
Model 3: Touch frequency
Touch frequency is count data, so a normal linear model is not
appropriate. A Poisson model was checked first, but overdispersion was
detected. Because of this, the final frequency model uses a
negative binomial mixed-effects model.
frequency_model_nb <- glmmTMB(
n_touch ~ object_type * condition + object_type * age_numeric +
sex + trial_ordinal +
(1 | subject_id) + (1 | item),
data = df_clean,
family = nbinom2,
na.action = na.omit
)
summary(frequency_model_nb)
## Family: nbinom2 ( log )
## Formula:
## n_touch ~ object_type * condition + object_type * age_numeric +
## sex + trial_ordinal + (1 | subject_id) + (1 | item)
## Data: df_clean
##
## AIC BIC logLik -2*log(L) df.resid
## 3689.6 3741.0 -1833.8 3667.6 779
##
## Random effects:
##
## Conditional model:
## Groups Name Variance Std.Dev.
## subject_id (Intercept) 0.24821 0.4982
## item (Intercept) 0.03115 0.1765
## Number of obs: 790, groups: subject_id, 51; item, 16
##
## Dispersion parameter for nbinom2 family (): 4.04
##
## Conditional model:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.796181 0.580573 3.094 0.00198 **
## object_type3D -1.010971 0.387774 -2.607 0.00913 **
## conditionneutral 0.045924 0.158218 0.290 0.77162
## age_numeric -0.018418 0.038356 -0.480 0.63110
## sexmale 0.096153 0.152616 0.630 0.52867
## trial_ordinal 0.013369 0.011561 1.156 0.24753
## object_type3D:conditionneutral 0.274822 0.111951 2.455 0.01409 *
## object_type3D:age_numeric -0.002385 0.025511 -0.094 0.92552
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
drop1(frequency_model_nb, test = "Chisq")
## Single term deletions
##
## Model:
## n_touch ~ object_type * condition + object_type * age_numeric +
## sex + trial_ordinal + (1 | subject_id) + (1 | item)
## Df AIC LRT Pr(>Chi)
## <none> 3689.6
## sex 1 3688.0 0.3972 0.52855
## trial_ordinal 1 3689.0 1.3366 0.24763
## object_type:condition 1 3693.7 6.0299 0.01407 *
## object_type:age_numeric 1 3687.6 0.0087 0.92553
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Touch frequency interpretation
Based on the current negative binomial model output:
object_type3D was significant in the model summary,
p = 0.00913. This suggests that touch frequency differed
between 2D and 3D stimuli.
object_type3D:conditionneutral was significant in the
model summary, p = 0.01409.
- The likelihood-ratio test from
drop1() also found
object_type:condition significant, p =
0.01407.
condition alone was not significant, p =
0.77162.
age_numeric was not significant, p =
0.63110.
sex was not significant, p = 0.52867.
trial_ordinal was not significant, p =
0.24753.
object_type:age_numeric was not significant, p
= 0.92553.
Overall, the frequency model suggests that object
type and the object type by condition
interaction are the strongest predictors of how many times
infants touched the stimuli.
Main research answer
The main research question was whether infant exploration differs
across 2D and 3D stimuli and which factors significantly predict
exploration.
Across the three outcomes, the most consistent finding is that the
effect of object type depends on condition. The
interaction between object_type and condition
was significant for:
- Touch duration: p = 0.002225
- Touch latency: p = 0.0112026
- Touch frequency: p = 0.01407 using the negative binomial
model
This suggests that infants’ exploration of 2D versus 3D stimuli is
not just different overall. Instead, the difference between 2D and 3D
stimuli changes depending on whether the trial was in the neutral or
negative condition.
Trial order also mattered for duration and latency. Infants showed
changes in how long they touched and how quickly they touched across
trials, which could reflect learning, fatigue, habituation, or
increasing familiarity with the task.
Age and sex were not significant predictors in these models. The
interaction between object type and age was also not significant,
suggesting that the 2D/3D difference did not meaningfully change across
the age range in this dataset.
Short conclusion for professor
A concise summary to bring to the professor:
I used mixed-effects models because each infant contributed multiple
trials and each item appeared repeatedly. I included random intercepts
for subject ID and item. The fixed effects were object type, condition,
age, sex, trial order, and the interactions between object type and
condition and between object type and age. Because socinf
and condition coded the same manipulation, I removed
socinf from the final models. Because
object_type was created from block, I removed
block from the final models as well. The main finding was
that the object type by condition interaction was significant across
duration, latency, and frequency. This suggests that infants’
exploration of 2D versus 3D stimuli depends on condition. Trial order
also significantly predicted duration and latency. Age and sex were not
significant predictors.
Questions/checks to discuss with professor
These are the main points to confirm before treating the analysis as
fully final:
- Confirm that
block = 2 should be coded as 2D and
block = 3 should be coded as 3D.
- Confirm that it is acceptable to treat the one negative duration
value as missing.
- Confirm whether the latency model should keep
(1 | item) even though the item variance was estimated as
0.
- Ask whether the professor wants follow-up estimated marginal means
using
emmeans to show the 2D vs. 3D difference separately
within each condition.
- Ask whether any additional control variables should be included,
such as experimenter, stimulus category, or top/bottom touch
region.
Optional follow-up: estimated marginal means
These commands are useful if the professor wants a clearer
interpretation of the significant object_type:condition
interaction.
# Estimated means for duration by object type within each condition.
emmeans(duration_model, pairwise ~ object_type | condition)
# Estimated means for latency by object type within each condition.
emmeans(latency_model, pairwise ~ object_type | condition)
# Estimated means for touch frequency by object type within each condition.
emmeans(frequency_model_nb, pairwise ~ object_type | condition, type = "response")