Données

Chargement des packages nécessaires et définition du répertoire

library(DataExplorer)
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ readr     2.1.5
## ✔ ggplot2   3.5.1     ✔ stringr   1.5.1
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(survival)
library(ggplot2)
library(survminer)
## Loading required package: ggpubr
## 
## Attaching package: 'survminer'
## 
## The following object is masked from 'package:survival':
## 
##     myeloma
library(gtsummary)
library(broom)
library(knitr)
library(GGally)
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
library(readxl)
library(lme4)
## Loading required package: Matrix
## 
## Attaching package: 'Matrix'
## 
## The following objects are masked from 'package:tidyr':
## 
##     expand, pack, unpack
library(cards)
library(cardx)
library(broom)

setwd(dir = "/Users/bellier_pro/Dropbox/Medecine/Anatomie/Projet_pedagogique/ECOS_VR/") # Define the directory


library(readxl)
ecos_vr <- read_excel("ecos_vr.xlsx") # Open the file

ecos_vr <- ecos_vr[,-1:-2]
ecos_vr <- ecos_vr[,-10]
ecos_vr$note_station <- as.numeric(ecos_vr$note_station)

Analyses statistiques

Difference-in-differences approach (ITT)

ecos_vr %>%
  tbl_summary(
    by = groupe,
    statistic = list(
      all_continuous() ~ "{mean} ({sd})",
      all_categorical() ~ "{n} ({p}%)"
    ),
    digits = all_continuous() ~ 1,
    missing_text = "(Données manquantes)"
  ) %>%
  add_p(pvalue_fun = ~style_pvalue(.x, digits = 3)) %>%  # Remplace add_difference()
  add_n() %>%
  add_stat_label() %>%
  modify_header(label ~ "**Variable**") %>%
  modify_spanning_header(c("stat_1", "stat_2", "stat_3") ~ "**Groupes**") %>%
  bold_labels()
Variable N
Groupes
p-value1
Groupe 1
N = 40
Groupe 2
N = 30
Groupe 3
N = 32
id, Mean (SD) 102 56.7 (29.9) 45.0 (28.7) 51.2 (29.7) 0.262
annee, n (%) 102


0.439
    DFASM1 (D2)
21 (53%) 8 (27%) 12 (38%)
    DFASM2 (D3)
10 (25%) 10 (33%) 10 (31%)
    DFASM3 (D4)
6 (15%) 6 (20%) 5 (16%)
    DFGSM3 (D1)
3 (7.5%) 6 (20%) 5 (16%)
vu_pl, n (%) 102


>0.999
    Non
6 (15%) 4 (13%) 4 (13%)
    Oui
34 (85%) 26 (87%) 28 (88%)
cb_vu, n (%) 89


0.584
    <3
20 (59%) 12 (46%) 18 (62%)
    >5
7 (21%) 4 (15%) 4 (14%)
    Entre 3 et 5
7 (21%) 10 (38%) 7 (24%)
    (Données manquantes)
6 4 3
realise_pl, n (%) 102


0.427
    Non
24 (60%) 14 (47%) 15 (47%)
    Oui
16 (40%) 16 (53%) 17 (53%)
cb_realise, n (%) 49


0.358
    <3
9 (56%) 13 (81%) 11 (65%)
    >5
2 (13%) 2 (13%) 4 (24%)
    Entre 3 et 5
5 (31%) 1 (6.3%) 2 (12%)
    (Données manquantes)
24 14 15
type_aiguille, n (%) 49


0.592
    Aiguille normal
4 (25%) 4 (25%) 6 (35%)
    Aiguilles atraumatique
9 (56%) 10 (63%) 6 (35%)
    Les deux
3 (19%) 2 (13%) 5 (29%)
    (Données manquantes)
24 14 15
cb_reussi, n (%) 49


0.631
    <3
11 (69%) 14 (88%) 12 (71%)
    >5
2 (13%) 0 (0%) 1 (5.9%)
    Entre 3 et 5
3 (19%) 2 (13%) 4 (24%)
    (Données manquantes)
24 14 15
stage_pl, n (%) 102


0.273
    Non
26 (65%) 15 (50%) 22 (69%)
    Oui
14 (35%) 15 (50%) 10 (31%)
formation_pl, n (%) 102


0.658
    Non
8 (20%) 4 (13%) 4 (13%)
    Oui
32 (80%) 26 (87%) 28 (88%)
ecos_pl, n (%) 102


0.705
    Non
31 (78%) 22 (73%) 22 (69%)
    Oui
9 (23%) 8 (27%) 10 (31%)
note_station, n (%) 18


0.183
    5
1 (13%) 0 (0%) 0 (0%)
    6
0 (0%) 0 (0%) 1 (17%)
    8
1 (13%) 0 (0%) 2 (33%)
    8.5
