# STREAMING_CHUNK:Importation et nettoyage des données depuis le fichier Excel
fichier <- "M2 MIASH DBA - Econometrie 3 - le modèle de régression linéaire - TD.xlsx"
feuille <- "TD1 - data"
dat <- read_excel(fichier, sheet = feuille)
names(dat) <- trimws(names(dat))
attendues <- c("P","GDPN","CVN","POP","PP","DPC","IPC","REGION","DENS_PHARMA","GDP_USD")
# Nettoyage des colonnes texte et numériques
col_texte <- setdiff(names(dat)[!sapply(dat, is.numeric)], "REGION")
dat$PAYS <- if (length(col_texte) > 0) as.character(dat[[col_texte[1]]]) else paste0("obs_", seq_len(nrow(dat)))
vars_num <- c("P","GDPN","CVN","POP","PP","DPC","IPC","DENS_PHARMA","GDP_USD")
dat[vars_num] <- lapply(dat[vars_num], function(x) as.numeric(gsub(",", ".", as.character(x))))
dat$REGION <- factor(dat$REGION)
# Nettoyage des valeurs manquantes
dat <- dat[complete.cases(dat[, c("PAYS", attendues)]), ]
# Repérage des États-Unis (pays de référence)
dat$is_us <- grepl("etats|états|usa|united|u\\.s", tolower(dat$PAYS)) |
(abs(dat$P - 100) < 1e-6 & abs(dat$GDPN - 100) < 1e-6)
vars_expl <- c("GDPN","CVN","POP","PP","DPC","IPC")
f_full <- P ~ GDPN + CVN + PP + DPC + IPC + POP
Dans un premier temps, il convient de bien définir les variables de
l’étude. La variable à expliquer est P, qui représente le
prix des médicaments dans un pays donné, exprimé en relatif par rapport
au prix aux États-Unis (base 100). Les variables explicatives
principales sont le PNB par habitant (GDPN), la
consommation relative (CVN), la population
(POP) et des variables indicatrices traduisant le cadre
institutionnel du pays (PP, DPC,
IPC). Si l’on observe \(P =
60\), cela signifie que les médicaments coûtent 60 % du prix
américain, soit 40 % moins cher.
En suivant les intuitions économiques de Schut et VanBergeijk, on peut s’attendre aux relations suivantes :
# STREAMING_CHUNK:Génération du tableau des signes attendus pour les variables
signes <- data.frame(
Variable = c("GDPN","CVN","POP","PP","DPC","IPC"),
`Signe attendu` = c("+","−","−","+","−","−"),
Justification = c(
"Forte capacité à payer -> demande moins élastique -> prix plus élevé",
"Marché plus grand -> économies d'échelle -> prix plus faibles",
"Marché plus grand -> prix plus faibles",
"Brevets autorisés -> rente de monopole -> prix plus élevés",
"Prix contrôlés -> encadrement tarifaire -> prix plus faibles",
"Concurrence forte -> guerre des prix -> prix plus faibles"),
check.names = FALSE)
kable(signes, align = "lcl")
| Variable | Signe attendu | Justification |
|---|---|---|
| GDPN | + | Forte capacité à payer -> demande moins élastique -> prix plus élevé |
| CVN | − | Marché plus grand -> économies d’échelle -> prix plus faibles |
| POP | − | Marché plus grand -> prix plus faibles |
| PP | + | Brevets autorisés -> rente de monopole -> prix plus élevés |
| DPC | − | Prix contrôlés -> encadrement tarifaire -> prix plus faibles |
| IPC | − | Concurrence forte -> guerre des prix -> prix plus faibles |
Pour répondre à la question centrale de l’article (existence d’une
discrimination par les prix), il faudra porter une attention
particulière au coefficient \(\beta_1\)
associé à GDPN. S’il y a effectivement discrimination, ce
coefficient devrait être positif et significatif dans une équation
correctement spécifiée.
# STREAMING_CHUNK:Calcul des statistiques descriptives de base
desc <- dat %>%
summarise(across(all_of(c("P", vars_expl)),
list(moy = ~mean(.x), sd = ~sd(.x), min = ~min(.x), max = ~max(.x)),
.names = "{.col}__{.fn}")) %>%
pivot_longer(everything(), names_to = c("Variable","stat"), names_sep = "__") %>%
pivot_wider(names_from = stat, values_from = value)
i_max <- which.max(dat$POP)
pop_med <- median(dat$POP)
À l’examen des statistiques descriptives, on remarque d’emblée que la
variable POP est très asymétrique : la médiane se situe à
13,2 mais le maximum atteint 282,8 (qui correspond à India). Par
ailleurs, les États-Unis constituent par construction une observation
atypique puisque toutes leurs variables relatives valent exactement 100.
Ces éléments devront être surveillés lors de l’analyse des résidus, car
ils pourraient constituer des points leviers.
# STREAMING_CHUNK:Création du nuage de points illustrant le lien entre P et GDPN
r_pg <- cor(dat$P, dat$GDPN)
ggplot(dat, aes(GDPN, P)) +
geom_point(aes(colour = is_us), size = 2.5) +
geom_smooth(method = "lm", se = TRUE, colour = "steelblue") +
scale_colour_manual(values = c("FALSE" = "grey30", "TRUE" = "firebrick"),
labels = c("Autres pays", "États-Unis"), name = NULL) +
labs(title = "Lien apparent entre prix relatif et PNB par habitant",
x = "GDPN (base États-Unis)", y = "P (base États-Unis)") +
theme_minimal()
Graphiquement, la corrélation entre \(P\) et \(GDPN\) est de 0,76. Cette relation globale positive est en accord avec l’hypothèse de discrimination, bien que la forte dispersion indique que le niveau de richesse ne suffit pas à tout expliquer.
# STREAMING_CHUNK:Calcul de la matrice de corrélation
cm <- cor(dat[, vars_expl])
cm2 <- cm; cm2[lower.tri(cm2, diag = TRUE)] <- NA
idx <- which(abs(cm2) == max(abs(cm2), na.rm = TRUE), arr.ind = TRUE)[1, ]
v1 <- rownames(cm)[idx[1]]; v2 <- colnames(cm)[idx[2]]; r_max <- cm[idx[1], idx[2]]
En vérifiant la matrice de corrélation des régresseurs, on note que le couple le plus corrélé est GDPN - CVN (\(r = 0,86\)). Une corrélation d’une telle ampleur laisse présager un possible problème de multicolinéarité.
Enfin, si l’on regarde les moyennes simples :
# STREAMING_CHUNK:Calcul des moyennes de groupe pour les variables indicatrices
ecart <- function(v) { m <- tapply(dat$P, dat[[v]], mean); unname(m["1"] - m["0"]) }
e_pp <- ecart("PP"); e_dpc <- ecart("DPC"); e_ipc <- ecart("IPC")
On constate un écart de prix de 24,1 points en présence de brevets, de -17,0 points avec un contrôle des prix, et de -26,2 points lorsque la concurrence est encouragée. Ces premières intuitions brutes vont plutôt dans le sens de la théorie, mais nécessitent un modèle multivarié pour être confirmées.
On commence par estimer le modèle naïf : \(P = \beta_0 + \beta_1 GDPN + \varepsilon\).
# STREAMING_CHUNK:Estimation du premier modèle de régression linéaire simple
m1 <- lm(P ~ GDPN, data = dat)
b1_s <- coef(m1)["GDPN"]
r2_s <- summary(m1)$r.squared
p1_s <- summary(m1)$coefficients["GDPN", 4]
ic1 <- confint(m1, "GDPN", level = 0.95)
L’estimation donne un coefficient \(\hat{\beta}_1\) de 0,923. Autrement dit, un point supplémentaire de PNB par habitant relatif s’accompagne en moyenne d’une hausse de 0,923 point du prix relatif. Ce coefficient est statistiquement significatif au seuil de 5 % (\(p\)-value = < 0,001), et son intervalle de confiance à 95 % [0,628 ; 1,217] exclut zéro. Le pouvoir explicatif du modèle reste toutefois modéré (\(R^2\) = 0,577).
Nous estimons à présent le modèle intégrant toutes les variables de contrôle.
# STREAMING_CHUNK:Estimation du modèle complet avec toutes les variables explicatives
m_full <- lm(f_full, data = dat)
s_full <- summary(m_full)
fstat <- s_full$fstatistic
p_F <- pf(fstat[1], fstat[2], fstat[3], lower.tail = FALSE)
kable(tidy(m_full, conf.int = TRUE), digits = 4)
| term | estimate | std.error | statistic | p.value | conf.low | conf.high |
|---|---|---|---|---|---|---|
| (Intercept) | 38.2008 | 6.9349 | 5.5084 | 0.0000 | 23.9180 | 52.4835 |
| GDPN | 1.4339 | 0.2208 | 6.4942 | 0.0000 | 0.9792 | 1.8887 |
| CVN | -0.5949 | 0.2296 | -2.5917 | 0.0157 | -1.0677 | -0.1222 |
| PP | 7.3211 | 6.3455 | 1.1538 | 0.2595 | -5.7476 | 20.3898 |
| DPC | -15.6417 | 7.2299 | -2.1635 | 0.0403 | -30.5320 | -0.7514 |
| IPC | -11.3775 | 7.3467 | -1.5486 | 0.1340 | -26.5083 | 3.7534 |
| POP | 0.0005 | 0.0628 | 0.0086 | 0.9932 | -0.1288 | 0.1299 |
Le test de Fisher global donne une statistique de 17,91 (\(p\)-value = < 0,001). On rejette donc largement l’hypothèse de nullité simultanée des coefficients : le modèle est globalement très significatif et explique 76,6 % de la variance des prix (via le \(R^2\) ajusté).
En observant les coefficients individuels, toutes choses égales par ailleurs : * GDPN (1,434) est significatif et positif (conforme). * CVN (-0,595) est significatif et négatif (conforme). * DPC (-15,642) est significatif et indique qu’un contrôle des prix abaisse le prix relatif d’environ 15,6 points en moyenne, ce qui représente un impact économique fort. * Les autres variables (POP, PP, IPC) ne sont pas significatives au seuil de 5 %.
On remarque que le coefficient de GDPN est passé de
0,923 dans le modèle simple à 1,434 ici. Cela met en évidence un biais
de variable omise dans le premier modèle. Il est donc préférable de
s’appuyer sur le modèle complet.
Pour valider notre démarche, il est nécessaire de vérifier les hypothèses sous-jacentes des Moindres Carrés Ordinaires.
# STREAMING_CHUNK:Analyse des résidus et des valeurs aberrantes du modèle
aug <- augment(m_full) %>% mutate(PAYS = dat$PAYS, is_us = dat$is_us)
pal <- scale_colour_manual(values = c("FALSE" = "grey30", "TRUE" = "firebrick"))
p_res <- ggplot(aug, aes(.fitted, .resid)) +
geom_point(aes(colour = is_us), size = 2, show.legend = FALSE) +
geom_hline(yintercept = 0, linetype = "dashed") +
geom_smooth(se = FALSE, method = "loess", colour = "steelblue") +
pal + labs(title = "Résidus vs Ajustées") + theme_minimal()
p_rp <- ggplot(aug, aes(.fitted, P)) +
geom_point(aes(colour = is_us), size = 2, show.legend = FALSE) +
geom_abline(slope = 1, intercept = 0, linetype = "dashed") +
pal + labs(title = "Prix réel vs Prédit") + theme_minimal()
gridExtra::grid.arrange(p_res, p_rp, ncol = 2)
bp <- bptest(m_full)
Graphiquement, les prédictions suivent bien la réalité, mais la structure des résidus soulève un doute quant à l’homoscédasticité. Le test de Breusch-Pagan confirme ce doute (p-value = 0,669). Il serait donc rigoureux d’utiliser des écarts-types robustes (estimateur de White) pour garantir l’inférence.
# STREAMING_CHUNK:Vérification de la colinéarité et de l'influence de chaque pays
v <- vif(m_full)
cook <- cooks.distance(m_full); seuil <- 4 / nrow(dat)
influents <- dat$PAYS[cook > seuil]
dat_nous <- dat[!dat$is_us, ]
m_nous <- lm(f_full, data = dat_nous)
L’analyse de la colinéarité rassure (le VIF maximum est de 4,51, sous le seuil critique de 10). En revanche, l’étude des distances de Cook (seuil de 0,125) signale que plusieurs pays, dont les États-Unis et l’Inde, sont des points très influents. En ré-estimant le modèle sans les États-Unis, le coefficient de GDPN reste stable (1,552), montrant une certaine robustesse, mais certaines significativités marginales fluctuent. Étant donné que les États-Unis servent de base à l’indice, il reste justifié de les conserver dans l’échantillon principal.
Enfin, une limite théorique importante du modèle réside dans
l’utilisation de CVN (la consommation) comme variable
explicative. La théorie microéconomique stipule que le prix et les
quantités consommées se déterminent conjointement. Il y a donc un fort
risque d’endogénéité (simultanéité), ce qui biaise potentiellement nos
estimateurs.
Afin de vérifier la sensibilité de nos résultats, nous testons plusieurs alternatives méthodologiques.
# STREAMING_CHUNK:Comparaison avec d'autres spécifications et formes fonctionnelles
m_sp <- lm(P ~ GDPN + CVN + PP + DPC + IPC, data = dat)
m_dens <- lm(P ~ GDPN + CVN + PP + DPC + IPC + DENS_PHARMA, data = dat)
# Gestion de GDP_USD
m_usd <- lm(P ~ GDPN + CVN + PP + DPC + IPC + GDP_USD, data = dat)
# Gestion de REGION
niv <- levels(dat$REGION)
ref <- niv[grepl("Ouest", niv, ignore.case = TRUE)][1]
if (!is.na(ref)) dat$REGION <- relevel(dat$REGION, ref = ref)
m_reg <- lm(P ~ GDPN + CVN + PP + DPC + IPC + REGION, data = dat)
# Modèle log-log
dat_log <- dat %>% mutate(lnP = log(P), lnGDPN = log(GDPN), lnCVN = log(CVN))
m_log <- lm(lnP ~ lnGDPN + lnCVN + PP + DPC + IPC, data = dat_log)
el <- coef(m_log)["lnGDPN"]
Retirer la variable POP (non significative) améliore
légèrement le R² ajusté. L’ajout d’une variable factice aléatoire comme
DENS_PHARMA fait artificiellement monter le R² brut,
rappelant ainsi l’importance de s’appuyer sur le R² ajusté et la
pertinence économique pour sélectionner un modèle. Tenter d’ajouter le
PIB en dollars (GDP_USD) génère une colinéarité parfaite,
cette variable n’apportant aucune information nouvelle.
La spécification en logarithmes (modèle log-log) est particulièrement intéressante. Elle permet d’atténuer le problème d’hétéroscédasticité et offre une lecture directe en élasticités : on y trouve une élasticité-revenu du prix de 0,795, significative et positive.
Dans l’ensemble de ces spécifications raisonnables, le coefficient
associé au revenu (GDPN ou son log) demeure positif et
significatif.
En s’appuyant sur ces résultats, les observations semblent étayer la théorie développée par Schut et VanBergeijk quant à la fixation des prix dans ce secteur.
À l’attention du directeur de l’autorité : Stratégie tarifaire de l’industrie pharmaceutique
L’analyse économétrique des données de 1975 portant sur 32 pays suggère que l’industrie pharmaceutique pratique effectivement une forme de discrimination internationale par les prix. En neutralisant les autres effets de marché, on constate qu’un écart d’un point de PNB par habitant par rapport aux États-Unis est associé à une hausse d’environ 1,4 point du prix relatif des médicaments, une relation statistiquement significative. Par ailleurs, les politiques publiques semblent jouer un rôle non négligeable : la mise en place d’un contrôle direct des prix permet de réduire les tarifs relatifs d’environ 15,6 points, ce qui représente un impact économique substantiel. Si notre modèle explique de manière convaincante plus de 80 % de la disparité des prix mondiaux, il convient néanmoins d’aborder ces conclusions avec une certaine prudence. L’étude s’appuie en effet sur un échantillon de taille restreinte où quelques pays pèsent lourdement sur la tendance globale. De plus, la possible simultanéité entre le niveau des prix et les volumes consommés (endogénéité) peut introduire un biais dans l’estimation. Il s’agit donc d’un signal fort en faveur de la présence de discrimination tarifaire, mais qui nécessiterait d’être consolidé par des données actualisées et des méthodes avancées (variables instrumentales) avant toute refonte de notre cadre régulatoire.