Ateliers R Trucs et Astuces

Introduction à la modélisation statistique et aux simulations de données

Raphaël Royauté & Lisa Gollot

INRAE UMR EcoSys

2025-03-20

Packages nécessaires

library(tidyverse); library(patchwork)
library(easystats); library(tictoc); 
library(progress); library(viridis)
library(marginaleffects); library(broom)
library(palmerpenguins); library(tinytable)

# style graphique
theme_set(theme_bw(16))

Objectifs

  • Apprendre à définir un modèle générateur de données
  • Maîtriser les fonctions de base pour simuler des données

Petit rappel

5 étapes pour simuler ses données

  1. Définir la question biologique et la quantité à estimer

  2. Convertir en modèle linéaire

  3. Simuler les données depuis (2)

  4. Valider le modèle

  5. Appliquer aux données

Exercice 1

Simulez des données sur la base du modèle suivant: \[y = N(\mu, \sigma)\] à l’aide de la fonction rnorm(n = , mean = , sd = )

  • Calculez la moyenne (mean()) et l’écart type (sd())
  • Représentez les données sous forme d’histogramme (hist())
  • Faites variez la taille d’échantillon n

Exercice 2

Simulez des données avec deux groupes sur la base du modèle suivant: \[y_i = N(\mu_i, \text{ } \sigma) \\ \mu_i = \beta_0 + \beta_1 \times x_i \\ x_i = \begin{cases} 0, & i = 1 \\ 1, & i = 2 \\ \end{cases} \]

  • Calculez la moyenne (mean()) et l’écart type (sd()) par groupe
  • Extraire les coefficients avec lm() et summary()
  • Faites variez la taille d’échantillon n
  • Testez l’hypothèse selon laquelle le groupe 2 a une moyenne 5 fois supérieure au groupe 1 à l’aide de la fonction marginaleffects::hypotheses()

Exercice 2 - Solution

Code
# Définir les paramètres
n = 10 # Taille d'échantillon par groupe
b0 = 100 # moyenne du groupe 1 (référence)
b1 = 10 # différence de moyenne du groupe 2 vàv de la référence (contraste)
sigma = 10 # écart type

# Simuler les donnée
dfsim = data.frame(Id = 1:(n*2),
                       groupe = c(rep("1", n),
                                  rep("2", n)))
dfsim$xi = ifelse(dfsim$groupe == "1", 0, 1)
dfsim = dfsim %>% 
  mutate(y = rnorm(n(), b0 + b1 * xi, sigma))

# Stocker le modèle et explorer les coefficients
mod <- lm(y ~ groupe, dfsim)
summary(mod)

Call:
lm(formula = y ~ groupe, data = dfsim)

Residuals:
     Min       1Q   Median       3Q      Max 
-29.0483  -4.7348   0.1901   6.5998  22.3351 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   96.995      3.487   27.82 3.04e-16 ***
groupe2       13.806      4.931    2.80   0.0118 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 11.03 on 18 degrees of freedom
Multiple R-squared:  0.3034,    Adjusted R-squared:  0.2647 
F-statistic:  7.84 on 1 and 18 DF,  p-value: 0.01184
Code
# Tester l'hypothèse (b0 + b1) = 5 x b0
hypotheses(mod, "(b1 + b2) = 5 * b1")

   Hypothesis Estimate Std. Error   z Pr(>|z|)     S 2.5 % 97.5 %
 (b1+b2)=5*b1     -374       17.8 -21   <0.001 324.2  -409   -339

Biais, précision et variance d’échantillonage

  • La variance d’échantillonage diminue avec la taille d’échantillon

  • Forte probabilité d’obtenir une valeure biaisée avec une faible taille d’échantillon

Biais, précision et variance d’échantillonage

Code
iter = 100
n = c(5:200)
b0 = 100
b1 = 10
sigma = 10
counter = 0 # compteur à incrémenter de 1 à chaque itération

