ERPs Pain Empathy 2023, stationary device, 2 versions

Recordings with BioSemi ActiveTwo, 64 channels

Author

Álvaro Rivera-Rei

Published

2025-05-23, Friday

Code
cat('\014')     # clean terminal
Code
rm(list = ls()) # clean workspace
library(tidyverse)
library(afex)
library(lmerTest)
library(emmeans)
library(easystats)
Code
my_dodge  <- .3
my_jitter <- .2

theme_set(theme_minimal())

a_posteriori_aov_ez <- function(aov_ez_object, sig_level = .05) {
  factors  <- as.list(rownames(aov_ez_object$anova_table))
  for (j in 1:length(factors)) {
    if (grepl(':', factors[[j]])) {
      factors[[j]] <- unlist(strsplit(factors[[j]], ':'))
    }
  }
  p_values <- aov_ez_object$anova_table$`Pr(>F)`
  for (i in 1:length(p_values)) {
    if (p_values[i] <= sig_level) {
      cat(rep('_', 60), '\n', sep = '')
      print(emmeans(aov_ez_object, factors[[i]], contr = 'pairwise'))
    }
  }
}

a_posteriori_lmer <- function(lmer_obj, sig_level = .05) {
  anova_lmer <- anova(lmer_obj)
  factors  <- as.list(row.names(anova_lmer))
  for (j in 1:length(factors)) {
    if (grepl(':', factors[[j]])) {
      factors[[j]] <- unlist(strsplit(factors[[j]], ':'))
    }
  }
  p_values <- anova_lmer$`Pr(>F)`
  for (i in 1:length(p_values)) {
    if (p_values[i] <= sig_level) {
      cat(rep('_', 60), '\n', sep = '')
      print(emmeans(lmer_obj, factors[[i]], contr = 'pairwise'))
    }
  }
}

xclude <- c(666)
Code
csv_answers <- list.files(path = '../csv', full.names = TRUE)
answers_df  <- vroom::vroom(csv_answers, col_types = c(Sex = 'c'), show_col_types = FALSE) |> 
  filter(Block > 0) |> 
  mutate(Block = factor(Block)) |> 
  filter(!is.na(Question)) |> 
  mutate(Sex = if_else(Sex == 'f', 'female', 'male')) |> 
  separate(Subject, c('ID', 'Version'), sep = '_', remove = FALSE, extra = 'drop') |> 
  mutate(Version  = tolower(Version),
         num_id   = parse_number(ID),
         Question = recode(Question, 'unpleasantness' = 'displeasing', 'pain' = 'painful'),
         Stimulus = case_match(Valence, 'EASE' ~ 'no_pain', 'PAIN' ~ 'pain')
         ) |> 
  mutate(Answer = if_else(Answer <  1,  1, Answer)) |> 
  mutate(Answer = if_else(num_id > 20, 1 + round((Answer-1)*96/144), Answer)) |> 
  mutate_if(is.character, as.factor) |> 
  relocate(Subject, .after = last_col()) |>
  filter(!(num_id %in% xclude))
write.csv(answers_df,  'data/painEmpathy_2023_answers_clean_2_versions_pilot_biosemi.csv',  row.names = FALSE)

erp_averages     <- list.files(path = './data/ave_volt_2_versions', full.names = TRUE)
painEmpathy_data <- vroom::vroom(erp_averages, show_col_types = FALSE) |> 
  separate(ERPset, c('ID', 'Version'), sep = '_', remove = FALSE) |> 
  rename(Component = mlabel,
         Amplitude = value,
         Stimulus  = binlabel,
         Electrode = chlabel) |> 
  mutate(worklat = gsub('.0', '', worklat, fixed = TRUE),
         num_id  = parse_number(ID),
         chindex = factor(chindex),
         bini    = factor(bini)) |> 
  left_join(unique(answers_df[c('num_id', 'Sex')]), by = 'num_id') |>  mutate_if(is.character, as.factor) |> 
  mutate_if(is.character, as.factor) |> 
  mutate(Component = factor(Component, levels = c('N1', 'N2', 'P1', 'P3', 'LPP')),
         Electrode = factor(Electrode, levels = c('FC1', 'Fz', 'FC2',
                                                  'CP1', 'Cz', 'CP2',
                                                  'O1' , 'Oz', 'O2')),
         ) |> 
  filter(!(num_id %in% xclude))
write.csv(painEmpathy_data,  file.path('data/painEmpathy_2024_data_clean_2_versions_pilot_biosemi.csv'),  row.names = FALSE)

Answers

Code
addmargins(xtabs(~ Version + Sex, data = unique(answers_df[c('Version', 'Sex', 'num_id')])), 2)
       Sex
Version female male Sum
     v1     19   11  30
     v2     19   11  30
Code
summary(answers_df)
       ID       Version       Sex       Block        trialN     
 pilot07: 121   v1:1425   female:1895   1:1453   Min.   : 1.00  
 pilot04: 106   v2:1495   male  :1025   2:1467   1st Qu.:16.00  
 pilot09: 106                                    Median :32.00  
 pilot30: 105                                    Mean   :31.85  
 pilot14: 104                                    3rd Qu.:47.00  
 pilot22: 104                                    Max.   :64.00  
 (Other):2274                                                   
      Image      Valence         Answer             Question          rT       
 hp-5    :  19   EASE:1434   Min.   : 1.00   displeasing:1479   Min.   :  267  
 10.1.jpg:  18   PAIN:1486   1st Qu.: 1.00   painful    :1441   1st Qu.: 3711  
 2.2.jpg :  18               Median :49.00                      Median : 4543  
 fp-28   :  18               Mean   :43.17                      Mean   : 4993  
 hp-27   :  18               3rd Qu.:77.00                      3rd Qu.: 5691  
 fnp-19  :  17               Max.   :97.00                      Max.   :94218  
 (Other) :2812                                                                 
    Session          num_id         Stimulus   
 Min.   :1.000   Min.   : 1.00   no_pain:1434  
 1st Qu.:1.000   1st Qu.: 8.00   pain   :1486  
 Median :1.000   Median :15.00                 
 Mean   :1.054   Mean   :15.55                 
 3rd Qu.:1.000   3rd Qu.:24.00                 
 Max.   :3.000   Max.   :31.00                 
                                               
                           Subject    
 pilot07_v1_2023-11-02_14-27-38:  62  
 pilot04_v2                    :  60  
 pilot01_v2                    :  59  
 pilot07_v2_2023-11-02_14-12-05:  59  
 pilot18_v2_2023-11-14_21-04-52:  57  
 pilot22_v2_2025-03-17_17-39-34:  56  
 (Other)                       :2567  

