Introduction aux mégadonnées en sciences sociales
Université de Montréal
library(ggplot2)
git
?Notre travail
“80% du temps d’analyse de données est consacré au nettoyage et à la préparation des données”
Règle | Description |
---|---|
1️⃣ | Chaque colonne est une variable |
2️⃣ | Chaque ligne est une observation |
3️⃣ | Chaque dataframe est un élément observé |
❌ Données de religion et revenu
religion | <$10k | $10-20k | $20-30k |
---|---|---|---|
Agnostic | 27 | 34 | 60 |
Atheist | 12 | 27 | 37 |
Buddhist | 27 | 21 | 30 |
library(dplyr)
library(tidyr)
df %>%
pivot_longer(
cols = matches("\\$"), # Sélectionne les colonnes contenant "$"
names_to = "revenu",
values_to = "freq"
) %>%
# Optionnel: ordonner les niveaux de revenu
mutate(
revenu = factor(
revenu,
levels = c("<$10k", "$10-20k", "$20-30k"),
ordered = TRUE
)
) %>%
arrange(religion, revenu)
✅ Données de religion et revenu
religion | revenu | freq |
---|---|---|
Agnostic | <$10k | 27 |
Agnostic | $10-20k | 34 |
Agnostic | $20-30k | 60 |
Atheist | <$10k | 12 |
Atheist | $10-20k | 27 |
❌ Données sur la tuberculose
pays | année | m014 | m1524 | m2534 | m3544 |
---|---|---|---|---|---|
AD | 2000 | 0 | 0 | 1 | 0 |
AE | 2000 | 2 | 4 | 4 | 6 |
AF | 2000 | 52 | 228 | 183 | 149 |
df %>%
pivot_longer(
cols = starts_with("m"),
names_to = "groupe",
values_to = "cas"
) %>%
separate(groupe,
into = c("sexe", "age"),
sep = 1,
) %>%
mutate(
sexe = case_when(
sexe == "m" ~ "M",
sexe == "f" ~ "F"
),
age = case_when(
age == "014" ~ "0-14",
age == "1524" ~ "15-24",
age == "2534" ~ "25-34",
age == "3544" ~ "35-44"
)
)
✅ Données sur la tuberculose
pays | année | sexe | groupe_age | cas |
---|---|---|---|---|
AD | 2000 | M | 0-14 | 0 |
AD | 2000 | M | 15-24 | 0 |
AD | 2000 | M | 25-34 | 1 |
AD | 2000 | M | 35-44 | 0 |
AE | 2000 | M | 0-14 | 2 |
❌ Données sur la température au Mexique
id | élément | d1 | d2 | d3 | d4 |
---|---|---|---|---|---|
MX17004 | tmax | NA | 27.3 | 24.1 | NA |
MX17004 | tmin | NA | 14.4 | 14.4 | NA |
✅ Données sur la température au Mexique
id | date | mesure | valeur |
---|---|---|---|
MX17004 | d1 | tmax | NA |
MX17004 | d1 | tmin | NA |
MX17004 | d2 | tmax | 27.3 |
MX17004 | d2 | tmin | 14.4 |
MX17004 | d3 | tmax | 24.1 |
❌ Données sur les chansons et le classement du Billboard
chanson | artiste | durée | rang_sem1 | rang_sem2 |
---|---|---|---|---|
Baby Don’t | 2Pac | 4:22 | 87 | 82 |
Try Again | Aaliyah | 4:03 | 84 | 62 |
# Création des deux tables
# Table 1: Info Chansons
chansons <- df %>%
select(chanson, artiste, durée) %>%
mutate(id_chanson = row_number())
# Table 2: Classements
classements <- df %>%
mutate(id_chanson = row_number()) %>%
pivot_longer(
cols = starts_with("rang_"),
names_to = "semaine",
values_to = "rang",
names_prefix = "rang_sem"
)
✅ Données sur les chansons du Billboard
id_chanson | chanson | artiste | durée |
---|---|---|---|
1 | Baby Don’t | 2Pac | 4:22 |
2 | Try Again | Aaliyah | 4:03 |
✅ Données sur le classement du Billboard
id_chanson | semaine | rang |
---|---|---|
1 | 1 | 87 |
1 | 2 | 82 |
2 | 1 | 84 |
2 | 2 | 62 |
❌ Données médicales
Table 1 - Info Patient:
id_patient | nom | age |
---|---|---|
1 | Alice | 32 |
2 | Bob | 45 |
Table 2 - Mesures:
id_patient | pression | glucose |
---|---|---|
1 | 120/80 | 95 |
2 | 130/85 | 105 |
✅ Données médicales
id_patient | nom | age | mesure | valeur |
---|---|---|---|---|
1 | Alice | 32 | pression | 120/80 |
1 | Alice | 32 | glucose | 95 |
2 | Bob | 45 | pression | 130/85 |
2 | Bob | 45 | glucose | 105 |
La structure tidy facilite l’analyse! 🎯
Ère | années | Échantillonnage | Entrevue | Environnement des données |
---|---|---|---|---|
Première vague | 1930 | Échantillonnage probabiliste par zone | Face à face | Sondage seul |
Deuxième vague | 1950 | Échantillonnage probabiliste par composition aléatoire (RDD) | Téléphone | Sondage seul |
Troisième vague | 2000 | Échantillonnage non-probabiliste | Ordinateur | Sondages liées aux sources de mégadonnées |
Le résultat?
Imaginons un sondage sur la satisfaction des repas :
Âge | Sondage (%) | Sondage (n) | Recensement (%) | Population (n) | Poids |
---|---|---|---|---|---|
18-34 | 20% | 200 | 30% | 300,000 | 1.5 |
35-64 | 45% | 450 | 45% | 450,000 | 1.0 |
65+ | 35% | 350 | 25% | 250,000 | 0.71 |
Total | 100% | 1,000 | 100% | 1,000,000 | - |
# Exemple avec une régression linéaire
# Opinion sur échelle 0-10 selon l'âge et le revenu
model <- lm(opinion ~ revenu,
data = df,
weights = poids) # Ajouter les poids ici
# Voir les résultats
summary(model)
Le premier demande:
“Est-ce que c’est permis de fumer pendant qu’on prie?”
→ Non! C’est un péché
Le deuxième demande:
“Est-ce que c’est permis de prier pendant qu’on fume?”
→ Oui! Bien sûr
Point méthodologique
La façon dont on formule une question peut drastiquement influencer la réponse obtenue!
Version A:
“How much do you agree: Individuals are more to blame than social conditions for crime and lawlessness in this country.”
→ Résultat: ~60% blâment les individus
Version B:
“How much do you agree: Social conditions are more to blame than individuals for crime and lawlessness in this country.”
→ Résultat: ~60% blâment les conditions sociales
Avertissement
Même question avec ordre inversé = conclusions opposées!
CPSIGEN | CPSA3 | CPSG1 | CPSO11 | CPSA2 |
---|---|---|---|---|
5 | 1 | 7 | 1 | 1 |
5 | 2 | 5 | 1 | 1 |
5 | 99 | 7 | 1 | 1 |
1 | 2 | 7 | 1 | 1 |
5 | 1 | 3 | 1 | 1 |
1 | 2 | 5 | 1 | 1 |
ses_gender | ses_born_canada | vote_intention | vote_probability_to_vote | issue_gst_opposed |
---|---|---|---|---|
female | 1 | cpc | 1 | 1.00 |
female | 1 | lpc | 1 | 0.67 |
female | 1 | NA | 1 | 1.00 |
male | 1 | lpc | 1 | 1.00 |
female | 1 | cpc | 1 | 0.33 |
male | 1 | lpc | 1 | 0.67 |
library(dplyr)
df_raw <- read.csv("data/ces/1993/raw/CES-E-1993_F1_subset.csv")
df_clean <- data.frame(id = 1:nrow(df_raw))
#------------------------------------------------------------------------------#
# VARIABLE : CPSG1 - GST opposition
# Question : In 1991 the Federal government adopted a new tax on goods and
# services, the GST. All things considered, are you VERY MUCH IN FAVOUR,
# SOMEWHAT IN FAVOUR, SOMEWHAT OPPOSED, or VERY MUCH OPPOSED to the GST?
# Codage : 1 = Opposed, 0 = Favour
#------------------------------------------------------------------------------#
table(df_raw$CPSG1, useNA = "ifany")
df_clean$issue_gst_opposed <- NA
df_clean$issue_gst_opposed[df_raw$CPSG1 == 1] <- 0
df_clean$issue_gst_opposed[df_raw$CPSG1 == 3] <- 0.33
df_clean$issue_gst_opposed[df_raw$CPSG1 == 5] <- 0.67
df_clean$issue_gst_opposed[df_raw$CPSG1 == 7] <- 1
table(df_clean$issue_gst_opposed, useNA = "ifany")
write.csv(df_clean, "data/ces/1993/ces93_clean.csv", row.names = FALSE)
1️⃣ Nouvelle variable : df_clean$issue_gst_opposed
df_clean
issue_gst_opposed
2️⃣ Condition de sélection : [df_raw$CPSG1 == 1]
df_raw
CPSG1
3️⃣ Attribution : <- 0
<-
0
“Pour toutes les observations où
CPSG1
égale 1 dansdf_raw
,
assigner la valeur 0 à la variableissue_gst_opposed
dansdf_clean
”
Comment pondérer?
La formule de base
Pour notre exemple
En pratique