out = matrix(NA, nrow = iter*length(n), ncol = 7)
colnames(out) = c("iter", # numéro de simulation
                  "n", # nombre de mesures par groupe
                  "b1_sim", # différence simulée
                  "b1_est", # différence estimée
                  "p", # p-value
                  "diff_est", # erreur de mesure (est - sim)
                  "perc_diff" # % erreur (est - sim) / sim * 100
)

# Barre de progression
pb <- progress_bar$new(
  format = "  downloading [:bar] :percent eta: :eta",
  total = nrow(out), clear = FALSE, width= 60)

set.seed(42)

for (i in 1:iter) {
  for (reps in 1:length(n)) {
    pb$tick()
    Sys.sleep(1 / nrow(out))
    
    counter = counter + 1
    
    # Génération du jeu de données simulées
    dfsim = data.frame(Id = 1:(n[reps]*2),
                       groupe = c(rep("1", n[reps]),
                                  rep("2", n[reps])))
    dfsim$xi = ifelse(dfsim$groupe == "1", 0, 1)
    dfsim = dfsim %>% 
      mutate(y = rnorm(n(), b0 + b1 * xi, sigma))
    
    # modèle statistique
    lm.sim = lm(y ~ groupe, dfsim)
    b1_est = as.numeric(coef(lm.sim)[2]) # valeur de b1 estimée
    p = p_value(lm.sim)$p[2] # p-value pour b1
    diff_est = b1_est - b1
    perc_diff = diff_est / b1 * 100
    
    # stockage des données à la ième ligne de la matrice 'out'
    out[counter, 1] = i # numéro de simulation
    out[counter, 2] = n[reps] # nombre de mesures par groupe
    out[counter, 3] = b1 # différence simulée
    out[counter, 4] = b1_est # différence estimée
    out[counter, 5] = p # p-value
    out[counter, 6] = diff_est # erreur de mesure (est - sim)
    out[counter, 7] = perc_diff # % erreur (est - sim) / sim * 100
  }
  
}

out %>% 
  data.frame() %>% 
  ggplot(aes(x = n, y = b1_est, fill = n)) +
  geom_point(alpha = .9, size = 2, shape = 21, color = "black") +
  geom_hline(yintercept = b1, linetype = "dashed", size = 1.5) +
  scale_fill_viridis(option = "H", direction = -1) +
  xlab("Taille d'echantillon par groupe") + 
  ylab("b1")

Puissance et typologie des erreurs

  • Puissance : probabilité de détecter un effet lorsqu’il existe
  • Erreur de type I : détecter un effet inexistant
  • Erreur de type II : rejeter un effet existant
  • Erreur de type S : se tromper dans le signe de l’effet
  • Erreur de type M : se tromper dans l’intensité de l’effet

Puissance et typologie des erreurs

Synthèse des différents types d’erreur statistiques pouvant être étudiées par simulation
Métrique Définition
Puissance Proportion des simulations avec des effets significatifs pour un \(\alpha\) donné
Taux de faux positifs Proportion des simulations avec des effets significatifs lorsque les données sont simulées sous l’hpothèse nulle
Couverture statistique % des simulations pour lesquelles l’intervalle de confiance inclue la valeure simulée
Erreur de type M moyenne de la valeure absolue des estimés significatifs pondérée par la taille d’effet
Erreur de type S % d’estimés du signe opposé à l’effet

Visualisation de l’erreur de type M & S

Code
out = as.data.frame(out)
out = out %>% 
  mutate(S = ifelse(b1_est < 0, 1, 0),
           M = ifelse(abs(b1_est - b1_sim) / b1_sim > .2,
                      1, 0))

p1 = out %>% 
  ggplot(aes(x = n, y = b1_est, fill = factor(M))) +
  geom_point(alpha = .9, size = 2, shape = 21) +
  geom_hline(yintercept = b1, linetype = "dashed", size = 1.5) +
  scale_fill_manual(values = c("white", "red")) +
  xlab("Taille d'echantillon par groupe") + 
  ylab("b1") +
  theme(legend.position = "none") +
  labs(title = "Erreur de type M",
       subtitle = "Estimés > 20 % d'erreur")

