5  Matrices

En R, une matrice est essentiellement un vecteur dont les éléments sont organisés sous forme de tableau, avec des lignes et des colonnes. Ce qui distingue une matrice d’un simple vecteur, c’est qu’elle possède un attribut appelé dim (pour dimension), qui définit sa structure bidimensionnelle (lignes et colonnes).

5.1 Créer une matrice avec matrix()

Pour créer une matrice, on utilise la fonction matrix(), qui permet de spécifier les données ainsi que le nombre de lignes (nrow, par défaut nrow = 1) et de colonnes (ncol) souhaité. Aussi, par défaut, le remplissage d’une matrice se fait par colonne. Pour un remplissage par ligne, il faut utiliser l’option byrow = TRUE.

matrix(1:6)
     [,1]
[1,]    1
[2,]    2
[3,]    3
[4,]    4
[5,]    5
[6,]    6
matrix(1:6, ncol = 2)
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
matrix(1:6, nrow = 2)
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
matrix(1:6, nrow = 2, byrow = TRUE)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

Comme pour les vecteurs, tous les éléments d’une matrice doivent être de même type (numérique, caractère ou logique). Aussi, comme les vecteurs, R utilise le principe de recyclage lors de la construction d’une matrice. Par exemple, le code suivant :

M <- matrix(1:6, nrow = 5, ncol = 10)
M
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    6    5    4    3    2    1    6    5     4
[2,]    2    1    6    5    4    3    2    1    6     5
[3,]    3    2    1    6    5    4    3    2    1     6
[4,]    4    3    2    1    6    5    4    3    2     1
[5,]    5    4    3    2    1    6    5    4    3     2

génère un Warning (non affiché ici) car le nombre d’éléments fournis (ici 1:6, soit 6 éléments) ne correspond pas au nombre total de cases que la matrice devrait contenir (ici 5 × 10 = 50 éléments). R essaie de remplir la matrice en répétant les valeurs du vecteur initial autant de fois que nécessaire. Mais ici, 6 ne divise pas 50, donc R recycle les valeurs de manière incomplète, ce qui déclenche le Warning.

On peut consulter ou modifier les dimensions d’une matrice à l’aide de la fonction dim(). On peut également utiliser str() pour obtenir une description plus complète de la structure de l’objet, y compris ses dimensions et le type de données qu’il contient :

dim(M) # voir aussi nrow() et ncol()
str(M)
[1]  5 10
 int [1:5, 1:10] 1 2 3 4 5 6 1 2 3 4 ...

Avec les fonctions colnames() et rownames(), on peut consulter ou modifier les noms des colonnes et des lignes d’une matrice. Cela permet de rendre les données plus lisibles et de faciliter leur manipulation :

colnames(M) <- LETTERS[1:10]
rownames(M) <- paste0("Ligne", 1:5)
M
       A B C D E F G H I J
Ligne1 1 6 5 4 3 2 1 6 5 4
Ligne2 2 1 6 5 4 3 2 1 6 5
Ligne3 3 2 1 6 5 4 3 2 1 6
Ligne4 4 3 2 1 6 5 4 3 2 1
Ligne5 5 4 3 2 1 6 5 4 3 2

5.2 Accéder aux éléments d’une matrice

R propose plusieurs méthodes pour extraire des éléments d’une matrice, que ce soit par indexation numérique (en indiquant les numéros/positions de lignes et/ou de colonnes à inclure ou à exclure — indexation négative), par indexation nominale lorsque la matrice possède des noms de lignes ou de colonnes, ou encore par indexation logique permettant de filtrer les valeurs selon une condition donnée.

Sélection de lignes

M[c(1, 3), ]                              # Iindexation numérique (Lignes 1 et 3)
M[-c(2, 4, 5), ]                          # Indexation négative: exclue les lignes 2, 4 et 5
M[c("Ligne1", "Ligne3"), ]                # Indexation par nom
M[c(TRUE, FALSE, TRUE, FALSE, FALSE), ]   # Indexation logique
       A B C D E F G H I J
Ligne1 1 6 5 4 3 2 1 6 5 4
Ligne3 3 2 1 6 5 4 3 2 1 6

Sélection de colonnes

M[, 1:2]                           # Indexation numérique (Colonnes 1 et 2)
M[, -(3:10)]                       # Indexation négative: exclue les colonnes 3-10
M[, c("A", "B")]                   # Indexation par nom
M[, c(TRUE, TRUE, rep(FALSE, 8))]  # Indexation logique
       A B
Ligne1 1 6
Ligne2 2 1
Ligne3 3 2
Ligne4 4 3
Ligne5 5 4

On peut utiliser l’indexation pour extraire un élément bien spécifique d’une matrice ou pour en isoler un sous‑ensemble plus large. Voici deux exemples :

