Afficher le code R
2 + 2[1] 4
Afficher le code R
5 * 4[1] 20
Afficher le code R
(10 - 2) / 4[1] 2
Comment passer d’une question simple — par exemple « quel est l’âge moyen des personnes interrogées ? » — à une instruction R que l’on peut relire, vérifier et reproduire ?
À la fin de ce chapitre, vous saurez :
data.frame, un tibble, un facteur et une liste ;|> pour écrire une suite d’opérations lisible ;package::fonction() ;Ce chapitre ne suppose aucune expérience de programmation. Les notions de variable, modalité, observation et fichier de données ont été introduites au chapitre 1.
R est à la fois un langage de programmation et un environnement de calcul statistique libre (R Core Team 2026). Il reçoit des instructions, crée des objets, transforme des données, estime des modèles et produit des graphiques. RStudio est un environnement de développement intégré (Integrated Development Environment, IDE) qui facilite l’écriture, l’exécution et l’organisation du code R (Posit Software, PBC 2026).
Cette distinction est importante : RStudio n’est pas R. Fermer RStudio n’efface pas R de l’ordinateur ; installer RStudio sans R ne suffit pas pour travailler ; et un script R reste du code R même s’il est exécuté depuis un autre environnement.
| R | RStudio | |
|---|---|---|
| Rôle | langage et moteur de calcul | environnement de travail |
| Exécute les calculs | oui | transmet les instructions à R |
| Contient les fonctions statistiques | oui | non, sauf fonctions liées à l’IDE |
| Édite les scripts | possible mais rudimentaire | oui, avec autocomplétion et outils de navigation |
| Gère projets, Git, terminal, aperçu Quarto | non directement | oui |
Une formule simple est utile au début : R calcule ; RStudio aide à travailler avec R.
L’interface classique de RStudio est organisée autour de quatre zones principales, dont la disposition peut être personnalisée (Posit Software, PBC 2026) :
.R, documents .qmd et autres fichiers texte ;Au début, la console attire naturellement l’attention car elle répond immédiatement. Pourtant, une analyse sérieuse doit être conservée dans un fichier source. Une commande uniquement saisie dans la console peut être oubliée ; une commande enregistrée dans un script peut être relue, modifiée et réexécutée.
La console est très utile pour tester une idée ou vérifier rapidement un objet. Elle ne doit pas devenir l’unique trace de l’analyse. Les traitements importants doivent être écrits dans un script .R ou un document Quarto .qmd.
R peut être utilisé comme une calculatrice :
2 + 2[1] 4
5 * 4[1] 20
(10 - 2) / 4[1] 2
Une instruction est exécutée lorsque l’on appuie sur Entrée dans la console. Depuis un script, le raccourci Ctrl + Entrée (ou Cmd + Entrée sous macOS) envoie la ligne ou la sélection courante vers la console.
> et le prompt +La console affiche généralement > lorsqu’elle attend une nouvelle instruction. Si une instruction est incomplète, elle peut afficher + :
mean(c(10, 12, 14R attend ici la fermeture des parenthèses. Ce n’est pas nécessairement une panne : l’expression n’est simplement pas terminée. Appuyer sur Esc permet d’annuler une instruction en cours.
Une analyse devient intéressante lorsque l’on conserve des résultats dans des objets. L’opérateur d’affectation usuel est <- :
age_moyen <- 46.2
age_moyen[1] 46.2
La première ligne signifie : « créer l’objet age_moyen et lui attribuer la valeur 46.2 ». La seconde demande à R d’afficher cet objet.
On peut utiliser un objet dans un calcul :
age_moyen + 1[1] 47.2
et créer un objet à partir d’autres objets :
n_femmes <- 1820
n_hommes <- 1710
n_total <- n_femmes + n_hommes
n_total[1] 3530
Un nom d’objet doit aider à comprendre le code. Préférer :
age_moyen
revenu_median
enquete_bruteà :
x
res2
data_final_final2Dans ce livre, nous utilisons principalement le snake_case : des mots en minuscules séparés par des _. La cohérence stylistique réduit l’effort de lecture (Tidyverse Team 2026).
Un bon nom décrit ce que contient l’objet, pas la fonction qui a servi à le produire. age_moyen est généralement plus informatif que resultat_mean.
Une grande partie de R repose sur les vecteurs. Un vecteur atomique contient plusieurs valeurs d’un même type.
ages <- c(23, 35, 42, 51)
ages[1] 23 35 42 51
c() signifie ici combine : elle combine plusieurs valeurs en un vecteur.
On peut appliquer une opération à toutes les valeurs :
ages + 1[1] 24 36 43 52
ages > 40[1] FALSE FALSE TRUE TRUE
La seconde instruction renvoie un vecteur logique composé de TRUE et FALSE.
Cette logique vectorisée est fondamentale : il est rarement nécessaire d’écrire une boucle pour ajouter 1 à chaque âge ou tester chaque observation une par une.
Les crochets [] permettent de sélectionner des positions :
ages[1][1] 23
ages[c(1, 3)][1] 23 42
R compte à partir de 1. Le premier élément est donc ages[1], pas ages[0].
On peut également utiliser une condition logique :
ages[ages >= 40][1] 42 51
Cette instruction se lit : « parmi ages, garder les valeurs pour lesquelles ages >= 40 est vrai ».
Dans une enquête, des valeurs visuellement proches peuvent avoir des significations très différentes. R distingue notamment :
| Type / classe courante | Exemple | Usage typique |
|---|---|---|
double / numeric |
46.5 |
âge, revenu, score |
integer |
46L |
compte, code entier |
character |
"Femme" |
texte, modalités non converties |
logical |
TRUE, FALSE |
indicateur logique |
factor |
modalités + niveaux | variable catégorielle |
Date |
2026-08-14 |
date d’entretien |
NA |
valeur manquante | absence de valeur exploitable |
x <- 46
class(x)[1] "numeric"
typeof(x)[1] "double"
typeof() renseigne sur le type interne ; class() renseigne sur la classe utilisée par les méthodes de haut niveau. Pour débuter, class() et les fonctions is.*() suffisent souvent :
is.numeric(x)[1] TRUE
is.character(x)[1] FALSE
Considérons un niveau de diplôme codé :
diplome_code <- c(1, 3, 4, 2, 4)
mean(diplome_code)[1] 2.8
R peut calculer une moyenne parce que les valeurs sont numériques. Cela ne signifie pas que cette moyenne ait une interprétation substantielle. La nature statistique d’une variable ne se déduit donc pas uniquement de son type informatique.
Ce principe sera central au chapitre 5 : il faudra toujours distinguer :
Si 1 = sans diplôme, 2 = secondaire, 3 = supérieur, R voit des nombres. Le chercheur doit, lui, voir une variable catégorielle ordonnée. Un calcul techniquement possible n’est pas automatiquement un calcul scientifiquement pertinent.
Un factor est une structure conçue pour des catégories. Il associe des valeurs observées à un ensemble de niveaux (levels).
sexe <- factor(c("Femme", "Homme", "Femme", "Homme"))
sexe[1] Femme Homme Femme Homme
Levels: Femme Homme
levels(sexe)[1] "Femme" "Homme"
Pour une variable ordinale, on peut indiquer un ordre :
sante <- factor(
c("Bonne", "Moyenne", "Très bonne", "Mauvaise"),
levels = c("Mauvaise", "Moyenne", "Bonne", "Très bonne"),
ordered = TRUE
)Il ne faut pas confondre un facteur R avec une variable haven_labelled importée depuis SPSS, Stata ou SAS. Ces structures seront étudiées en détail au chapitre 5.
as.numeric() sur un facteurniveau <- factor(c("Faible", "Moyen", "Élevé"))
as.numeric(niveau)[1] 2 3 1
Le résultat correspond aux codes internes des niveaux, pas à une mesure numérique de « faible », « moyen » et « élevé ». Si l’objectif est de récupérer les libellés, on utilise plutôt :
as.character(niveau)[1] "Faible" "Moyen" "Élevé"
Un facteur n’est pas du texte enrichi d’une moyenne possible. C’est une représentation de catégories dont l’ordre, les niveaux et la catégorie de référence peuvent jouer un rôle analytique.
NA : la valeur manquante de RR représente généralement une valeur manquante par NA.
revenus <- c(1800, 2400, NA, 3100)
mean(revenus)[1] NA
Par défaut, mean() renvoie ici NA, car la moyenne dépend d’une valeur inconnue. Lorsque la fonction le permet, on peut demander d’ignorer les valeurs manquantes :
mean(revenus, na.rm = TRUE)[1] 2433.333
Mais na.rm = TRUE ne « règle » pas le problème méthodologique des données manquantes : il modifie seulement le calcul. Le chapitre 7 sera entièrement consacré à leur signification et à leur traitement.
Pour détecter les valeurs manquantes :
is.na(revenus)[1] FALSE FALSE TRUE FALSE
sum(is.na(revenus))[1] 1
Éviter :
revenus == NAUne valeur manquante n’est pas une valeur ordinaire que l’on peut comparer avec ==.
data.frame et tibble : les tableaux de donnéesUne enquête est généralement représentée dans R par un tableau rectangulaire : une ligne par unité d’observation, une colonne par variable. Un data.frame est la structure historique de base R ; un tibble est une variante moderne utilisée dans le tidyverse (Wickham et al. 2023, 2019).
Créons un mini-fichier pédagogique :
enquete_demo <- data.frame(
id = 1:5,
sexe = c("Femme", "Homme", "Femme", "Homme", "Femme"),
age = c(22, 41, 36, 58, 29),
sport = c(TRUE, FALSE, TRUE, FALSE, TRUE)
)
enquete_demo id sexe age sport
1 1 Femme 22 TRUE
2 2 Homme 41 FALSE
3 3 Femme 36 TRUE
4 4 Homme 58 FALSE
5 5 Femme 29 TRUE
Quelques fonctions essentielles :
dim(enquete_demo)[1] 5 4
nrow(enquete_demo)[1] 5
ncol(enquete_demo)[1] 4
names(enquete_demo)[1] "id" "sexe" "age" "sport"
str(enquete_demo)'data.frame': 5 obs. of 4 variables:
$ id : int 1 2 3 4 5
$ sexe : chr "Femme" "Homme" "Femme" "Homme" ...
$ age : num 22 41 36 58 29
$ sport: logi TRUE FALSE TRUE FALSE TRUE
Avec {dplyr}, glimpse() donne une vue compacte :
# install.packages("dplyr") # une seule fois sur votre machine
library(dplyr)
glimpse(enquete_demo)Rows: 5
Columns: 4
$ id <int> 1, 2, 3, 4, 5
$ sexe <chr> "Femme", "Homme", "Femme", "Homme", "Femme"
$ age <dbl> 22, 41, 36, 58, 29
$ sport <lgl> TRUE, FALSE, TRUE, FALSE, TRUE
$enquete_demo$age[1] 22 41 36 58 29
mean(enquete_demo$age)[1] 37.2
La notation $ est pratique pour une manipulation ponctuelle. Dans les pipelines dplyr, nous utiliserons généralement directement les noms de colonnes.
Une liste peut contenir des éléments de natures différentes :
resultat <- list(
moyenne = 37.2,
variable = "age",
effectif = 5,
valeurs = c(22, 41, 36, 58, 29)
)
resultat$moyenne
[1] 37.2
$variable
[1] "age"
$effectif
[1] 5
$valeurs
[1] 22 41 36 58 29
resultat$moyenne[1] 37.2
Cette structure peut sembler abstraite au début, mais de nombreux résultats R — modèles, tests, objets de design d’enquête — sont des objets complexes proches de listes. Savoir qu’un résultat contient plusieurs composantes aidera plus tard à comprendre pourquoi l’on peut écrire, par exemple, modele$coefficients.
Une fonction reçoit des arguments, effectue une opération et renvoie un résultat.
mean(c(10, 12, 14))[1] 12
Ici :
mean est le nom de la fonction ;c(10, 12, 14) est un argument ;Une même fonction accepte souvent plusieurs arguments :
round(3.14159, digits = 2)[1] 3.14
digits = 2 précise le nombre de décimales.
round(3.14159, 2)[1] 3.14
round(x = 3.14159, digits = 2)[1] 3.14
Les deux lignes produisent le même résultat. Dans un code pédagogique ou lorsque plusieurs arguments sont possibles, les noms rendent souvent l’intention plus explicite.
?mean
help("mean")La documentation indique notamment l’usage de la fonction, ses arguments et souvent des exemples. Pour rechercher un terme lorsque l’on ne connaît pas la fonction :
help.search("median")Un code trouvé en ligne peut correspondre à une ancienne version d’un package ou à une situation différente. Vérifier ?fonction permet de voir quels arguments votre version installée accepte réellement.
|> : écrire une suite d’opérationsLe pipe natif de R, |>, transmet le résultat d’une expression à l’étape suivante. Cette écriture se rapproche de la logique d’un workflow :
enquete_demo |>
dplyr::filter(age >= 30) |>
dplyr::summarise(age_moyen = mean(age)) age_moyen
1 45
Cette instruction se lit de haut en bas :
enquete_demo ;Dans de nombreux anciens scripts et de nombreuses ressources, vous rencontrerez également %>%, le pipe popularisé par {magrittr} et très utilisé avec le tidyverse :
enquete_demo %>%
filter(age >= 30) %>%
summarise(age_moyen = mean(age))Les deux écritures sont proches pour les usages simples. Dans ce livre, nous privilégions |> lorsque rien ne justifie une syntaxe spécifique à %>%.
R de base contient déjà de nombreuses fonctions. Les packages ajoutent des fonctions, jeux de données et méthodes spécialisées.
install.packages("dplyr")Cette commande télécharge et installe le package. Elle ne doit pas être répétée dans chaque script d’analyse.
library(dplyr)Une fois chargé, les fonctions exportées du package peuvent être appelées directement :
filter(enquete_demo, age >= 30) id sexe age sport
1 2 Homme 41 FALSE
2 3 Femme 36 TRUE
3 4 Homme 58 FALSE
package::fonction()On peut appeler une fonction sans charger tout le package :
dplyr::filter(enquete_demo, age >= 30) id sexe age sport
1 2 Homme 41 FALSE
2 3 Femme 36 TRUE
3 4 Homme 58 FALSE
Cette écriture est particulièrement utile :
Le tidyverse rassemble plusieurs packages cohérents, notamment {dplyr}, {tidyr}, {readr}, {ggplot2}, {forcats} et {purrr} (Wickham et al. 2019). Nous les introduirons progressivement plutôt que de charger des dizaines de packages sans expliquer leur rôle.
install.packages("dplyr") installe le package sur la machine. library(dplyr) le rend disponible dans la session courante. Un script partagé contient généralement les library() nécessaires, pas une série de install.packages() exécutée à chaque lancement.
Leur usage détaillé viendra dans les chapitres suivants, mais cinq verbes {dplyr} suffisent déjà à comprendre une grande partie des scripts d’analyse (Wickham et al. 2026) :
| Verbe | Question | Exemple |
|---|---|---|
select() |
quelles colonnes garder ? | select(age, sexe) |
filter() |
quelles lignes garder ? | filter(age >= 30) |
mutate() |
quelle variable créer/modifier ? | mutate(age2 = age^2) |
arrange() |
dans quel ordre afficher ? | arrange(age) |
summarise() |
quelle synthèse calculer ? | summarise(m = mean(age)) |
Exemple :
enquete_demo |>
dplyr::filter(age >= 30) |>
dplyr::select(id, sexe, age) |>
dplyr::arrange(age) id sexe age
1 3 Femme 36
2 2 Homme 41
3 4 Homme 58
Le but n’est pas encore de mémoriser toute la syntaxe. Il s’agit de reconnaître une logique : un tableau entre, une transformation est effectuée, un nouvel objet ou un résultat sort.
Créons un petit script mentalement divisé en sections :
# 01_demo.R
# Packages ----
library(dplyr)
# Données ----
enquete_demo <- data.frame(
id = 1:5,
sexe = c("Femme", "Homme", "Femme", "Homme", "Femme"),
age = c(22, 41, 36, 58, 29)
)
# Analyse ----
resume_age <- enquete_demo |>
summarise(
n = n(),
age_moyen = mean(age),
age_median = median(age)
)
resume_ageCe script permet de recréer l’objet et le résultat depuis une session vide. C’est un critère simple mais puissant : si l’on redémarre R et que l’on exécute le script dans l’ordre, retrouve-t-on le résultat ?
Le chapitre 3 montrera comment étendre cette logique à un projet entier.
Un message d’erreur n’est pas un verdict sur les capacités de l’utilisateur. C’est une information sur l’endroit où l’exécution ne peut pas continuer.
Considérons :
mean(enquete_demo$ages)La colonne s’appelle age, pas ages. Selon le contexte, R peut renvoyer un message indiquant qu’il ne trouve pas l’objet ou produire un résultat inattendu à partir d’une colonne absente. Le premier réflexe est de vérifier les noms :
names(enquete_demo)[1] "id" "sexe" "age" "sport"
exists("nom"), names(data) ou ls() peuvent aider.class(), str() ou glimpse().Error) interrompt l’instruction courante ;Warning) signale un problème potentiel mais un résultat peut avoir été produit ;Ignorer systématiquement les avertissements est une mauvaise habitude. Les masquer dans un document final peut être pertinent après vérification, mais il faut d’abord comprendre leur cause.
Lorsqu’un pipeline de dix lignes échoue, exécuter les étapes une à une permet souvent d’identifier très vite l’opération fautive.
Créons un jeu un peu plus long :
enquete_demo2 <- data.frame(
id = 1:8,
sexe = c("Femme", "Homme", "Femme", "Homme", "Femme", "Homme", "Femme", "Homme"),
age = c(22, 41, 36, 58, 29, 47, 65, 33),
satisfaction = c(8, 6, 7, 5, 8, 6, NA, 7)
)Inspectons :
glimpse(enquete_demo2)Rows: 8
Columns: 4
$ id <int> 1, 2, 3, 4, 5, 6, 7, 8
$ sexe <chr> "Femme", "Homme", "Femme", "Homme", "Femme", "Homme", "Fe…
$ age <dbl> 22, 41, 36, 58, 29, 47, 65, 33
$ satisfaction <dbl> 8, 6, 7, 5, 8, 6, NA, 7
Puis calculons une synthèse :
resume_demo <- enquete_demo2 |>
summarise(
n = n(),
age_moyen = mean(age),
satisfaction_moyenne = mean(satisfaction, na.rm = TRUE),
n_satisfaction_manquante = sum(is.na(satisfaction))
)
resume_demo n age_moyen satisfaction_moyenne n_satisfaction_manquante
1 8 41.375 6.714286 1
Ce pipeline permet déjà d’exercer plusieurs compétences :
data.frame ;summarise() transforme plusieurs lignes en une ligne de résultats ;n() compte les lignes ;mean() calcule une moyenne ;na.rm = TRUE retire les NA du calcul de moyenne ;is.na() produit des TRUE/FALSE et sum() compte les TRUE.Le point important est moins la valeur numérique que la capacité à expliquer comment elle a été obtenue.
Créez trois objets :
n_repondants contenant 3600 ;titre_enquete contenant "EnquêteR" ;analyse_terminee contenant FALSE.Affichez ensuite leur classe avec class().
n_repondants <- 3600
titre_enquete <- "EnquêteR"
analyse_terminee <- FALSE
class(n_repondants)[1] "numeric"
class(titre_enquete)[1] "character"
class(analyse_terminee)[1] "logical"
On obtient typiquement numeric, character et logical. La classe décrit ici la façon dont R représente l’information, pas sa signification scientifique.
À partir de :
score <- c(4, 5, NA, 3, 5, NA)calculez le nombre de valeurs manquantes puis la moyenne des réponses disponibles.
sum(is.na(score))[1] 2
mean(score, na.rm = TRUE)[1] 4.25
Il y a deux valeurs manquantes. na.rm = TRUE permet de calculer la moyenne sur les quatre valeurs observées, mais cette décision n’explique pas pourquoi les deux réponses manquent.
Avec enquete_demo2, gardez les personnes de 40 ans ou plus et calculez leur âge médian.
enquete_demo2 |>
filter(age >= 40) |>
summarise(age_median = median(age)) age_median
1 52.5
On filtre d’abord les lignes, puis on résume le sous-ensemble obtenu. L’ordre des opérations fait partie du sens du calcul.
Créez le tableau suivant :
mini <- data.frame(
id = 1:6,
age = c(20, 24, 37, 45, 51, 63),
emploi = c(TRUE, FALSE, TRUE, TRUE, FALSE, FALSE)
)age et de emploi ;Vous recevez un objet nommé enquete, mais mean(enquete$diplome) renvoie un résultat numérique qui vous semble étrange. Quelles vérifications effectuez-vous avant d’interpréter cette moyenne ? Proposez au moins trois commandes R et expliquez leur utilité.
À partir de enquete_demo2, produisez en quelques lignes un résumé qui contient :
satisfaction ;satisfaction parmi les réponses observées.Rédigez ensuite deux phrases expliquant précisément ce que vous avez calculé et ce que la présence de valeurs manquantes vous empêche encore de conclure.
mini <- data.frame(
id = 1:6,
age = c(20, 24, 37, 45, 51, 63),
emploi = c(TRUE, FALSE, TRUE, TRUE, FALSE, FALSE)
)
dim(mini)[1] 6 3
class(mini$age)[1] "numeric"
class(mini$emploi)[1] "logical"
mean(mini$age)[1] 40
sum(mini$emploi)[1] 3
sum(mini$emploi) fonctionne parce que, dans ce contexte, TRUE est compté comme 1 et FALSE comme 0. Pour un lecteur débutant, sum(mini$emploi) reste lisible si l’objet est clairement logique ; sum(mini$emploi == TRUE) serait plus explicite mais redondant.
Une démarche possible :
class(enquete$diplome)
table(enquete$diplome, useNA = "ifany")
str(enquete$diplome)On peut également consulter la documentation de l’enquête ou le dictionnaire de variables. Si diplome est un code numérique pour des catégories, une moyenne des codes n’a généralement pas l’interprétation d’une moyenne quantitative. Le point essentiel est de ne pas laisser la possibilité technique du calcul se substituer à la définition substantielle de la variable.
resume <- enquete_demo2 |>
summarise(
n = n(),
age_moyen = mean(age),
age_min = min(age),
age_max = max(age),
n_satisfaction_manquante = sum(is.na(satisfaction)),
satisfaction_moyenne = mean(satisfaction, na.rm = TRUE)
)
resume n age_moyen age_min age_max n_satisfaction_manquante satisfaction_moyenne
1 8 41.375 22 65 1 6.714286
Une formulation correcte pourrait être : « Le tableau contient huit observations. La satisfaction moyenne est calculée uniquement parmi les réponses non manquantes. » La présence d’un NA ne permet pas, à elle seule, de savoir si la non-réponse est aléatoire ou liée au niveau de satisfaction ; cette question sera traitée au chapitre 7.
<- crée ou met à jour un objet.NA représente une valeur manquante et nécessite des fonctions adaptées comme is.na().data.frame ou un tibble représente naturellement un fichier d’enquête rectangulaire.|> rend lisible une chaîne d’opérations successives.La documentation officielle de R constitue la référence du langage (R Core Team 2026). Le guide de l’IDE RStudio détaille l’interface et les outils de développement (Posit Software, PBC 2026). Pour approfondir la logique de manipulation des données, R for Data Science propose une présentation progressive du workflow tidyverse (Wickham et al. 2023).
Le prochain chapitre ne cherchera pas à ajouter de nouvelles fonctions statistiques. Il répondra à une question plus fondamentale : comment organiser un projet pour que le même code retrouve les mêmes fichiers et puisse être réexécuté plusieurs mois plus tard ?