p2 = out %>% 
  ggplot(aes(x = n, y = b1_est, fill = factor(S))) +
  geom_point(alpha = .9, size = 2, shape = 21) +
  geom_hline(yintercept = b1, linetype = "dashed", size = 1.5) +
  scale_fill_manual(values = c("white", "red")) +
  xlab("Taille d'echantillon par groupe") + 
  ylab("b1") +
  theme(legend.position = "none") +
  labs(title = "Erreur de type S")

p1 + p2

Dimorphisme sexuel chez les manchots

Un chercheur vous contacte pour un conseil statistique. Il constate que les mâle et femelles des manchots de sa station expérimentale ont des tailles très différentes. Il pense que les manchots d’Adélie expriment un plus faible dimorphisme de part un régime alimentaire plus similaire entre sexes. Ses premières observations semblent aller dans son sens. Attraper des manchots est difficile ! Il pense pouvoir capturer au maximum 10 individus de chaque sexe et espèce. As-t-il une bonne chance de détecter une différence de dimorphisme entre espèce ?

Dimorphisme sexuel chez les manchots

Code
set.seed(42)
penguins %>% 
  drop_na() %>% 
  group_by(sex, species) %>% 
  slice_sample(n = 5) %>% 
  ggplot(aes(y = flipper_length_mm, x = sex, group = species)) +
  geom_point() +
  facet_wrap(~species) +
  ylab("Flipper length (mm)")

Dimorphisme sexuel chez les manchots

Code
set.seed(42)
df <- penguins %>% 
  drop_na() %>% 
  group_by(sex, species) %>% 
  slice_sample(n = 5) %>% 
  summarise(mean_fl = mean(flipper_length_mm, na.rm = T),
            sd_fl = sd(flipper_length_mm, na.rm = T)) %>% 
  mutate(N = 5) %>%
  pivot_wider(names_from = sex, values_from = c(mean_fl, sd_fl)) %>% 
  mutate(Delta_mean = mean_fl_male - mean_fl_female) %>% 
  select(species, N, 
         mean_fl_female, sd_fl_female,
         mean_fl_male, sd_fl_male,
         Delta_mean) %>% 
  rename(Species = species,
         # Females = mean_fl_female,
         # Males = mean_fl_male,
         Delta = Delta_mean)
df %>% 
  tt(digits = 3) %>% 
  setNames(c("", "", "mean", 
             "sd", "mean", "sd", "")) %>% 
  group_tt(j = list(
    "Species" = 1,
    "N" = 2,
    "Females" = 3:4,
    "Males" = 5:6,
    "Delta" = 7))
Species N Females Males Delta
mean sd mean sd
Adelie 5 185 2.83 192 5.4 7.2
Chinstrap 5 189 7.98 200 3.35 11
Gentoo 5 214 5.4 226 2.68 12.4

Définir la question

Question scientifique Les manchots d’Adélie ont-ils un dimorphisme sexuel plus faible comparé aux manchots Chinstrap et Gentoo?

Prédiction La différence male-femelle chez les manchots d’Adélie est plus faible que celle des deux autres espèces

Mettre en équations

Modèle \[ \begin{aligned} flipper_{i,j} &= N(\mu_{i,j}, \text{ } \sigma) \\ \mu_{i,j} &= \beta_0 + \\ &\beta_1 \times Sex_{[i = 1]} + \\ &\beta_2 \times Sp_{[j = 1]} + \beta_3 \times Sp_{[j = 2]} +\\ &\beta_4 \times Sex_{[i = 1]} \times Sp_{[j = 1]} \\ &\beta_5 \times Sex_{[i = 1]} \times Sp_{[j = 2]}\\ i = 0: Females&; i = 1: Males\\ j = 0: Adélie; j = 1&: Chintrap; j = 2: Adélie \end{aligned} \]

Mettre en équations

