Bases de R
Contexte
Matière : _Analyse probabiliste de données · Prof : F. Corset · Type : TP1 Source : TP1 — Introduction à R
🎯 Objectifs de la séance
- Prendre en main RStudio et la logique de script
- Maîtriser les types de base et les structures de données (vecteur, liste, matrice, data.frame)
- Comprendre l’indexation et le filtrage, qui sont le cœur de R
- Écrire ses propres fonctions et simuler de l’aléatoire
🧠 Notions clés
- Tout est vecteur : un scalaire est un vecteur de longueur 1. Les opérations sont vectorisées — pas besoin de boucle pour appliquer un calcul à tout un vecteur.
- Indexation à partir de 1 (pas 0 comme en C/Java/Python).
- Indice négatif = exclusion, pas « compter depuis la fin ».
- Auto-conversion (coercition) : un vecteur n’a qu’un seul type ; R promeut tout vers le type le plus général.
- Recycling : un vecteur trop court est répété pour atteindre la longueur voulue.
- Structures : vecteur (1 type, plat) → matrice (1 type, 2D) → data.frame (1 type par colonne) → liste (tout type, hétérogène).
📝 Cours
1. RStudio — les 4 fenêtres
| Fenêtre | Rôle |
|---|---|
| Édition | Écriture des scripts .R — exécution avec Ctrl+Entrée |
| Console | Exécution directe, tests rapides |
| Environnement / Historique | Variables en mémoire, commandes passées |
| Explorateur / Graphiques / Packages / Aide | Fichiers, plots, doc |
Bonne pratique
Travailler dans un script (
TP1.R) et pas dans la console : commenter chaque ligne avec#. La console ne garde rien de reproductible.
2. R comme super-calculateur
5*(-3.2) # -16
5^2 # 25
5**2 # 25 (équivalent, mais 5^2 est la forme idiomatique)
sin(2*pi/3) # 0.8660254
sqrt(3)/2 # 0.8660254 <- même valeur, vérification numérique
log(exp(1)) # 1 (log = népérien par défaut)
log(1) # 03. Affectation et types
x <- 1 # affectation (flèche = idiomatique en R)
x # [1] 1
2*x # [1] 2Le
[1]en sortieCe n’est pas la valeur : c’est l’indice du premier élément affiché sur la ligne. Sur un long vecteur, chaque ligne commence par l’indice de son premier élément.
Chaînes — guillemets simples ou doubles, indifférent :
ch <- "Voici une chaîne"
(ch <- 'Voici une chaîne') # les parenthèses = affecte ET afficheNumérique vs entier :
(nb <- 101) # numeric (double)
(nb2 <- 101L) # integer — le suffixe L force l'entier
nb == nb2 # TRUE <- égalité de valeur
identical(nb,nb2) # FALSE <- mais types différents !Piège d'examen
==compare les valeurs (avec conversion),identical()compare valeur ET type. C’est la distinction classiquement demandée.
Valeurs spéciales :
| Valeur | Sens |
|---|---|
TRUE / FALSE (ou T / F) | Booléens |
NA | Donnée manquante (Not Available) |
NaN | Résultat indéfini (Not a Number), ex. 0/0 |
Inf / -Inf | Infini, ex. 1/0 |
1+2i | Complexe |
rm(ch, nb, nb2, a) # supprime des variables de l'environnement4. Vecteurs
Création :
c(1,2,3,4,5) # [1] 1 2 3 4 5 — c = "combine"
c(1:5) # [1] 1 2 3 4 5
1:10 # séquence entière
seq(1,10) # idem
seq(0,20,1.3) # séquence à pas choisi (1.3)
rep(2,3) # [1] 2 2 2
rep(1:2,3) # [1] 1 2 1 2 1 2 — répète le motif 3 fois
rep(1:2,2:3) # [1] 1 1 2 2 2 — répète 1 deux fois, 2 trois foisVecteurs typés vides / initialisés :
logical(2) # [1] FALSE FALSE
integer(1) # [1] 0
numeric() # numeric(0) — vecteur vide
character(3) # [1] "" "" ""Indexation et filtrage — le cœur du TP :
z <- seq(0,20,1.3)
z[8] # 8e élément -> 9.1
z[-8] # TOUT SAUF le 8e
z[1:8] # les 8 premiers
z[-(1:8)] # tout sauf les 8 premiers
z[9:length(z)] # du 9e au dernier
z[c(2,6,14)] # éléments 2, 6 et 14
z[z>10] # FILTRAGE : les éléments > 10
z[z>4 & z<15] # & = ET logique, | = OU logiqueIndice négatif
z[-8]exclut l’élément 8. Ce n’est pas « le 8e depuis la fin » comme en Python. Pour le dernier élément :z[length(z)].
Trois façons d’indexer :
v <- c(1,3,2)
v[c(1,3)] # par POSITION -> 1 2
v[c(TRUE,FALSE,TRUE)] # par MASQUE logique -> 1 2
v %in% c(1,2) # [1] TRUE FALSE TRUE — test d'appartenance
v[v %in% c(1,2)] # par APPARTENANCE -> 1 2Coller des chaînes :
paste(c("toto","tutu"), 1:2) # "toto 1" "tutu 2" (sep=" " par défaut)
paste(c("toto","tutu"), 1:2, sep="") # "toto1" "tutu2"
paste(c("toto","tutu"), 1:2, collapse=" & ") # "toto 1 & tutu 2" (UNE seule chaîne)
sepvscollapse
sep= colle les arguments entre eux, élément par élément (résultat : un vecteur).collapse= aplatit ensuite le vecteur résultat en une seule chaîne.
5. Listes
Une liste est un conteneur hétérogène : chaque élément peut avoir un type et une longueur différents.
(l <- list(1:10, c("toto","titi"))) # éléments anonymes -> [[1]], [[2]]
(l2 <- list(a=1:10, b=c("toto","titi"))) # éléments nommés -> $a, $b
c(l, l2) # fusionne deux listes
names(l2) # [1] "a" "b"Extraction :
l2[[1]] # par indice -> le CONTENU (vecteur 1:10)
l2$a # par nom, mode "utilisateur"
l2[["a"]] # par nom, mode "développeur"
cle <- "a"
l2[[cle]] # OK -> évalue la variable cle, donc l'élément "a"
l2$cle # NULL -> $ ne fait PAS d'évaluation, il cherche un élément nommé "cle"
[ ]vs[[ ]]— piège classique
l2[1]renvoie une sous-liste (structure conservée).l2[[1]]renvoie le contenu de l’élément. Quand on veut travailler sur les données, c’est presque toujours[[ ]]ou$. Et pour indexer par une variable, il faut[[ ]]—$ne marche pas.
l2[1] # sous-liste contenant $a
l2[c(2,1)] # sous-liste réordonnée6. Matrices
A <- matrix(1:12, nrow=4, ncol=3, byrow=TRUE) # remplit LIGNE par ligne
B <- matrix(1:12, nrow=4, ncol=3) # remplit COLONNE par colonne (défaut)
t(A) # transposée
A[2,3] # élément ligne 2, colonne 3
A[,3] # toute la colonne 3
A[,c(1,3)] # colonnes 1 et 3
t(B) %*% A # produit MATRICIEL (%*%), à ne pas confondre avec * (terme à terme)
byrowPar défaut R remplit par colonnes.
byrow=TRUEchange tout le résultat — erreur fréquente.
*vs%*%
A * B= produit terme à terme.A %*% B= produit matriciel au sens algébrique.
7. Auto-conversion (coercition)
Un vecteur ne contient qu’un seul type. R promeut silencieusement selon la hiérarchie :
logical → integer → numeric → character
a <- c(TRUE, 2L)
a ; class(a) # [1] 1 2 "integer" (TRUE devient 1)
a <- c(a, 3)
a ; class(a) # [1] 1 2 3 "numeric"
a <- c(a, "quatre")
a ; class(a) # "1" "2" "3" "quatre" "character"Danger silencieux
Un seul texte dans une colonne de nombres transforme tout en
character— et les calculs échouent ensuite. C’est la cause n°1 de bugs après un import de fichier.
Vecteur → liste :
c(l, v) # équivalent à c(l, as.list(v)) : chaque élément de v devient un élément de liste8. Recycling
Si un vecteur est trop court, R le répète jusqu’à la longueur nécessaire.
(1:8)[c(TRUE,FALSE)] # [1] 1 3 5 7 — motif TF recyclé 4 fois
(1:9)[c(TRUE,FALSE)] # [1] 1 3 5 7 9 — recyclage incomplet, mais toléré
(1:8)[c(TRUE,FALSE,FALSE)] # [1] 1 4 7 — un sur trois
cbind(1:5, c(TRUE,FALSE,FALSE))
# [,1] [,2]
# [1,] 1 1
# [2,] 2 0
# [3,] 3 0
# [4,] 4 1 <- le motif a rebouclé ici
# [5,] 5 0Deux pièges
- Le recycling est silencieux quand la longue est un multiple de la courte — sinon simple warning, pas d’erreur. Un bug peut passer inaperçu.
- Le recycling ne s’applique pas aux data.frames.
9. data.frame — le tableau individus × variables
C’est la structure de l’analyse de données : une ligne = un individu, une colonne = une variable. Chaque colonne a son propre type (contrairement à la matrice).
IMC <- data.frame(
Sexe = c("H","F","H","F"),
Taille = c(1.83,1.76,1.82,1.60),
Poids = c(67,58,66,48),
row.names = c("Pierre","Valérie","Paul","Virginie")
)À connaître pour explorer un data.frame : str(), summary(), head(), nrow(), ncol(), dim(), names().
10. Facteurs et variables ordinales
Un facteur encode une variable qualitative : R stocke des niveaux (levels) et non du texte libre.
x <- factor(c("bleu","vert","bleu","rouge","bleu","vert","vert"))
x # Levels: bleu rouge vert (ordre ALPHABÉTIQUE par défaut)
levels(x) # [1] "bleu" "rouge" "vert"
class(x) # [1] "factor"Variable ordinale — quand les modalités ont un ordre naturel :
z <- ordered(
c("Petit","Grand","Moyen","Grand","Moyen","Petit","Petit"),
levels = c("Petit","Moyen","Grand") # on IMPOSE l'ordre
)
class(z) # [1] "ordered" "factor"
z # Levels: Petit < Moyen < GrandPourquoi ça compte
Sans
levels=, R trie par ordre alphabétique — « Grand < Moyen < Petit », ce qui n’a aucun sens. Le type conditionne aussi les tests statistiques et les graphiques applicables.
11. Écrire ses fonctions
Hello <- function() {
cat("Hello World", "\n")
}
Hello()
Bonjour <- function(x) {
cat("Bonjour", x, "\n")
}
Bonjour("et bon TP")
cat()vsprint()
cat()affiche du texte brut (sans le[1], sans les guillemets) — pour un message.print()affiche la représentation R de l’objet — pour inspecter. Une fonction R renvoie automatiquement sa dernière expression évaluée ;return()est optionnel.
12. Aléatoire et simulation
sample(0:1, 10, replace=TRUE) # 10 lancers de pièce (1=pile, 0=face)
runif(5) # 5 tirages uniformes sur [0,1]
replace=TRUESans lui,
sample()tire sans remise — impossible de tirer 10 valeurs dans0:1. À ne jamais oublier pour simuler des tirages répétés.
Répéter une expérience :
lancer <- function() sample(0:1, 10, replace=TRUE)
simu <- replicate(100, lancer()) # matrice 10 x 100 : 100 expériences en colonnesAppliquer une fonction sur les lignes/colonnes :
(nb.pile <- apply(simu, MARGIN=2, FUN=sum)) # somme par COLONNE = nb de piles par expérience
table(nb.pile) # tableau de fréquences
barplot(table(nb.pile)/100,
main = "Diagramme en bâton des piles obtenus",
xlab = "Nombre de piles")Retenir
MARGIN
MARGIN=1→ on applique par ligne.MARGIN=2→ par colonne. Moyen mnémotechnique : dansdim(), les lignes viennent en premier (1), les colonnes en second (2).
13. Importer des données
donnees <- read.table(
file = "nutriage.txt",
header = TRUE, # 1re ligne = noms des variables
sep = "\t", # séparateur : tabulation
dec = "." # séparateur décimal
)| Paramètre | Rôle |
|---|---|
file | Chemin du fichier — file.choose() ouvre un sélecteur graphique |
header | TRUE si la 1re ligne contient les noms de colonnes |
sep | Séparateur de champs : "\t", " ", ",", ";" |
dec | Séparateur décimal : "." ou "," (fichiers français !) |
row.names | 1 = utiliser la 1re colonne comme noms de lignes |
attach(donnees) # accès direct aux variables par leur nom
attach()Pratique en TP, mais déconseillé en vrai : ça duplique le contexte et crée des ambiguïtés si une variable du même nom existe déjà. Préférer
donnees$Variable. Pour annuler :detach(donnees).
Fichiers français
Un CSV exporté depuis Excel FR utilise souvent
sep=";"etdec=",". Si les nombres arrivent encharacter, c’est presque toujours ça (cf. coercition § 7).
💡 Exemples / démos
Chaîne complète : simuler et visualiser
lancer <- function() sample(0:1, 10, replace=TRUE)
simu <- replicate(100, lancer())
nb.pile <- apply(simu, MARGIN=2, FUN=sum)
barplot(table(nb.pile)/100,
main="Diagramme en bâton des piles obtenus",
xlab="Nombre de piles")Ce pipeline fonction → replicate → apply → table → barplot est le schéma type de toute simulation du cours.
📝 Exercices du TP
Simulation aléatoire
- Écrire une fonction simulant un lancer de pièce (pile / face).
- Écrire une fonction simulant un dé à 6 faces avec
sample(). - Simuler un Yams (5 dés) — penser aux arguments
sizeetreplace. - Estimer la probabilité d’un Yams avec
replicate(),apply()etunique().
Indice pour le Yams
Un Yams = les 5 dés identiques ⇔
length(unique(des)) == 1.
TP — Indice de Masse Corporelle
Données : 10 enfants de 3–4 ans (sexe, ZEP, âge en années/mois, poids en kg, taille en cm).
- Enregistrer les variables dans des vecteurs nommés.
- Calculer les moyennes pertinentes.
- Calculer l’IMC = Poids(kg) / Taille²(m) — ⚠️ convertir les cm en m.
- Regrouper le tout dans la structure R appropriée (→
data.frame, § 9). - Consulter l’aide de
plot()(?plot). - Tracer poids en fonction de la taille, avec titre et axes légendés.
⚠️ À retenir absolument (examen)
==(valeur) vsidentical()(valeur et type).- Indexation à partir de 1 ; indice négatif = exclusion.
[ ](sous-liste) vs[[ ]]/$(contenu) ;$n’évalue pas les variables.- Coercition :
logical → integer → numeric → character, silencieuse et destructrice. - Recycling : silencieux si multiple, inapplicable aux data.frames.
matrix(byrow=): par défaut R remplit par colonnes.*(terme à terme) vs%*%(matriciel).apply(MARGIN=1)= lignes,MARGIN=2= colonnes.factor()trie par ordre alphabétique → utiliserordered(levels=)pour l’ordinal.sample(..., replace=TRUE)obligatoire pour des tirages répétés.
📇 Aide-mémoire
| Concept | Fonction / opérateur | Exemple |
|---|---|---|
| Affectation | <- | x <- 5 |
| Vecteur | c() | c(1,2,3) |
| Séquence | : | 1:10 |
| Séquence à pas | seq() | seq(0,20,1.3) |
| Répétition | rep() | rep(2,3) |
| Indexation | [] | v[1:3] |
| Exclusion | [-] | v[-8] |
| Filtrage | [] + condition | z[z>10] |
| Appartenance | %in% | v %in% c(1,2) |
| Matrice | matrix() | matrix(1:6,2,3) |
| Produit matriciel | %*% | t(B) %*% A |
| Transposée | t() | t(A) |
| Liste | list() | list(a=1,b=2) |
| Data.frame | data.frame() | data.frame(x,y) |
| Facteur | factor() | factor(c("A","B")) |
| Ordinal | ordered() | ordered(x, levels=...) |
| Fonction | function() | f <- function(x){...} |
| Application | apply() | apply(mat,2,sum) |
| Réplication | replicate() | replicate(100, expr) |
| Aléatoire | sample(), runif() | sample(1:6,10,TRUE) |
| Fréquences | table() | table(vec) |
| Graphiques | plot(), barplot() | plot(x,y) |
| Import | read.table() | read.table(file=...) |
| Concaténation texte | paste() | paste(a, b, sep="") |
| Type d’un objet | class() | class(a) |
| Suppression | rm() | rm(x, y) |
| Aide | ? | ?plot |
❓ Points flous / à revoir
- Refaire l’exercice du Yams et vérifier la probabilité estimée (théorique : 6/6^5 ≈ 0.0077)
- Tester
l2[1]vsl2[[1]]dans la console pour bien voir la différence de structure - Importer
nutriage.txtet vérifier les types obtenus avecstr()
🔗 Liens
- Matière : _Analyse probabiliste de données
- Séance précédente : —
- Séance suivante : [[]]