Pain rating:

Code
painrat_data <- subset(answers_df, Question == 'painful')
pain_rating_lmer <- lmer(Answer ~ Stimulus*Version + (Stimulus*Version|num_id) + (1|Image), painrat_data)
afex_plot(
  pain_rating_lmer,
  x     = 'Stimulus',
  trace = 'Version',
  id    = 'num_id',
  error_arg = list(width = .15),
  dodge     = my_dodge,
  data_arg  = list(
    position = 
      position_jitterdodge(
        jitter.width  = my_jitter, 
        jitter.height = 0, 
        dodge.width   = my_dodge  ## needs to be same as dodge
      )),
  mapping   = c('color'),
  point_arg = list(size = 4)
)
Figure 1: Pain rating by Version & Stimulus
Code
options(width = 120)
summary(pain_rating_lmer)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Answer ~ Stimulus * Version + (Stimulus * Version | num_id) +      (1 | Image)
   Data: painrat_data

REML criterion at convergence: 12385.8

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-4.6953 -0.4156 -0.0620  0.4121  4.3199 

Random effects:
 Groups   Name                   Variance Std.Dev. Corr             
 Image    (Intercept)             44.27    6.654                    
 num_id   (Intercept)            188.63   13.734                    
          Stimuluspain           350.60   18.724   -0.74            
          Versionv2               63.05    7.940   -0.74  0.51      
          Stimuluspain:Versionv2  79.01    8.889    0.41 -0.65 -0.75
 Residual                        252.29   15.884                    
Number of obs: 1441, groups:  Image, 312; num_id, 30

Fixed effects:
                       Estimate Std. Error     df t value Pr(>|t|)    
(Intercept)              12.251      2.793 36.391   4.386 9.47e-05 ***
Stimuluspain             63.960      3.832 35.526  16.692  < 2e-16 ***
Versionv2                -2.027      2.223 50.154  -0.912    0.366    
Stimuluspain:Versionv2    1.798      2.881 53.142   0.624    0.535    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) Stmlsp Vrsnv2
Stimuluspan -0.735              
Versionv2   -0.675  0.474       
Stmlspn:Vr2  0.397 -0.596 -0.721
Code
r2(pain_rating_lmer)
# R2 for Mixed Models

  Conditional R2: 0.829
     Marginal R2: 0.714
Code
icc(pain_rating_lmer)
# Intraclass Correlation Coefficient

    Adjusted ICC: 0.403
  Unadjusted ICC: 0.115
Code
ranova(pain_rating_lmer, reduce.terms = FALSE)
ANOVA-like table for random-effects: Single term deletions

Model:
Answer ~ Stimulus + Version + (Stimulus * Version | num_id) + (1 | Image) + Stimulus:Version
                              npar  logLik   AIC    LRT Df Pr(>Chisq)    
<none>                          16 -6192.9 12418                         
(Stimulus * Version | num_id)    6 -6393.2 12798 400.64 10  < 2.2e-16 ***
(1 | Image)                     15 -6216.8 12464  47.73  1  4.901e-12 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
anova(pain_rating_lmer)
Type III Analysis of Variance Table with Satterthwaite's method
                 Sum Sq Mean Sq NumDF  DenDF  F value Pr(>F)    
Stimulus         104323  104323     1 33.109 413.4998 <2e-16 ***
Version             134     134     1 48.809   0.5298 0.4702    
Stimulus:Version     98      98     1 53.142   0.3897 0.5351    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
interpret(omega_squared(pain_rating_lmer, alternative = 'two.sided'), rules = 'field2013')
# Effect Size for ANOVA (Type III)

Parameter        | Omega2 (partial) |       95% CI | Interpretation
-------------------------------------------------------------------
Stimulus         |             0.92 | [0.87, 0.95] |          large
Version          |             0.00 | [0.00, 0.00] |     very small
Stimulus:Version |             0.00 | [0.00, 0.00] |     very small

- Interpretation rule: field2013
Code
a_posteriori_lmer(pain_rating_lmer)
____________________________________________________________
NOTE: Results may be misleading due to involvement in interactions
$emmeans
 Stimulus emmean   SE   df lower.CL upper.CL
 no_pain    11.2 2.20 33.0     6.76     15.7
 pain       76.1 2.05 33.7    71.93     80.3

Results are averaged over the levels of: Version 
Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
 contrast       estimate   SE   df t.ratio p.value
 no_pain - pain    -64.9 3.19 32.9 -20.324  <.0001

Results are averaged over the levels of: Version 
Degrees-of-freedom method: kenward-roger 

Unpleasantness rating:

Code
unplsnt_data <- subset(answers_df, Question == 'displeasing')
unpleasantness_rating_lmer <- lmer(Answer ~ Stimulus*Version + (Stimulus*Version|num_id) + (1|Image), unplsnt_data)
afex_plot(
  unpleasantness_rating_lmer,
  x     = 'Stimulus',
  trace = 'Version',
  id    = 'num_id',
  error_arg = list(width = .15),
  dodge     = my_dodge,
  data_arg  = list(
    position = 
      position_jitterdodge(
        jitter.width  = my_jitter, 
        jitter.height = 0, 
        dodge.width   = my_dodge  ## needs to be same as dodge
      )),
  mapping   = c('color'),
  point_arg = list(size = 4)
)
Figure 2: Unpleasantness rating by Version & Stimulus
Code
options(width = 120)
summary(unpleasantness_rating_lmer)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Answer ~ Stimulus * Version + (Stimulus * Version | num_id) +      (1 | Image)
   Data: unplsnt_data

REML criterion at convergence: 12989.1

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-4.2924 -0.4956 -0.0421  0.4650  3.2978 

Random effects:
 Groups   Name                   Variance Std.Dev. Corr             
 Image    (Intercept)             82.64    9.091                    
 num_id   (Intercept)            185.44   13.618                    
          Stimuluspain           264.21   16.255   -0.67            
          Versionv2               47.85    6.918   -0.78  0.57      
          Stimuluspain:Versionv2  50.91    7.135    0.24 -0.47 -0.32
 Residual                        290.17   17.035                    
