# 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:

  1. Touch duration: how long the infant touched the stimulus.
  2. Touch latency: how quickly the infant first touched the stimulus.
  3. Touch frequency: how many times the infant touched the stimulus.

The main independent variables are:

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:

The random effects control for natural variation due to repeated measurements:

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:

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:

  1. Confirm that block = 2 should be coded as 2D and block = 3 should be coded as 3D.
  2. Confirm that it is acceptable to treat the one negative duration value as missing.
  3. Confirm whether the latency model should keep (1 | item) even though the item variance was estimated as 0.
  4. Ask whether the professor wants follow-up estimated marginal means using emmeans to show the 2D vs. 3D difference separately within each condition.
  5. 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")