Quantité à estimer \[ \begin{aligned} &\text{Dimorphisme Adélie } = \beta_1 \\ &\text{Dimorphisme Chinstrap } = \beta_1 + \beta_4 \\ &\text{Dimorphisme Gentoo } = \beta_1 +\beta_5 \\ \end{aligned} \]

Coder le modèle

# Lister les paramètres
n = 10
sigma = 15
Sex = c("Females", "Males")
Sp = c("Ad", "Ch", "Gen")

mu_A_F = 185; mu_A_M = 192
mu_C_F = 189; mu_C_M = 200
mu_G_F = 214; mu_G_M = 226

b0 = mu_A_F # moyenne ailes manchots d'Adélie femelles
b1 = mu_A_M - mu_A_F # différence male - femelles Adélie
b2 = mu_C_F - mu_A_F # différence femelles Chinstrap - femelles Adélie
b3 = mu_G_F - mu_A_F # différence femelles Gentoo - femelles Adélie 
b4 = mu_C_M - (b0+b1+b2) # interaction sexe =  males x Sp =  Chinstrap
b5 = mu_G_M - (b0+b1+b3) # interaction sexe =  males x Sp =  Gentoo

c(b0, b1, b2, b3, b4, b5)
[1] 185   7   4  29   4   5

Coder le modèle

Code
# Generer le dataframe
df = crossing(n = 1:n, Sex, Sp) %>% 
  mutate(Sex_bool = ifelse(Sex == "Males", 1, 0),
         Sp_bool_1 = ifelse(Sp == "Ch", 1, 0),
         Sp_bool_2 = ifelse(Sp == "Gen", 1, 0))

# Générer les données
set.seed(42)
df = df %>% 
  mutate(flipper_length = rnorm(n(), 
                      b0 + 
                        b1 * Sex_bool +
                        b2 * Sp_bool_1 + 
                        b3 * Sp_bool_2 +
                        b4 * Sex_bool * Sp_bool_1 +
                        b5 * Sex_bool * Sp_bool_2,
                      sigma))

# Graphique
df %>% 
  ggplot(aes(x = Sex, y = flipper_length, color = Sp, group = Sp)) +
  geom_point(size = 4, alpha = .6) +
  geom_smooth(method = "lm") +
  facet_wrap(~Sp) +
  scale_color_manual(values =
                       c("darkorange","darkorchid","cyan4")) +
  theme(legend.position = "none")

Exercice 3

  • Testez le modèle statistique avec les fonctions lm() et summary()
  • Utilisez la fonction performance::check_model() pour évaluer la pertinence du modèle sur les données simulées
  • Utilisez la fonction marginaleffects::hypotheses() pour tester l’hypothèse d’un dimorphisme moins prononcé chez les manchots d’Adélie

Exercice 3 - Solution

Estimer le modèle

Code

lm.penguins = lm(flipper_length ~ 1 + Sex * Sp, df)
summary(lm.penguins)

Call:
lm(formula = flipper_length ~ 1 + Sex * Sp, data = df)

Residuals:
    Min      1Q  Median      3Q     Max 
-45.189  -8.141   3.241  10.351  33.711 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)    186.5537     5.6682  32.913  < 2e-16 ***
SexMales         0.6877     8.0160   0.086  0.93195    
SpCh             2.4627     8.0160   0.307  0.75986    
SpGen           27.3535     8.0160   3.412  0.00123 ** 
SexMales:SpCh   10.5888    11.3363   0.934  0.35443    
SexMales:SpGen  11.9939    11.3363   1.058  0.29476    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 17.92 on 54 degrees of freedom
Multiple R-squared:  0.4399,    Adjusted R-squared:  0.388 
F-statistic: 8.482 on 5 and 54 DF,  p-value: 5.631e-06

Exercice 3 - Solution

Représenter les coefficients

Code