Number of obs: 1479, groups:  Image, 315; num_id, 30

Fixed effects:
                       Estimate Std. Error     df t value Pr(>|t|)    
(Intercept)              17.366      2.922 39.543   5.942 5.93e-07 ***
Stimuluspain             49.285      3.653 44.812  13.491  < 2e-16 ***
Versionv2                -4.929      2.421 68.830  -2.036   0.0456 *  
Stimuluspain:Versionv2    7.297      3.171 87.050   2.301   0.0238 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) Stmlsp Vrsnv2
Stimuluspan -0.686              
Versionv2   -0.677  0.507       
Stmlspn:Vr2  0.338 -0.549 -0.624
Code
r2(unpleasantness_rating_lmer)
# R2 for Mixed Models

  Conditional R2: 0.762
     Marginal R2: 0.580
Code
icc(unpleasantness_rating_lmer)
# Intraclass Correlation Coefficient

    Adjusted ICC: 0.433
  Unadjusted ICC: 0.182
Code
ranova(unpleasantness_rating_lmer, reduce.terms = FALSE)
ANOVA-like table for random-effects: Single term deletions

Model:
Answer ~ Stimulus + Version + (Stimulus * Version | num_id) + (1 | Image) + Stimulus:Version
                              npar  logLik   AIC    LRT Df Pr(>Chisq)    
<none>                          16 -6494.5 13021                         
(Stimulus * Version | num_id)    6 -6671.3 13355 353.50 10  < 2.2e-16 ***
(1 | Image)                     15 -6553.2 13136 117.33  1  < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
anova(unpleasantness_rating_lmer)
Type III Analysis of Variance Table with Satterthwaite's method
                 Sum Sq Mean Sq NumDF  DenDF  F value  Pr(>F)    
Stimulus          85574   85574     1 38.003 294.9039 < 2e-16 ***
Version             133     133     1 57.471   0.4570 0.50172    
Stimulus:Version   1537    1537     1 87.050   5.2963 0.02376 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
interpret(omega_squared(unpleasantness_rating_lmer, alternative = 'two.sided'), rules = 'field2013')
# Effect Size for ANOVA (Type III)

Parameter        | Omega2 (partial) |       95% CI | Interpretation
-------------------------------------------------------------------
Stimulus         |             0.88 | [0.80, 0.92] |          large
Version          |             0.00 | [0.00, 0.00] |     very small
Stimulus:Version |             0.05 | [0.00, 0.16] |          small

- Interpretation rule: field2013
Code
a_posteriori_lmer(unpleasantness_rating_lmer)
____________________________________________________________
NOTE: Results may be misleading due to involvement in interactions
$emmeans
 Stimulus emmean   SE   df lower.CL upper.CL
 no_pain    14.9 2.29 36.7     10.3     19.5
 pain       67.8 2.30 36.5     63.2     72.5

Results are averaged over the levels of: Version 
Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
 contrast       estimate   SE   df t.ratio p.value
 no_pain - pain    -52.9 3.08 37.5 -17.160  <.0001

Results are averaged over the levels of: Version 
Degrees-of-freedom method: kenward-roger 

____________________________________________________________
$emmeans
 Stimulus Version emmean   SE   df lower.CL upper.CL
 no_pain  v1        17.4 2.92 40.2    11.46     23.3
 pain     v1        66.7 2.69 42.3    61.22     72.1
 no_pain  v2        12.4 2.20 45.5     8.01     16.9
 pain     v2        69.0 2.55 40.4    63.86     74.2

Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
 contrast                estimate   SE   df t.ratio p.value
 no_pain v1 - pain v1      -49.28 3.66 44.1 -13.481  <.0001
 no_pain v1 - no_pain v2     4.93 2.43 70.0   2.031  0.1867
 no_pain v1 - pain v2      -51.65 4.00 39.6 -12.925  <.0001
 pain v1 - no_pain v2       54.21 3.20 47.1  16.925  <.0001
 pain v1 - pain v2          -2.37 2.52 64.4  -0.939  0.7841
 no_pain v2 - pain v2      -56.58 3.27 43.5 -17.280  <.0001

Degrees-of-freedom method: kenward-roger 
P value adjustment: tukey method for comparing a family of 4 estimates 

ERP plots

BDF files were pre-processed in Matlab using the EEGLAB 2023.1 toolbox (Delorme and Makeig 2004), the ERPLAB 10.0 toolbox (Lopez-Calderon and Luck 2014), and automated with in-house scripts. EEG data was high-pass filtered at 0.5 Hz with a 12 dB/oct roll-off. A working time window was selected from 2 seconds before the first Stimulus to 2 seconds after the last one. Defective channels were identified by eye inspection and omitted from the preprocessing steps. Artifacts originating from eye blinks or movements, heart beats, muscle contraction, channel noise, or electrical interference were identified and removed by means of independent Component analysis (ICA) and using the ICLabel 1.4 classifier (Pion-Tonachini, Kreutz-Delgado, and Makeig 2019), Components with an score between 0.8 and 1 in the aforementioned artifactual categories were removed. At this point defective channels were spherically interpolated. Data was re-referenced to infinity with the REST 1.2 toolbox (Dong et al. 2017), low-pass filtered at 35 Hz with a 12 dB/oct roll-off, cut in [-200ms 1000ms] epochs around stimuli, and baseline-corrected relative to the mean voltage in the pre-Stimulus time.

Topographic layout:

(a) Topography V1
(b) Topography V2
Figure 3: Topographic Maps

ERPs General description

Code
options(width = 90)
ggplot(
  painEmpathy_data, aes(x = Amplitude, fill = Component, color = Component)) +
  geom_histogram(alpha = .4) +
  facet_wrap(~Component, ncol = 1) +
  theme(strip.text.x = element_blank())
addmargins(xtabs(~ Version + Sex, data = unique(painEmpathy_data[c('Version', 'Sex', 'num_id')])), 2)
       Sex
Version female male Sum
     v1     19   11  30
     v2     19   11  30