0 (0%) 0 (0%) 1 (17%)
    9
2 (25%) 0 (0%) 0 (0%)
    12
2 (25%) 0 (0%) 1 (17%)
    14
2 (25%) 3 (75%) 0 (0%)
    17.9
0 (0%) 1 (25%) 0 (0%)
    20
0 (0%) 0 (0%) 1 (17%)
    (Données manquantes)
32 26 26
sexe, n (%) 102


0.571
    Femme
29 (73%) 22 (73%) 20 (63%)
    Homme
11 (28%) 8 (27%) 12 (38%)
stai_trait, Mean (SD) 101 40.3 (8.8) 44.6 (8.3) 41.9 (8.6) 0.080
    (Données manquantes)
0 1 0
stai_etat, Mean (SD) 101 37.1 (9.5) 39.6 (8.7) 38.7 (10.5) 0.362
    (Données manquantes)
0 1 0
note_ecos, Mean (SD) 102 15.1 (2.7) 15.0 (3.6) 13.5 (4.4) 0.287
stai_etat2, Mean (SD) 102 37.4 (9.8) 41.0 (10.6) 39.9 (8.6) 0.063
delta_stai_etat, Mean (SD) 102 0.3 (11.9) 2.8 (9.3) 1.3 (8.3) 0.456
1 Kruskal-Wallis rank sum test; Fisher’s exact test; Pearson’s Chi-squared test

Analyse multivariée en intention de traiter

### Pour la note aux ECOS tests
library(lmerTest) 
## 
## Attaching package: 'lmerTest'
## The following object is masked from 'package:lme4':
## 
##     lmer
## The following object is masked from 'package:stats':
## 
##     step
# Filtrage des lignes complètes sur les variables du modèle
ecos_model <- ecos_vr %>%
  filter(!is.na(note_ecos),
         !is.na(groupe),
         !is.na(vu_pl),
         !is.na(realise_pl),
         !is.na(formation_pl),
         !is.na(stage_pl),
         !is.na(type_aiguille),
         !is.na(annee)) %>%
  mutate(across(c(groupe, vu_pl, realise_pl, formation_pl, stage_pl, type_aiguille, annee), as.factor))

# Modèle de régression à ordonnée à l'origine aléatoire
lrm_note_ecos <- lmer(note_ecos ~ groupe + formation_pl + stage_pl + 
                        type_aiguille + sexe + 
                        (1 | annee), data = ecos_model)