model_parameters(lm.penguins) %>% tt(digits = 2)
Parameter Coefficient SE CI CI_low CI_high t df_error p
(Intercept) 186.55 5.7 0.95 175 198 32.913 54 0.0000000000000000000000000000000000002
SexMales 0.69 8 0.95 -15 17 0.086 54 0.9319468401391421963353423052467405796
SpCh 2.46 8 0.95 -14 19 0.307 54 0.7598588900983966887281439994694665074
SpGen 27.35 8 0.95 11 43 3.412 54 0.0012273135022853084562938219548300367
SexMales:SpCh 10.59 11.3 0.95 -12 33 0.934 54 0.3544323133403803893770600552670657635
SexMales:SpGen 11.99 11.3 0.95 -11 35 1.058 54 0.2947633515564935247077471558441175148

Exercice 3 - Solution

Représenter les coefficients

Code

plot(model_parameters(lm.penguins))

Exercice 3

Valeures simulées vs. estimées

Code
df_parms = data.frame(Parameter = 
                        c("(Intercept)", "SexMales",
                          "SpCh", "SpGen", "SexMales:SpCh",
                          "SexMales:SpGen"),
                      Coefficient = c(b0, b1, b2, b3, b4, b5))

parms <- model_parameters(lm.penguins) %>% data.frame()
parms %>% 
  ggplot(aes(x = Coefficient, y = Parameter)) +
  geom_pointrange(aes(xmin = CI_low, xmax = CI_high)) +
  geom_point(data = df_parms,
             aes(x = Coefficient, 
                 y = Parameter, 
                 fill = "red"), 
             shape = 23, 
             size = 2.5, 
             alpha = .6) +
  theme(legend.position = "none")

Exercice 3 - Solution

Calculer les moyennes par sexe et espèce

Code

estimate_means(lm.penguins) %>% tt(digits = 2)
Sex Sp Mean SE CI_low CI_high t df
Females Ad 187 5.7 175 198 33 54
Females Ch 189 5.7 178 200 33 54
Females Gen 214 5.7 203 225 38 54
Males Ad 187 5.7 176 199 33 54
Males Ch 200 5.7 189 212 35 54
Males Gen 227 5.7 215 238 40 54

Exercice 3 - Solution

Inspecter le modèle

Code

check_model(lm.penguins)

Exercice 3 - Solution

Calculer les différences de dimorphisme

Code

avg_comparisons(lm.penguins, variables = "Sex", by = "Sp") %>% 
    knitr::kable(digits = 2)
term contrast Sp estimate std.error statistic p.value s.value conf.low conf.high
Sex Males - Females Ad 0.69 8.02 0.09 0.93 0.10 -15.02 16.40
Sex Males - Females Ch 11.28 8.02 1.41 0.16 2.65 -4.43 26.99
Sex Males - Females Gen 12.68 8.02 1.58 0.11 3.14 -3.03 28.39

Exercice 3 - Solution

Calculer les différences de dimorphisme

Code
p <- plot_comparisons(lm.penguins, variables = "Sex", condition = "Sp")

df_dim = data.frame(marginaleffects_term_index = rep("Sex", 3),
                    Sp = c("Ad", "Ch", "Gen"),
                    Estimate = c(mu_A_M - mu_A_F,
                                 mu_C_M - mu_C_F,
                                 mu_G_M - mu_G_F))
p +
  geom_point(data = df_dim,
             aes(x = Sp, 
                 y = Estimate, 
                 fill = "red"), 
             shape = 23, 
             size = 3, 
             alpha = .9) +
  theme(legend.position = "none")

Exercice 3 - Solution

Tester les hypothèses

Code

hypotheses(lm.penguins, "b2 = (b5 - b3)")

 Hypothesis Estimate Std. Error      z Pr(>|z|)   S 2.5 % 97.5 %
 b2=(b5-b3)    -7.44         24 -0.309    0.757 0.4 -54.6   39.7
hypotheses(lm.penguins, "b2 = (b6 - b4)")

 Hypothesis Estimate Std. Error     z Pr(>|z|)   S 2.5 % 97.5 %
 b2=(b6-b4)       16         24 0.667    0.505 1.0 -31.1   63.2