Code
summary(painEmpathy_data)
       worklat    Component   Amplitude           chindex      Electrode   bini   
 [140  170]:360   N1 :360   Min.   :-14.9196   11     :240   FC1    :240   1:900  
 [150  180]:360   N2 :360   1st Qu.: -2.4596   27     :240   Fz     :240   2:900  
 [270  330]:360   P1 :360   Median :  1.0775   29     :240   FC2    :240          
 [280  380]:360   P3 :360   Mean   :  0.6984   38     :240   O1     :240          
 [600  800]:360   LPP:360   3rd Qu.:  3.3000   46     :240   Oz     :240          
                            Max.   : 15.9852   64     :240   O2     :240          
                                               (Other):360   (Other):360          
    Stimulus          ERPset           ID       Version      num_id          Sex      
 no_pain:900   pilot01_v1:  30   pilot01:  60   v1:900   Min.   : 1.00   female:1140  
 pain   :900   pilot01_v2:  30   pilot02:  60   v2:900   1st Qu.: 8.00   male  : 660  
               pilot02_v1:  30   pilot03:  60            Median :15.50                
               pilot02_v2:  30   pilot04:  60            Mean   :15.77                
               pilot03_v1:  30   pilot05:  60            3rd Qu.:24.00                
               pilot03_v2:  30   pilot06:  60            Max.   :31.00                
               (Other)   :1620   (Other):1440                                         
Code
n1_data  <- subset(painEmpathy_data, Component == 'N1',)
n2_data  <- subset(painEmpathy_data, Component == 'N2',)
p1_data  <- subset(painEmpathy_data, Component == 'P1',)
p3_data  <- subset(painEmpathy_data, Component == 'P3',)
lpp_data <- subset(painEmpathy_data, Component == 'LPP',)
Figure 4: N1, N2, P1, P3 & LPP voltage distributions

In the front: N1 & N2:

(a) fERPs V1
(b) fERPs V2
Figure 5: Early Frontal ROI

N1, average from [150 180] ms interval

Electrodes FC1, Fz, FC2

Figure 6: N1 measurement window
Code
painEmpathy_n1_lmer <- lmer(Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) + (1 | num_id : Electrode), n1_data)
afex_plot(
  painEmpathy_n1_lmer,
  x     = 'Stimulus',
  trace = 'Version',
  id    = 'num_id',
  error_arg = list(width = .25),
  dodge     = my_dodge,
  data_arg  = list(
    position = 
      position_jitterdodge(
        jitter.width  = my_jitter, 
        jitter.height = 0, 
        dodge.width   = my_dodge  ## needs to be same as dodge
      )),
  mapping   = c('color'),
  point_arg = list(size = 3)
)
Figure 7: N1 means by Version & Stimulus
Code
options(width = 120)
summary(painEmpathy_n1_lmer)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) +      (1 | num_id:Electrode)
   Data: n1_data

REML criterion at convergence: 685.8

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.0512 -0.4869  0.0043  0.5047  2.0954 

Random effects:
 Groups           Name                   Variance Std.Dev. Corr             
 num_id:Electrode (Intercept)            0.13664  0.3696                    
 num_id           (Intercept)            3.70535  1.9249                    
                  Stimuluspain           0.50392  0.7099   -0.45            
                  Versionv2              1.24335  1.1151   -0.67  0.50      
                  Stimuluspain:Versionv2 1.39140  1.1796    0.55 -0.80 -0.56
 Residual                                0.09341  0.3056                    
Number of obs: 360, groups:  num_id:Electrode, 90; num_id, 30

Fixed effects:
                       Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)            -2.86201    0.35506 28.99052  -8.061 6.89e-09 ***
Stimuluspain           -0.05899    0.13738 28.99902  -0.429    0.671    
Versionv2               0.18241    0.20862 28.99682   0.874    0.389    
Stimuluspain:Versionv2 -0.15562    0.22479 28.99804  -0.692    0.494    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) Stmlsp Vrsnv2
Stimuluspan -0.446              
Versionv2   -0.657  0.501       
Stmlspn:Vr2  0.536 -0.788 -0.570
Code
r2(painEmpathy_n1_lmer)
# R2 for Mixed Models

  Conditional R2: 0.971
     Marginal R2: 0.003
Code
icc(painEmpathy_n1_lmer)
# Intraclass Correlation Coefficient

    Adjusted ICC: 0.971
  Unadjusted ICC: 0.968
Code
ranova(painEmpathy_n1_lmer, reduce.terms = FALSE)
ANOVA-like table for random-effects: Single term deletions

Model:
Amplitude ~ Stimulus + Version + (Stimulus * Version | num_id) + (1 | num_id:Electrode) + Stimulus:Version
                              npar  logLik     AIC    LRT Df Pr(>Chisq)    
<none>                          16 -342.89  717.77                         
(Stimulus * Version | num_id)    6 -539.65 1091.29 393.52 10  < 2.2e-16 ***
(1 | num_id:Electrode)          15 -393.31  816.62 100.84  1  < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
anova(painEmpathy_n1_lmer)
Type III Analysis of Variance Table with Satterthwaite's method
                   Sum Sq  Mean Sq NumDF  DenDF F value Pr(>F)
Stimulus         0.244214 0.244214     1 28.999  2.6145 0.1167
Version          0.034714 0.034714     1 28.998  0.3716 0.5469
Stimulus:Version 0.044769 0.044769     1 28.998  0.4793 0.4943
Code
interpret(omega_squared(painEmpathy_n1_lmer, alternative = 'two.sided'), rules = 'field2013')
# Effect Size for ANOVA (Type III)

Parameter        | Omega2 (partial) |       95% CI | Interpretation
-------------------------------------------------------------------
Stimulus         |             0.05 | [0.00, 0.26] |          small
Version          |             0.00 | [0.00, 0.00] |     very small
Stimulus:Version |             0.00 | [0.00, 0.00] |     very small

- Interpretation rule: field2013
Code
a_posteriori_lmer(painEmpathy_n1_lmer)

N1 model check

Code
check_model(painEmpathy_n1_lmer)
Figure 8: N1 ANOVA assumptions

N2, average from [270 330] ms interval

Electrodes FC1, Fz, FC2

Figure 9: N2 measurement window
Code
painEmpathy_n2_lmer <- lmer(Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) + (1 | num_id : Electrode), n2_data)
afex_plot(
  painEmpathy_n2_lmer,
  x     = 'Stimulus',
  trace = 'Version',
  id    = 'num_id',
  error_arg = list(width = .25),
  dodge     = my_dodge,
  data_arg  = list(
    position = 
      position_jitterdodge(
        jitter.width  = my_jitter, 
        jitter.height = 0, 
        dodge.width   = my_dodge  ## needs to be same as dodge
      )),
  mapping   = c('color'),
  point_arg = list(size = 3)
)
Figure 10: N2 means by Version & Stimulus
Code
options(width = 120)
summary(painEmpathy_n2_lmer)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) +      (1 | num_id:Electrode)
   Data: n2_data