M[1, 2]      # Élément situé à la ligne 1, colonne 2
M[1, ][2]    # Idem, en deux étapes
M[, 2][1]    # Idemt, en inversant l’ordre d’accès
[1] 6
M[c(1, 3), c(3, 4)]          # Lignes 1 et 3, colonnes 3 et 4
M[c(1, 3), ][, c(3, 4)]      # Idem, syntaxe alternative
       C D
Ligne1 5 4
Ligne3 1 6

Simplification automatique: l’argument drop

Par défaut, R simplifie le résultat d’une extraction dès que cela est possible, notamment en renvoyant un vecteur plutôt qu’une matrice lorsque l’extraction ne concerne qu’une seule ligne ou une seule colonne. Cette simplification automatique peut toutefois être désactivée : il suffit d’utiliser l’argument drop = FALSE pour forcer R à conserver le résultat sous forme de matrice, même lorsque celui‑ci pourrait être réduit à un vecteur. Exemple :

M[1, ]
A B C D E F G H I J 
1 6 5 4 3 2 1 6 5 4 
M[1, , drop = FALSE]
       A B C D E F G H I J
Ligne1 1 6 5 4 3 2 1 6 5 4

Pour vérifier la nature de l’objet obtenu après extraction, on peut utiliser les fonctions is.vector() et is.matrix(). Elles permettent de confirmer si R a simplifié le résultat ou si la structure matricielle a été conservée. Exemple :

M[1, ] |> is.vector()
M[1, , drop = FALSE] |> is.matrix()
[1] TRUE
[1] TRUE
Note

R met à disposition une large famille de fonctions is_*() permettant de tester la nature d’un objet. Parmi les plus utiles, on peut citer : is.vector(), is.matrix(), is.table(), is.list(), is.data.frame().

Indexation linéaire

Une autre façon d’accéder aux éléments d’une matrice en R consiste à utiliser ce qu’on appelle l’index linéaire. Cela revient à considérer la matrice comme un vecteur formé en concaténant les colonnes les unes après les autres. Autrement dit, R parcourt les éléments colonne par colonne, et attribue à chaque élément un numéro d’ordre selon cette logique. Cette méthode permet d’accéder aux éléments avec une seule valeur d’indice, comme dans l’exemple suivant :

M[8]
[1] 2

qui renvoie 2, car c’est le 8e élément de M en comptant colonne par colonne.

5.3 Manipuler les matrices

Modifier une matrice

En R, il est très simple de modifier les éléments d’une matrice, que ce soit un seul élément, une ligne, une colonne ou un sous-ensemble. Voici quelques exemples illustrant différentes méthodes.

# Modifier un élément spécifique (ligne 2, colonne 2)
M[2, 2] <- 22
# Remplacer toute la première ligne
M[1, ] <- 11
# Modifier plusieurs éléments à la fois (lignes 1 et 3, colonnes 3 et 4)
M[c(1, 3), c(3, 4)] <- c(13, 14, 33, 34)
# Modifier la 10e colonne pour toutes les lignes sauf la première
M[-1, 10] <- NA

M
        A  B  C  D  E  F  G  H  I  J
Ligne1 11 11 13 33 11 11 11 11 11 11
Ligne2  2 22  6  5  4  3  2  1  6 NA
Ligne3  3  2 14 34  5  4  3  2  1 NA
Ligne4  4  3  2  1  6  5  4  3  2 NA
Ligne5  5  4  3  2  1  6  5  4  3 NA

Lorsqu’on assigne un vecteur à une portion de matrice, R peut recycler les éléments de ce vecteur pour remplir tous les emplacements ciblés, à condition que le nombre total d’éléments à modifier soit un multiple exact de la longueur du vecteur fourni (exemple : M[1, ] <- 11). Toutefois, il est préférable de s’assurer que les tailles sont compatibles afin d’éviter des erreurs involontaires. À noter aussi que R remplit les éléments colonne par colonne, conformément à la manière dont les matrices sont stockées en mémoire.

Assembler des vecteurs et matrices

Lorsque l’on souhaite regrouper plusieurs vecteurs ou matrices pour former une structure plus grande, R propose deux fonctions très pratiques : rbind() et cbind(). Ces fonctions permettent d’assembler des objets :

  • rbind() (row bind) : ajoute des lignes ou empile des vecteurs verticalement.
  • cbind() (column bind) : ajoute des colonnes ou aligne des vecteurs horizontalement.
v1 <- 1:10
v2 <- 11:20

cbind(v1, v2)  # Crée une matrice à deux colonnes
      v1 v2
 [1,]  1 11
 [2,]  2 12
 [3,]  3 13
 [4,]  4 14
 [5,]  5 15
 [6,]  6 16
 [7,]  7 17
 [8,]  8 18
 [9,]  9 19