hypotheses(lm.penguins, "(b5 - b3) = (b6 - b4)")

      Hypothesis Estimate Std. Error    z Pr(>|z|)   S 2.5 % 97.5 %
 (b5-b3)=(b6-b4)     23.5       17.9 1.31     0.19 2.4 -11.6   58.6

Exercice 4

Faîtes une analyse de puissance pour calculer un plan d’échantillonnage optimal pour estimer une différence de dimorphisme d’au moins 20 % entre manchots d’Adélie et les deux autres espèces

OU

Simulez votre plan d’expérience

BONUS : Analyse de puissance

Code
out %>% 
  mutate(sig = case_when(p < 0.05 ~ 1, p >= 0.05 ~ 0)) %>%
  group_by(n) %>% 
  summarise(sig.prop = sum(sig)/n() * 100) %>% 
  ggplot(aes(x = n, y = sig.prop, fill = n)) +
  geom_line() +
  geom_point(alpha = .9, size = 3, shape = 21, color = "black") +
  geom_hline(aes(yintercept=80),linetype="dashed") +
  scale_fill_viridis(option = "H", direction = -1) +
  xlab("Taille d'echantillon par groupe") + 
  ylab("Puissance statistique")

BONUS : GLM avec données de proportions

Différences de survie entre espèces \[ \begin{aligned} Survie_i &= Binomial(n,p) \\ logit(p_i) &= \beta_0 + \\ &\beta_1 \times Sp_{[i = 1]} + \\ &\beta_2 \times Sp_{[i = 2]}\\ i = 0: Adélie; i = 1&: Chintrap; i = 2: Adélie \end{aligned} \]

BONUS : GLM avec données de proportions

Différences de survie entre espèces

Code
n = 20
Sp = c("Ad", "Ch", "Gen")
b0 = plogis(-.4) # moyenne de survie manchots d'Adélie  = 40 %
b1 = plogis(1) # différence de survie Chinstrap - Adélie = 64 %
b2 = plogis(1.5) # différence de survie Gentoo - Adélie


# Generer le dataframe
df <- crossing(n = 1:n, Sp) %>% 
  mutate(Sp_bool_1 = ifelse(Sp == "Ch", 1, 0),
         Sp_bool_2 = ifelse(Sp == "Gen", 1, 0))

# Générer les données
set.seed(42)
df <- df %>% 
  mutate(logit_p = b0 + 
           b1 * Sp_bool_1 +
           b2 * Sp_bool_2) %>% # Echelle logit
  mutate(p = plogis(logit_p)) %>% # Echelle des probabilités
  mutate(Survie = rbinom(n(), prob = p, size = 1))

glm.binom <- glm(Survie ~ Sp, df, family = "binomial")
model_parameters(glm.binom) # Coefficients
Parameter   | Log-Odds |   SE |        95% CI |     z |     p
-------------------------------------------------------------
(Intercept) |    -0.41 | 0.46 | [-1.34, 0.48] | -0.89 | 0.374
Sp [Ch]     |     1.25 | 0.67 | [-0.02, 2.62] |  1.87 | 0.061
Sp [Gen]    |     1.25 | 0.67 | [-0.02, 2.62] |  1.87 | 0.061
Code
avg_comparisons(glm.binom) # Différence de survie (%)

 Contrast Estimate Std. Error z Pr(>|z|)   S   2.5 % 97.5 %
 Ch - Ad       0.3       0.15 2   0.0455 4.5 0.00601  0.594
 Gen - Ad      0.3       0.15 2   0.0455 4.5 0.00601  0.594

Term: Sp
Type:  response 

BONUS : GLM avec données de proportions

Code
plot_predictions(glm.binom, by = "Sp")

BONUS : GLM avec données de comptage

\[ \begin{aligned} Fécondité_i &= Poisson(\lambda_i) \\ log(\lambda_i) &= \beta_0 + \\ &\beta_1 \times Sp_{[i = 1]} + \\ &\beta_2 \times Sp_{[i = 2]}\\ i = 0: Adélie; i = 1&: Chintrap; i = 2: Adélie \end{aligned} \]