REML criterion at convergence: 795.1

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.39271 -0.48281  0.02937  0.44161  2.27512 

Random effects:
 Groups           Name                   Variance Std.Dev. Corr             
 num_id:Electrode (Intercept)            0.57658  0.7593                    
 num_id           (Intercept)            6.16661  2.4833                    
                  Stimuluspain           0.68295  0.8264   -0.36            
                  Versionv2              0.98177  0.9908   -0.37  0.38      
                  Stimuluspain:Versionv2 1.17877  1.0857    0.31 -0.76 -0.52
 Residual                                0.09321  0.3053                    
Number of obs: 360, groups:  num_id:Electrode, 90; num_id, 30

Fixed effects:
                       Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)            -4.42244    0.46151 28.99883  -9.582 1.72e-10 ***
Stimuluspain           -0.05740    0.15760 28.99784  -0.364    0.718    
Versionv2               1.41284    0.18654 28.99570   7.574 2.38e-08 ***
Stimuluspain:Versionv2 -0.08916    0.20841 28.99689  -0.428    0.672    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) Stmlsp Vrsnv2
Stimuluspan -0.357              
Versionv2   -0.365  0.390       
Stmlspn:Vr2  0.299 -0.753 -0.534
Code
r2(painEmpathy_n2_lmer)
# R2 for Mixed Models

  Conditional R2: 0.986
     Marginal R2: 0.070
Code
icc(painEmpathy_n2_lmer)
# Intraclass Correlation Coefficient

    Adjusted ICC: 0.985
  Unadjusted ICC: 0.916
Code
ranova(painEmpathy_n2_lmer, reduce.terms = FALSE)
ANOVA-like table for random-effects: Single term deletions

Model:
Amplitude ~ Stimulus + Version + (Stimulus * Version | num_id) + (1 | num_id:Electrode) + Stimulus:Version
                              npar  logLik     AIC    LRT Df Pr(>Chisq)    
<none>                          16 -397.57  827.14                         
(Stimulus * Version | num_id)    6 -566.16 1144.33 337.18 10  < 2.2e-16 ***
(1 | num_id:Electrode)          15 -536.78 1103.55 278.41  1  < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
anova(painEmpathy_n2_lmer)
Type III Analysis of Variance Table with Satterthwaite's method
                 Sum Sq Mean Sq NumDF  DenDF F value    Pr(>F)    
Stimulus         0.0884  0.0884     1 29.000  0.9486    0.3381    
Version          7.0118  7.0118     1 28.997 75.2238 1.504e-09 ***
Stimulus:Version 0.0171  0.0171     1 28.997  0.1830    0.6720    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
interpret(omega_squared(painEmpathy_n2_lmer, alternative = 'two.sided'), rules = 'field2013')
# Effect Size for ANOVA (Type III)

Parameter        | Omega2 (partial) |       95% CI | Interpretation
-------------------------------------------------------------------
Stimulus         |             0.00 | [0.00, 0.00] |     very small
Version          |             0.71 | [0.50, 0.81] |          large
Stimulus:Version |             0.00 | [0.00, 0.00] |     very small

- Interpretation rule: field2013
Code
a_posteriori_lmer(painEmpathy_n2_lmer)
____________________________________________________________
NOTE: Results may be misleading due to involvement in interactions
$emmeans
 Version emmean    SE df lower.CL upper.CL
 v1       -4.45 0.440 29    -5.35    -3.55
 v2       -3.08 0.428 29    -3.96    -2.21

Results are averaged over the levels of: Stimulus 
Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
 contrast estimate    SE df t.ratio p.value
 v1 - v2     -1.37 0.158 29  -8.673  <.0001

Results are averaged over the levels of: Stimulus 
Degrees-of-freedom method: kenward-roger 

N2 model check

Code
check_model(painEmpathy_n2_lmer)
Figure 11: N2 ANOVA assumptions

In the back: P1 & P3:

(a) ERPs V1
(b) ERPs V2
Figure 12: Early Occipital ROI

P1, average [140 170] ms interval

Electrodes O1, Oz, O2

Figure 13: P1 measurement window
Code
painEmpathy_p1_lmer <- lmer(Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) + (1 | num_id : Electrode), p1_data)
afex_plot(
  painEmpathy_p1_lmer,
  x     = 'Stimulus',
  trace = 'Version',
  id    = 'num_id',
  error_arg = list(width = .25),
  dodge     = my_dodge,
  data_arg  = list(
    position = 
      position_jitterdodge(
        jitter.width  = my_jitter, 
        jitter.height = 0, 
        dodge.width   = my_dodge  ## needs to be same as dodge
      )),
  mapping   = c('color'),
  point_arg = list(size = 3)
)
Figure 14: P1 means by Version & Stimulus
Code
options(width = 120)
summary(painEmpathy_p1_lmer)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) +      (1 | num_id:Electrode)
   Data: p1_data

REML criterion at convergence: 1064.1

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.5676 -0.3373  0.0015  0.3524  3.3907 

Random effects:
 Groups           Name                   Variance Std.Dev. Corr             
 num_id:Electrode (Intercept)             1.3857  1.1772                    
 num_id           (Intercept)            13.7168  3.7036                    
                  Stimuluspain            0.7017  0.8377    0.08            
                  Versionv2               1.5938  1.2625   -0.57 -0.04      
                  Stimuluspain:Versionv2  1.1538  1.0742    0.05 -0.78 -0.20
 Residual                                 0.2414  0.4914                    
Number of obs: 360, groups:  num_id:Electrode, 90; num_id, 30

Fixed effects:
                       Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)             3.56105    0.68942 28.99822   5.165  1.6e-05 ***
Stimuluspain           -0.10485    0.16958 29.00117  -0.618    0.541    
Versionv2              -0.06164    0.24185 28.99996  -0.255    0.801    
Stimuluspain:Versionv2  0.21698    0.22179 28.99990   0.978    0.336    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) Stmlsp Vrsnv2
Stimuluspan  0.044              
Versionv2   -0.552  0.030       
Stmlspn:Vr2  0.062 -0.768 -0.271
Code
r2(painEmpathy_p1_lmer)
# R2 for Mixed Models

  Conditional R2: 0.983
     Marginal R2: 0.000