summary(lrm_note_ecos)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: note_ecos ~ groupe + formation_pl + stage_pl + type_aiguille +  
##     sexe + (1 | annee)
##    Data: ecos_model
## 
## REML criterion at convergence: 218.2
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -1.68701 -0.58963 -0.03005  0.53473  1.98386 
## 
## Random effects:
##  Groups   Name        Variance Std.Dev.
##  annee    (Intercept) 8.635    2.938   
##  Residual             6.316    2.513   
## Number of obs: 49, groups:  annee, 4
## 
## Fixed effects:
##                                     Estimate Std. Error      df t value
## (Intercept)                          12.2284     1.9875  6.5866   6.153
## groupeGroupe 2                        0.5617     0.9151 38.0208   0.614
## groupeGroupe 3                       -0.2965     0.9451 37.6536  -0.314
## formation_plOui                       2.0535     0.8990 37.8856   2.284
## stage_plOui                           0.8978     0.8663 37.6857   1.036
## type_aiguilleAiguilles atraumatique  -1.9500     0.9499 39.7689  -2.053
## type_aiguilleLes deux                 0.3831     1.2069 39.4389   0.317
## sexeHomme                             1.4256     0.8929 37.9856   1.597
##                                     Pr(>|t|)    
## (Intercept)                         0.000592 ***
## groupeGroupe 2                      0.542940    
## groupeGroupe 3                      0.755418    
## formation_plOui                     0.028045 *  
## stage_plOui                         0.306642    
## type_aiguilleAiguilles atraumatique 0.046717 *  
## type_aiguilleLes deux               0.752589    
## sexeHomme                           0.118638    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) grpGr2 grpGr3 frmt_O stg_pO typ_Aa typ_Ld
## groupeGrop2 -0.192                                          
## groupeGrop3 -0.245  0.469                                   
## formatn_plO -0.316 -0.155 -0.128                            
## stage_plOui -0.307  0.080  0.252 -0.079                     
## typ_gllAgla -0.309 -0.009  0.089  0.081 -0.058              
## typ_gllLsdx -0.177  0.077 -0.113 -0.056 -0.194  0.561       
## sexeHomme   -0.222  0.079 -0.137 -0.012  0.163  0.075  0.245
anova(lrm_note_ecos)
## Type III Analysis of Variance Table with Satterthwaite's method
##               Sum Sq Mean Sq NumDF  DenDF F value  Pr(>F)  
## groupe         5.308   2.654     2 37.837  0.4203 0.65991  
## formation_pl  32.956  32.956     1 37.886  5.2181 0.02804 *
## stage_pl       6.783   6.783     1 37.686  1.0740 0.30664  
## type_aiguille 46.514  23.257     2 38.845  3.6824 0.03432 *
## sexe          16.100  16.100     1 37.986  2.5492 0.11864  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Tests post-hoc
library(emmeans)
## Welcome to emmeans.
## Caution: You lose important information if you filter this package's results.
## See '? untidy'
## 
## Attaching package: 'emmeans'
## The following object is masked from 'package:GGally':
## 
##     pigs
emmeans_ecos <- emmeans(lrm_note_ecos, pairwise ~ groupe, adjust="bonferroni") # Estimer les moyennes marginales par groupe
emmeans_ecos$contrasts # Résultats des comparaisons par paires avec correction de multiplicité (par Bonferroni)
##  contrast            estimate    SE   df t.ratio p.value
##  Groupe 1 - Groupe 2   -0.562 0.918 38.4  -0.612  1.0000
##  Groupe 1 - Groupe 3    0.297 0.946 38.1   0.314  1.0000
##  Groupe 2 - Groupe 3    0.858 0.961 38.3   0.893  1.0000
## 
## Results are averaged over the levels of: formation_pl, stage_pl, type_aiguille, sexe 
## Degrees-of-freedom method: kenward-roger 
## P value adjustment: bonferroni method for 3 tests
emmeans_ecos$emmeans # Afficher les moyennes ajustées
##  groupe   emmean   SE   df lower.CL upper.CL
##  Groupe 1   13.9 1.69 3.97     9.17     18.6
##  Groupe 2   14.5 1.76 4.42     9.75     19.2
##  Groupe 3   13.6 1.67 3.73     8.81     18.4
## 
## Results are averaged over the levels of: formation_pl, stage_pl, type_aiguille, sexe 
## Degrees-of-freedom method: kenward-roger 
## Confidence level used: 0.95
### STAI
library(reshape2)
## 
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
## 
##     smiths
ecos_vr_long <- melt(ecos_vr,
    id.vars=c("stai_trait","groupe","formation_pl","stage_pl", "annee","sexe", "id"),
    measure.vars=c("stai_etat", "stai_etat2"),
    variable.name="temps_stai_etat",
    value.name="stai_etat") # Passer en format long plutôt que large

lrm_stai_etat <- lmer(stai_etat ~ groupe*temps_stai_etat + 
                        formation_pl + stage_pl + sexe + (1 | id), 
                      data = ecos_vr_long)
anova(lrm_stai_etat)
## Type III Analysis of Variance Table with Satterthwaite's method
##                         Sum Sq Mean Sq NumDF  DenDF F value  Pr(>F)  
## groupe                 181.960  90.980     2 87.365  1.6562 0.19680  
## temps_stai_etat         70.524  70.524     1 89.892  1.2838 0.26020  
## formation_pl           262.826 262.826     1 86.809  4.7845 0.03140 *
## stage_pl                34.534  34.534     1 87.348  0.6287 0.43000  
## sexe                   192.615 192.615     1 87.053  3.5064 0.06449 .
## groupe:temps_stai_etat  24.121  12.061     2 89.861  0.2196 0.80331  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Tests post-hoc
emmeans_stai <- emmeans(lrm_stai_etat, pairwise ~ groupe, adjust="bonferroni") # Estimer les moyennes marginales par groupe
## NOTE: Results may be misleading due to involvement in interactions
emmeans_stai$contrasts # Résultats des comparaisons par paires avec correction de multiplicité (par Bonferroni)
##  contrast            estimate   SE   df t.ratio p.value
##  Groupe 1 - Groupe 2   -3.241 1.97 96.4  -1.648  0.3080
##  Groupe 1 - Groupe 3   -2.702 1.92 95.5  -1.409  0.4861
##  Groupe 2 - Groupe 3    0.539 2.07 96.3   0.260  1.0000
## 
## Results are averaged over the levels of: temps_stai_etat, formation_pl, stage_pl, sexe 
## Degrees-of-freedom method: kenward-roger 
## P value adjustment: bonferroni method for 3 tests
emmeans_stai$emmeans # Afficher les moyennes ajustées
##  groupe   emmean   SE   df lower.CL upper.CL
##  Groupe 1   37.8 1.48 95.6     34.8     40.7
##  Groupe 2   41.0 1.70 96.2     37.6     44.4
##  Groupe 3   40.5 1.66 95.6     37.2     43.8
## 
## Results are averaged over the levels of: temps_stai_etat, formation_pl, stage_pl, sexe 
## Degrees-of-freedom method: kenward-roger 
## Confidence level used: 0.95