5 Les matrices

En R, une matrice n’est rien d’autre qu’un vecteur dont les éléments sont disposés sous forme d’un tableau qui comporte des lignes et des colonnes. Ce qui caractérise une matrice est le fait qu’elle dispose de l’attribut dim (pour dimension). Pour déclarer une matrice, il suffit d’utiliser la fonction matrix().

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

Par défaut, le remplissage d’une matrice se fait par colonne. Si vous voulez un remplissage par ligne, il faut utiliser l’argument byrow avec la valeur TRUE.

matrix(1:6, nrow = 1, byrow = TRUE)
matrix(1:6, nrow = 2, byrow = TRUE)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    2    3    4    5    6
     [,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 classe (numérique, caractère ou logique). Mais, contrairement aux vecteurs, les matrices disposent d’une dimension. Ce qu’on peut vérifier avec la fonction dim(), ou encore avec la fonction str().

xm <- matrix(1:6, nrow = 5, ncol = 10)
xm
     [,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
dim(xm)
[1]  5 10
str(xm)
 int [1:5, 1:10] 1 2 3 4 5 6 1 2 3 4 ...

Avec les fonctions colnames() et rownames() on peut récupérer ou définir les noms des colonnes et des lignes .

colnames(xm) <- paste("X", 1:10, sep = "")
rownames(xm) <- paste("i", 1:5, sep = "")
xm
   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
i1  1  6  5  4  3  2  1  6  5   4
i2  2  1  6  5  4  3  2  1  6   5
i3  3  2  1  6  5  4  3  2  1   6
i4  4  3  2  1  6  5  4  3  2   1
i5  5  4  3  2  1  6  5  4  3   2

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

Voici quelques exemples qui illustrent la façon d’accéder aux éléments (lignes, colonnes) d’une matrice.

xm[1, ]  # ligne 1 (l'output est un vecteur)
 X1  X2  X3  X4  X5  X6  X7  X8  X9 X10 
  1   6   5   4   3   2   1   6   5   4 
xm[c(1, 3), ]  # ligne 1 et 3
xm[c("i1", "i3"), ]  # ligne "i1" et "i3"
   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
i1  1  6  5  4  3  2  1  6  5   4
i3  3  2  1  6  5  4  3  2  1   6
xm[, 1:2]  # colonnes 1 et 2
xm[, c(TRUE, TRUE, rep(FALSE, 8))]  # idem
xm[, c("X1", "X2")]  # colonnes "X1" et "X2"
   X1 X2
i1  1  6
i2  2  1
i3  3  2
i4  4  3
i5  5  4
xm[, -c(1, 3)] # toutes les colonnes sauf 1 et 3
   X2 X4 X5 X6 X7 X8 X9 X10
i1  6  4  3  2  1  6  5   4
i2  1  5  4  3  2  1  6   5
i3  2  6  5  4  3  2  1   6
i4  3  1  6  5  4  3  2   1
i5  4  2  1  6  5  4  3   2
xm[1, 2] # ligne 1, colonne 2 (vecteur)
xm[1, ][2] # idem
xm[, 2][1] # idem
[1] 6
xm[c(1, 3), c(3, 4)] # lignes 1,3 et colonnes 3 et 4
xm[c(1, 3), ][, c(3, 4)] # idem
   X3 X4
i1  5  4
i3  1  6

Vous avez certainement remarqué que, dès que possible, R simplifie le résultat d’une extraction et renvoie un vecteur comme sortie. Si vous voulez éviter cela, alors il faut utiliser l’option drop = FALSE.

xm[1, , drop = FALSE]
xm[, 2, drop = FALSE]
xm[1, 2, drop = FALSE]
   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
i1  1  6  5  4  3  2  1  6  5   4
   X2
i1  6
i2  1
i3  2
i4  3
i5  4
   X2
i1  6

Dans ces trois cas, on obtient une matrice comme sortie, alors que sans drop = FALSE, le résultat serait un vecteur. En effet,

dim(xm[1, ])
dim(xm[1, , drop = FALSE])
NULL
[1]  1 10

Modifier une matrice

On peut facilement modifier les éléments d’une matrice. Voici un exemple.

xm[1, ] <- c(0, 4)
xm[2, 2] <- 22
xm[-1, 10] <- c(50, 60, 10, 20)
xm
   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
i1  0  4  0  4  0  4  0  4  0   4
i2  2 22  6  5  4  3  2  1  6  50
i3  3  2  1  6  5  4  3  2  1  60
i4  4  3  2  1  6  5  4  3  2  10
i5  5  4  3  2  1  6  5  4  3  20

Il est parfois utile de pouvoir ajouter des lignes ou des colonnes à une matrice existante. Pour cela, il existe deux fonctions: rbind() et cbind(), respectivement.

rbind(xm, 1:10) # ici on ne modifie pas la matrice xm
   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
i1  0  4  0  4  0  4  0  4  0   4
i2  2 22  6  5  4  3  2  1  6  50
i3  3  2  1  6  5  4  3  2  1  60
i4  4  3  2  1  6  5  4  3  2  10
i5  5  4  3  2  1  6  5  4  3  20
    1  2  3  4  5  6  7  8  9  10
mat <- matrix(1:25, nrow = 5, byrow = TRUE)
cbind(xm, mat)
   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10               
i1  0  4  0  4  0  4  0  4  0   4  1  2  3  4  5
i2  2 22  6  5  4  3  2  1  6  50  6  7  8  9 10
i3  3  2  1  6  5  4  3  2  1  60 11 12 13 14 15
i4  4  3  2  1  6  5  4  3  2  10 16 17 18 19 20
i5  5  4  3  2  1  6  5  4  3  20 21 22 23 24 25

Opérations matricielles

R sait aussi faire toute sorte d’opérations matricielles. Voici quelques exemples élémentaires.

X <- matrix(c(9, 2, -3, 2, 4, -2, -3, -2, 16), 3, byrow = TRUE)
Y <- matrix(0:8, ncol = 3)
X + Y
     [,1] [,2] [,3]
[1,]    9    5    3
[2,]    3    8    5
[3,]   -1    3   24
X - Y
     [,1] [,2] [,3]
[1,]    9   -1   -9
[2,]    1    0   -9
[3,]   -5   -7    8
X * Y   # multiplication élément par élément
     [,1] [,2] [,3]
[1,]    0    6  -18
[2,]    2   16  -14
[3,]   -6  -10  128
X / Y
     [,1]   [,2]   [,3]
[1,]  Inf  0.667 -0.500
[2,]  2.0  1.000 -0.286
[3,] -1.5 -0.400  2.000
X %*% Y # multiplication matricielle
     [,1] [,2] [,3]
[1,]   -4   20   44
[2,]    0   12   24
[3,]   30   63   96
t(X) # transposer
     [,1] [,2] [,3]
[1,]    9    2   -3
[2,]    2    4   -2
[3,]   -3   -2   16
det(X) # déterminant
[1] 464
solve(X) # inverse
        [,1]    [,2]   [,3]
[1,]  0.1293 -0.0560 0.0172
[2,] -0.0560  0.2909 0.0259
[3,]  0.0172  0.0259 0.0690
colMeans(X) # moyenne par colonne (il y a aussi rowMeans())
[1] 2.67 1.33 3.67
diag(rep(1, 3)) # matrice diagonale
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1