Code
icc(painEmpathy_p1_lmer)
# Intraclass Correlation Coefficient

    Adjusted ICC: 0.983
  Unadjusted ICC: 0.982
Code
ranova(painEmpathy_p1_lmer, reduce.terms = FALSE)
boundary (singular) fit: see help('isSingular')
ANOVA-like table for random-effects: Single term deletions

Model:
Amplitude ~ Stimulus + Version + (Stimulus * Version | num_id) + (1 | num_id:Electrode) + Stimulus:Version
                              npar  logLik    AIC    LRT Df Pr(>Chisq)    
<none>                          16 -532.03 1096.1                         
(Stimulus * Version | num_id)    6 -683.12 1378.2 302.17 10  < 2.2e-16 ***
(1 | num_id:Electrode)          15 -668.42 1366.8 272.77  1  < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
anova(painEmpathy_p1_lmer)
Type III Analysis of Variance Table with Satterthwaite's method
                   Sum Sq  Mean Sq NumDF  DenDF F value Pr(>F)
Stimulus         0.000263 0.000263     1 29.002  0.0011 0.9739
Version          0.009426 0.009426     1 29.003  0.0390 0.8448
Stimulus:Version 0.231085 0.231085     1 29.000  0.9571 0.3360
Code
interpret(omega_squared(painEmpathy_p1_lmer, alternative = 'two.sided'), rules = 'field2013')
# Effect Size for ANOVA (Type III)

Parameter        | Omega2 (partial) |       95% CI | Interpretation
-------------------------------------------------------------------
Stimulus         |             0.00 | [0.00, 0.00] |     very small
Version          |             0.00 | [0.00, 0.00] |     very small
Stimulus:Version |             0.00 | [0.00, 0.00] |     very small

- Interpretation rule: field2013
Code
a_posteriori_lmer(painEmpathy_p1_lmer)

P1 model check

Code
check_model(painEmpathy_p1_lmer)
Figure 15: P1 ANOVA assumptions

P3, average from [280 380] ms interval

Electrodes O1, Oz, O2

Figure 16: P3 measurement window
Code
painEmpathy_p3_lmer <- lmer(Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) + (1 | num_id : Electrode), p3_data)
afex_plot(
  painEmpathy_p3_lmer,
  x     = 'Stimulus',
  trace = 'Version',
  id    = 'num_id',
  error_arg = list(width = .25),
  dodge     = my_dodge,
  data_arg  = list(
    position = 
      position_jitterdodge(
        jitter.width  = my_jitter, 
        jitter.height = 0, 
        dodge.width   = my_dodge  ## needs to be same as dodge
      )),
  mapping   = c('color'),
  point_arg = list(size = 3)
)
Figure 17: P3 means by Version & Stimulus
Code
options(width = 120)
summary(painEmpathy_p3_lmer)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) +      (1 | num_id:Electrode)
   Data: p3_data

REML criterion at convergence: 854.4

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.93599 -0.36962 -0.02765  0.37979  2.27960 

Random effects:
 Groups           Name                   Variance Std.Dev. Corr             
 num_id:Electrode (Intercept)             0.7103  0.8428                    
 num_id           (Intercept)            10.9062  3.3025                    
                  Stimuluspain            0.7202  0.8486   -0.28            
                  Versionv2               0.6248  0.7904   -0.39  0.35      
                  Stimuluspain:Versionv2  1.1681  1.0808    0.10 -0.67 -0.33
 Residual                                 0.1094  0.3308                    
Number of obs: 360, groups:  num_id:Electrode, 90; num_id, 30

Fixed effects:
                       Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)             5.68487    0.61045 28.99177   9.313 3.25e-10 ***
Stimuluspain           -0.53754    0.16260 28.99728  -3.306  0.00253 ** 
Versionv2              -0.96415    0.15251 28.99671  -6.322 6.61e-07 ***
Stimuluspain:Versionv2 -0.09064    0.20929 28.99796  -0.433  0.66816    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) Stmlsp Vrsnv2
Stimuluspan -0.273              
Versionv2   -0.373  0.365       
Stmlspn:Vr2  0.102 -0.675 -0.367
Code
r2(painEmpathy_p3_lmer)
# R2 for Mixed Models

  Conditional R2: 0.990
     Marginal R2: 0.031
Code
icc(painEmpathy_p3_lmer)
# Intraclass Correlation Coefficient

    Adjusted ICC: 0.990
  Unadjusted ICC: 0.959
Code
ranova(painEmpathy_p3_lmer, reduce.terms = FALSE)
ANOVA-like table for random-effects: Single term deletions

Model:
Amplitude ~ Stimulus + Version + (Stimulus * Version | num_id) + (1 | num_id:Electrode) + Stimulus:Version
                              npar  logLik     AIC    LRT Df Pr(>Chisq)    
<none>                          16 -427.22  886.43                         
(Stimulus * Version | num_id)    6 -596.97 1205.94 339.50 10  < 2.2e-16 ***
(1 | num_id:Electrode)          15 -570.04 1170.09 285.65  1  < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
anova(painEmpathy_p3_lmer)
Type III Analysis of Variance Table with Satterthwaite's method
                 Sum Sq Mean Sq NumDF  DenDF F value    Pr(>F)    
Stimulus         2.5808  2.5808     1 29.000 23.5822 3.783e-05 ***
Version          4.9583  4.9583     1 28.998 45.3064 2.192e-07 ***
Stimulus:Version 0.0205  0.0205     1 28.998  0.1876    0.6682    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
interpret(omega_squared(painEmpathy_p3_lmer, alternative = 'two.sided'), rules = 'field2013')
# Effect Size for ANOVA (Type III)

Parameter        | Omega2 (partial) |       95% CI | Interpretation
-------------------------------------------------------------------
Stimulus         |             0.42 | [0.15, 0.62] |          large
Version          |             0.59 | [0.34, 0.73] |          large
Stimulus:Version |             0.00 | [0.00, 0.00] |     very small

- Interpretation rule: field2013
Code
a_posteriori_lmer(painEmpathy_p3_lmer)
____________________________________________________________
NOTE: Results may be misleading due to involvement in interactions
$emmeans
 Stimulus emmean    SE df lower.CL upper.CL
 no_pain    5.20 0.586 29     4.00     6.40
 pain       4.62 0.566 29     3.46     5.78