BONUS : GLM avec données de comptage

Code
n = 20
Sp = c("Ad", "Ch", "Gen")
b0 = log(10) # moyenne de fécondité manchots d'Adélie  = 10
b1 = log(2) # différence de fécondité Chinstrap - Adélie = +2
b2 = plogis(4) # différence de fécondité Gentoo - Adélie + 4


# Generer le dataframe
df <- crossing(n = 1:n, Sp) %>% 
  mutate(Sp_bool_1 = ifelse(Sp == "Ch", 1, 0),
         Sp_bool_2 = ifelse(Sp == "Gen", 1, 0))

# Générer les données
set.seed(42)
df <- df %>% 
  mutate(log_lambda = b0 + 
           b1 * Sp_bool_1 +
           b2 * Sp_bool_2) %>% # Echelle log
  mutate(lambda = exp(log_lambda)) %>% # Echelle des comptages
  mutate(Fecondite = rpois(n(), lambda = lambda))

glm.poiss <- glm(Fecondite ~ Sp, df, family = "poisson")
model_parameters(glm.poiss) # Coefficients
Parameter   | Log-Mean |   SE |       95% CI |     z |      p
-------------------------------------------------------------
(Intercept) |     2.31 | 0.07 | [2.17, 2.44] | 32.72 | < .001
Sp [Ch]     |     0.73 | 0.09 | [0.57, 0.90] |  8.53 | < .001
Sp [Gen]    |     1.05 | 0.08 | [0.89, 1.21] | 12.75 | < .001
Code
avg_comparisons(glm.poiss) # Différence de survie (%)

 Contrast Estimate Std. Error     z Pr(>|z|)     S 2.5 % 97.5 %
 Ch - Ad      10.9       1.24  8.72   <0.001  58.3  8.41   13.3
 Gen - Ad     18.5       1.39 13.34   <0.001 132.5 15.83   21.3

Term: Sp
Type:  response 

BONUS : GLM avec données de comptage

Code
plot_predictions(glm.poiss, by = "Sp") # Figure

BONUS : Test d’équivalence

  • Région d’équivalence = +/- 5 unités
  • p(Equiv) > 0.05 -> l’effet n’est pas dans la région d’équivalence
Code
n = 10
sigma = 10
b0 = 100
b1 = 50
Eq = 5 # Région d'équivalence = +/- 5

groupe = c("1", "2")

df = data.frame(Rep = 1:(n[1]*2),
                groupe = c(rep("1", n[1]),
                           rep("2", n[1])))
df$xi = ifelse(df$groupe == "1", 0, 1)

set.seed(42)
df = df %>% 
  mutate(y = rnorm(n(), b0 + b1 * xi, sigma))

lm.eq = lm(y ~ groupe, df)
# pred.b1 = avg_slopes(lm.eq, variables = "groupe")
hyp = hypotheses(lm.eq, 
                 equivalence = 
                   c(- Eq, Eq))
hyp

        Term Estimate Std. Error    z Pr(>|z|)     S 2.5 % 97.5 % p (NonSup)
 (Intercept)    105.5       4.10 25.7   <0.001 483.1  97.4  113.5          1
 groupe2         42.9       5.79  7.4   <0.001  42.8  31.5   54.2          1
 p (NonInf) p (Equiv)
     <0.001         1
     <0.001         1

BONUS : Test d’équivalence

  • Région d’équivalence = +/- 5 unités
  • p(Equiv) > 0.05 -> l’effet n’est pas dans la région d’équivalence
Code
hyp %>% 
    data.frame() %>% 
    ggplot(aes(y = term, x = estimate)) +
    geom_point() +
    geom_pointrange(aes(xmin = conf.low, xmax = conf.high)) +
    geom_rect(aes(xmin = -Eq, xmax = Eq, ymin = 0, ymax = 2), , fill = "grey", alpha = .6)