[10,] 10 20
rbind(v1, v2)  # Crée une matrice à deux lignes
   [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
v1    1    2    3    4    5    6    7    8    9    10
v2   11   12   13   14   15   16   17   18   19    20
rbind(M, v1)   # Ajoute v1 comme nouvelle ligne à M
        A  B  C  D  E  F  G  H  I  J
Ligne1 11 11 13 33 11 11 11 11 11 11
Ligne2  2 22  6  5  4  3  2  1  6 NA
Ligne3  3  2 14 34  5  4  3  2  1 NA
Ligne4  4  3  2  1  6  5  4  3  2 NA
Ligne5  5  4  3  2  1  6  5  4  3 NA
v1      1  2  3  4  5  6  7  8  9 10
matrix(1:25, nrow = 5, byrow = TRUE) |> cbind(M)  # Ajoute 5 nouvelles colonnes à M
                       A  B  C  D  E  F  G  H  I  J
Ligne1  1  2  3  4  5 11 11 13 33 11 11 11 11 11 11
Ligne2  6  7  8  9 10  2 22  6  5  4  3  2  1  6 NA
Ligne3 11 12 13 14 15  3  2 14 34  5  4  3  2  1 NA
Ligne4 16 17 18 19 20  4  3  2  1  6  5  4  3  2 NA
Ligne5 21 22 23 24 25  5  4  3  2  1  6  5  4  3 NA

Les fonctions rbind() et cbind() ne modifient pas directement la matrice d’origine. Elles produisent un nouvel objet, sans altérer l’original. Si l’on souhaite que la matrice M intègre réellement les modifications, il faut réassigner le résultat, comme dans l’exemple suivant :

M <- rbind(M, v1)

5.4 Opérations matricielles

R permet d’effectuer une grande variété d’opérations mathématiques sur les matrices. Les exemples suivants illustrent ces possibilités, sans afficher les sorties.

X <- matrix(c(9, 2, -3, 2, 4, -2, -3, -2, 16), 3, byrow = TRUE)
X
Y <- matrix(0:8, ncol = 3)
Y
Output
     [,1] [,2] [,3]
[1,]    9    2   -3
[2,]    2    4   -2
[3,]   -3   -2   16
     [,1] [,2] [,3]
[1,]    0    3    6
[2,]    1    4    7
[3,]    2    5    8

Opérations élément par élément

X + Y  # Addition
X - Y  # Soustraction
X * Y  # Multiplication élément par élément
X / Y  # Division élément par élément
Output
     [,1] [,2] [,3]
[1,]    9    5    3
[2,]    3    8    5
[3,]   -1    3   24
     [,1] [,2] [,3]
[1,]    9   -1   -9
[2,]    1    0   -9
[3,]   -5   -7    8
     [,1] [,2] [,3]
[1,]    0    6  -18
[2,]    2   16  -14
[3,]   -6  -10  128
     [,1]       [,2]       [,3]
[1,]  Inf  0.6666667 -0.5000000
[2,]  2.0  1.0000000 -0.2857143
[3,] -1.5 -0.4000000  2.0000000

Opérations matricielles classiques

X %*% Y                   # Produit matriciel (multiplication algébrique)
t(X)                      # Transposition
det(X)                    # Déterminant
solve(X)                  # Inverse de la matrice (si elle est inversible)
rep(1, 3) |> diag()       # Matrice diagonale
Output
     [,1] [,2] [,3]
[1,]   -4   20   44
[2,]    0   12   24
[3,]   30   63   96
     [,1] [,2] [,3]
[1,]    9    2   -3
[2,]    2    4   -2
[3,]   -3   -2   16
[1] 464
            [,1]        [,2]       [,3]
[1,]  0.12931034 -0.05603448 0.01724138
[2,] -0.05603448  0.29094828 0.02586207
[3,]  0.01724138  0.02586207 0.06896552
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1

Fonctions statistiques sur les matrices

colMeans(X)  # Moyenne par colonne
colSums(X)   # Somme par colonne
rowMeans(X)  # Moyenne par ligne
rowSums(X)   # Somme par ligne
Output
[1] 2.666667 1.333333 3.666667
[1]  8  4 11
[1] 2.666667 1.333333 3.666667
[1]  8  4 11

Opérations logiques sur les matrices

R permet aussi d’appliquer des conditions logiques pour filtrer ou modifier les éléments d’une matrice. Voici quelques exemples.

X > 0              # Test logique : quels éléments sont > 0
X[X > 0]           # Extraction des éléments strictement positifs
X[X > 0] <- 100    # Remplacement des éléments > 0 par 100
X
which(X > 0)       # Positions des éléments > 0 (index linéaire)
Output
      [,1]  [,2]  [,3]
[1,]  TRUE  TRUE FALSE
[2,]  TRUE  TRUE FALSE
[3,] FALSE FALSE  TRUE
[1]  9  2  2  4 16
     [,1] [,2] [,3]
[1,]  100  100   -3
[2,]  100  100   -2
[3,]   -3   -2  100
[1] 1 2 4 5 9