Results are averaged over the levels of: Version 
Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
 contrast       estimate   SE df t.ratio p.value
 no_pain - pain    0.583 0.12 29   4.856  <.0001

Results are averaged over the levels of: Version 
Degrees-of-freedom method: kenward-roger 

____________________________________________________________
NOTE: Results may be misleading due to involvement in interactions
$emmeans
 Version emmean    SE df lower.CL upper.CL
 v1        5.42 0.593 29     4.20     6.63
 v2        4.41 0.562 29     3.26     5.56

Results are averaged over the levels of: Stimulus 
Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
 contrast estimate   SE df t.ratio p.value
 v1 - v2      1.01 0.15 29   6.731  <.0001

Results are averaged over the levels of: Stimulus 
Degrees-of-freedom method: kenward-roger 

P3 model check

Code
check_model(painEmpathy_p3_lmer)
Figure 18: P3 ANOVA assumptions

Late Centro-parietal: LPP

(a) pERPs V1
(b) pERPs V2
Figure 19: Late Centro-parietal ROI

LPP, average from [600 800] ms interval

Electrodes CP1, Cz, CP2

Figure 20: LPP measurement window
Code
painEmpathy_lpp_lmer <- lmer(Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) + (1 | num_id : Electrode), lpp_data)
afex_plot(
  painEmpathy_lpp_lmer,
  x     = 'Stimulus',
  trace = 'Version',
  id    = 'num_id',
  error_arg = list(width = .25),
  dodge     = my_dodge,
  data_arg  = list(
    position = 
      position_jitterdodge(
        jitter.width  = my_jitter, 
        jitter.height = 0, 
        dodge.width   = my_dodge  ## needs to be same as dodge
      )),
  mapping   = c('color'),
  point_arg = list(size = 3)
)
Figure 21: LPP means by Version & Stimulus
Code
options(width = 120)
summary(painEmpathy_lpp_lmer)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Amplitude ~ Stimulus * Version + (Stimulus * Version | num_id) +      (1 | num_id:Electrode)
   Data: lpp_data

REML criterion at convergence: 545.7

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.39188 -0.50031  0.01664  0.46119  2.06278 

Random effects:
 Groups           Name                   Variance Std.Dev. Corr             
 num_id:Electrode (Intercept)            0.19443  0.4409                    
 num_id           (Intercept)            0.72566  0.8519                    
                  Stimuluspain           0.30631  0.5535   -0.20            
                  Versionv2              0.34942  0.5911   -0.49  0.32      
                  Stimuluspain:Versionv2 0.43915  0.6627    0.43 -0.50 -0.39
 Residual                                0.06501  0.2550                    
Number of obs: 360, groups:  num_id:Electrode, 90; num_id, 30

Fixed effects:
                       Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)             1.34474    0.16453 29.00090   8.173 5.18e-09 ***
Stimuluspain            0.59257    0.10796 28.99945   5.489 6.53e-06 ***
Versionv2              -0.08897    0.11442 29.00154  -0.778   0.4431    
Stimuluspain:Versionv2  0.23278    0.13239 29.00272   1.758   0.0893 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) Stmlsp Vrsnv2
Stimuluspan -0.214              
Versionv2   -0.479  0.344       
Stmlspn:Vr2  0.404 -0.527 -0.427
Code
r2(painEmpathy_lpp_lmer)
# R2 for Mixed Models

  Conditional R2: 0.947
     Marginal R2: 0.106
Code
icc(painEmpathy_lpp_lmer)
# Intraclass Correlation Coefficient

    Adjusted ICC: 0.940
  Unadjusted ICC: 0.840
Code
ranova(painEmpathy_lpp_lmer, reduce.terms = FALSE)
ANOVA-like table for random-effects: Single term deletions

Model:
Amplitude ~ Stimulus + Version + (Stimulus * Version | num_id) + (1 | num_id:Electrode) + Stimulus:Version
                              npar  logLik    AIC    LRT Df Pr(>Chisq)    
<none>                          16 -272.83 577.65                         
(Stimulus * Version | num_id)    6 -397.97 807.93 250.28 10  < 2.2e-16 ***
(1 | num_id:Electrode)          15 -362.05 754.09 178.44  1  < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
anova(painEmpathy_lpp_lmer)
Type III Analysis of Variance Table with Satterthwaite's method
                 Sum Sq Mean Sq NumDF  DenDF F value    Pr(>F)    
Stimulus         3.8450  3.8450     1 28.997 59.1477 1.764e-08 ***
Version          0.0044  0.0044     1 29.000  0.0684   0.79560    
Stimulus:Version 0.2010  0.2010     1 29.003  3.0914   0.08926 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Code
interpret(omega_squared(painEmpathy_lpp_lmer, alternative = 'two.sided'), rules = 'field2013')
# Effect Size for ANOVA (Type III)

Parameter        | Omega2 (partial) |       95% CI | Interpretation
-------------------------------------------------------------------
Stimulus         |             0.65 | [0.42, 0.78] |          large
Version          |             0.00 | [0.00, 0.00] |     very small
Stimulus:Version |             0.06 | [0.00, 0.28] |         medium

- Interpretation rule: field2013
Code
a_posteriori_lmer(painEmpathy_lpp_lmer)
____________________________________________________________
NOTE: Results may be misleading due to involvement in interactions
$emmeans
 Stimulus emmean    SE df lower.CL upper.CL
 no_pain    1.30 0.146 29     1.00     1.60
 pain       2.01 0.179 29     1.64     2.38

Results are averaged over the levels of: Version 
Degrees-of-freedom method: kenward-roger 
Confidence level used: 0.95 

$contrasts
 contrast       estimate     SE df t.ratio p.value
 no_pain - pain   -0.709 0.0922 29  -7.691  <.0001

Results are averaged over the levels of: Version 
Degrees-of-freedom method: kenward-roger 

LPP model check

Code
check_model(painEmpathy_lpp_lmer)
Figure 22: LPP ANOVA assumptions

Factorial Mass Univariate analysis (FMUT, cluster mass)

Fields and Kuperberg (2020)

max_dist value of 50 corresponds to an approximate distance of 5.24 cm (assuming
a 56 cm great circle circumference head and that your electrode coordinates are
based on an idealized spherical head with radius of 85.000000).

Min/Max distances between all pairs of channels (in chanlocs units):
26.560450/169.891840

Median (semi-IQR) distance between all pairs of channels (in chanlocs units):
119.172654 (30.583399)

Mean (SD) # of neighbors per channel: 2.6 (1.2)
Median (semi-IQR) # of neighbors per channel: 2.0 (1.0)
Min/max # of neighbors per channel: 0 to 4

Effects over time

(a) Stimulus by Version interaction
(b) Stimulus by Version interaction with MASS
(c) Stimulus effect
(d) Stimulus effect with MASS
(e) Version effect
(f) Version effect with MASS
Figure 23: Full time window FMUT rasters
painEmpathy_fmut_2_versions_pilot_biosemi:

1 significant StimulusXVersion cluster(s) out of 27
cluster 1 F-masss: 813
cluster 1 p-value: 0.0132

3 significant Stimulus cluster(s) out of 26
cluster 1 F-masss: 2445
cluster 1 p-value: 0.0065
cluster 2 F-masss: 13142
cluster 2 p-value: 0.0001
cluster 3 F-masss: 1228
cluster 3 p-value: 0.0261

3 significant Version cluster(s) out of 22
cluster 1 F-masss: 12389
cluster 1 p-value: 0.0001
cluster 2 F-masss: 3356
cluster 2 p-value: 0.0007
cluster 3 F-masss: 2330
cluster 3 p-value: 0.0021


Mass Univariate analysis (cluster-mass), full time window

max_dist value of 50 corresponds to an approximate distance of 5.24 cm (assuming
a 56 cm great circle circumference head and that your electrode coordinates are
based on an idealized spherical head with radius of 85.000000).

Min/Max distances between all pairs of channels (in chanlocs units):
25.654041/169.962716

Median (semi-IQR) distance between all pairs of channels (in chanlocs units):
113.111431 (33.320704)

Mean (SD) # of neighbors per channel: 6.5 (1.5)
Median (semi-IQR) # of neighbors per channel: 7.0 (1.5)
Min/max # of neighbors per channel: 3 to 8

Groppe, Urbach, and Kutas (2011)

(a) Raster V1
(b) Raster V2
Figure 24: Full time window rasters
painEmpathy_v1_mass_pilot_biosemi:

1 significant positive cluster(s) out of 3
cluster 1 t-masss: 1883
cluster 1 p-value: 0.0000

1 significant negative cluster(s) out of 24
cluster 1 t-masss: -514
cluster 1 p-value: 0.0092


painEmpathy_v2_mass_pilot_biosemi:

1 significant positive cluster(s) out of 10
cluster 1 t-masss: 2225
cluster 1 p-value: 0.0000

1 significant negative cluster(s) out of 20
cluster 1 t-masss: -358
cluster 1 p-value: 0.0236


Multivariate pattern analysis (decoding)

No processing besides a 0.1 Hz high-pass filter (12 dB/oct roll-off) and reference to infinity (Dong et al. 2017).

Using 13 central electrodes shared between BioSemi ActiveTwo and Emotiv Epoc Flex devices:

  • F3, Fz, F4
  • FC1, FC2
  • C3, Cz, C4
  • CP1 ,CP2
  • P3, Pz, P4

Done in the ADAM 1.14 toolbox (Fahrenfort 2020) with FieldTrip 20211209 (Oostenveld et al. 2011).

Exemplar ERPs on Pz

(a) V1 ERPs
(b) V2 ERPs
Figure 25: ERPs for each type of stimulus

Decoding over time

Figure 26: Area Under the Curve over time

Decoding difference

Figure 27: Decoding difference between versions

Temporal generalization plot

Figure 28: Temporal Decoding Generalization for both versions

Activation pattern

Figure 29: Activation Pattern on a time window

Temporal generalization over time

Figure 30: Temporal generalization over time, training over the same time window as in Figure 29

Individual results

(a) V1 decoding
(b) V2 decoding
Figure 31: Decoding by subject

References

Delorme, Arnaud, and Scott Makeig. 2004. “EEGLAB: An Open Source Toolbox for Analysis of Single-Trial EEG Dynamics Including Independent Component Analysis.” Journal of Neuroscience Methods 134 (March): 9–21. https://doi.org/10.1016/J.JNEUMETH.2003.10.009.
Dong, Li, Fali Li, Qiang Liu, Xin Wen, Yongxiu Lai, Peng Xu, and Dezhong Yao. 2017. “MATLAB Toolboxes for Reference Electrode Standardization Technique (REST) of Scalp EEG.” Frontiers in Neuroscience 11 (October): 601. https://doi.org/10.3389/fnins.2017.00601.
Fahrenfort, Johannes Jacobus. 2020. “Multivariate Methods to Track the Spatiotemporal Profile of Feature-Based Attentional Selection Using EEG.” Neuromethods 151: 129–56. https://doi.org/10.1007/7657_2019_26/COVER.
Fields, Eric C., and Gina R. Kuperberg. 2020. “Having Your Cake and Eating It Too: Flexibility and Power with Mass Univariate Statistics for ERP Data.” Psychophysiology 57 (February): e13468. https://doi.org/10.1111/PSYP.13468.
Groppe, David M., Thomas P. Urbach, and Marta Kutas. 2011. “Mass Univariate Analysis of Event-Related Brain Potentials/Fields i: A Critical Tutorial Review.” Psychophysiology 48 (December): 1711–25. https://doi.org/10.1111/J.1469-8986.2011.01273.X.
Lopez-Calderon, Javier, and Steven J. Luck. 2014. “ERPLAB: An Open-Source Toolbox for the Analysis of Event-Related Potentials.” Frontiers in Human Neuroscience 8 (April): 75729. https://doi.org/10.3389/FNHUM.2014.00213/BIBTEX.
Oostenveld, Robert, Pascal Fries, Eric Maris, and Jan Mathijs Schoffelen. 2011. “FieldTrip: Open Source Software for Advanced Analysis of MEG, EEG, and Invasive Electrophysiological Data.” Computational Intelligence and Neuroscience 2011. https://doi.org/10.1155/2011/156869.
Pion-Tonachini, Luca, Ken Kreutz-Delgado, and Scott Makeig. 2019. “ICLabel: An Automated Electroencephalographic Independent Component Classifier, Dataset, and Website.” NeuroImage 198: 181–97. https://doi.org/10.1016/j.neuroimage.2019.05.026.