Menu

Les matrices en R : matrix(), cbind, rbind et calcul matriciel

Comment construire des matrices avec matrix(), cbind() et rbind(), indexer lignes et colonnes, et bien distinguer le * élément par élément de la vraie multiplication matricielle %*%.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Une matrice est un vecteur avec des dimensions

Une matrice en R est un rectangle de valeurs - lignes et colonnes - où chaque cellule contient le même type, généralement des nombres. Sous le capot, c'est littéralement un vecteur auquel on a agrafé un attribut dim, ce qui explique l'essentiel de son comportement : un seul type de bout en bout, du calcul vectorisé partout.

Tu en construis une en remettant un vecteur en forme avec matrix() :

Six valeurs, deux lignes - R en déduit qu'il faut trois colonnes. dim() rapporte les deux dimensions d'un coup, 2 3 ; nrow() et ncol() les donnent séparément.

Regarde de près la matrice affichée : les valeurs vont 1 2 en descendant la première colonne, puis 3 4 en descendant la suivante. R remplit les matrices colonne par colonne par défaut. Si tes données se lisent ligne par ligne - ce qui est la façon dont les humains les écrivent d'habitude - dis-le avec byrow = TRUE :

Maintenant la première ligne est 1 2 3. Oublier byrow = TRUE ne provoque pas d'erreur - ça te donne silencieusement une disposition d'allure transposée des mêmes nombres, alors prends l'habitude de vérifier la mise en page affichée dès que tu construis une matrice à partir de valeurs brutes.

Indexation : m[ligne, colonne]

L'indexation de matrice prend deux positions dans une seule paire de crochets, la ligne avant la virgule, la colonne après - toutes deux comptées à partir de 1 :

Laisser une position vide signifie « toutes » : m[1, ] est toute la première ligne, m[, 2] toute la deuxième colonne. Remarque que les deux reviennent sous forme de vecteurs simples - R supprime la dimension réduite à la taille 1. C'est pratique en interactif et piégeux dans du code, parce qu'une fonction attendant une matrice s'étouffera avec le vecteur. Demande à R de conserver la forme avec drop = FALSE :

dim() rapporte maintenant 1 3 - toujours une matrice. Chaque fois que tu extrais une seule ligne ou colonne dans une fonction, écris drop = FALSE ; le bug que ça évite (du code qui marche sur des données larges et casse sur des données à une colonne) est particulièrement pénible à traquer.

Les masques logiques marchent aussi ici : m[m > 3] renvoie toutes les cellules supérieures à 3, sous forme de vecteur.

Construire avec cbind() et rbind()

Au lieu de remettre en forme un long vecteur, tu peux assembler une matrice à partir de morceaux : cbind() lie des vecteurs en colonnes, rbind() en lignes. Les mêmes fonctions étendent aussi une matrice existante :

Les noms voyagent avec les vecteurs : cbind() a utilisé heights et weights comme noms de colonnes automatiquement, ce qui garde la matrice affichée lisible. Les deux fonctions exigent que les longueurs s'alignent (avec recyclage pour les valeurs de longueur 1) ; lier un vecteur de longueur 3 à une matrice de 4 lignes déclenche un avertissement.

Les noms de colonnes et de lignes peuvent aussi être définis directement via colnames(m) <- ... et rownames(m) <- ..., après quoi tu peux indexer par nom : people[, "weights"].

Le * élément par élément et la vraie multiplication matricielle %*%

Voici la distinction la plus importante de tout cet article. R a deux opérateurs de multiplication pour les matrices, et ils calculent des choses entièrement différentes :

  • a * a est élément par élément : chaque cellule multipliée par la cellule correspondante. 1 2 3 4 deviennent 1 4 9 16, disposés dans la même forme. C'est juste de l'arithmétique vectorisée, le même * que tu utilises sur les vecteurs.
  • a %*% a est la multiplication matricielle de l'algèbre linéaire - chaque cellule du résultat est une ligne de la première matrice fois une colonne de la seconde, sommées. La même entrée donne 7 10 15 22 : des nombres complètement différents.

Lance l'extrait et compare les deux sorties côte à côte ; les voir différer sur des entrées identiques est ce qui fixe la distinction. Si tu écris * là où les maths appellent %*%, R ne t'avertira pas - les formes sont compatibles dans les deux cas pour des matrices carrées - tu obtiens simplement de mauvais nombres. Dans du code de statistique (matrices de covariance, algèbre des modèles linéaires), c'est l'un des bugs silencieux classiques.

t() transpose - échange lignes et colonnes - et apparaît constamment à côté de %*% parce que la multiplication matricielle exige que les dimensions internes correspondent :

Pour être complet : solve(m) inverse une matrice, et %*% avec un vecteur le traite comme une matrice à une colonne. C'est aussi loin que la plupart du travail de données a besoin d'aller.

Résumés par ligne et par colonne

Sommer ou moyenner sur les lignes et les colonnes est si courant que R livre des fonctions dédiées et rapides pour ça :

rowSums() réduit chaque ligne à un nombre (6 15 ici), colSums() chaque colonne (5 7 9), et les variantes Means font la moyenne à la place. Préfère-les aux boucles faites main ou même à apply(m, 1, sum) - elles sont plus claires et plus rapides. Pour les résumés que ces quatre-là ne couvrent pas (disons un maximum par colonne), la famille apply est l'outil général : apply(m, 2, max).

Matrice ou data frame ?

Les deux sont rectangulaires, alors lequel choisir ?

  • Matrice : chaque cellule du même type, et les maths comptent. Calcul numérique, algèbre linéaire, calculs de distances, grilles de type image. Les matrices sont plus légères et leurs opérations plus rapides précisément grâce à la garantie du type unique.
  • Data frame : des colonnes de types différents - des noms à côté d'âges à côté d'indicateurs logiques. C'est la donnée tabulaire du monde réel, et c'est ce qu'attendent presque toutes les fonctions d'analyse de données.

Une bonne règle : si tu l'ouvrirais naturellement dans un tableur avec des colonnes nommées et hétérogènes, c'est un data frame. Si c'est une grille de nombres sur laquelle tu comptes faire de l'algèbre, c'est une matrice. La conversion entre les deux est facile (as.matrix(), as.data.frame()) - mais as.matrix() sur un data frame comportant une colonne texte convertit tout en character, alors ne convertis que les colonnes numériques.

Ce que tu retiens

  • Une matrice est un vecteur avec des dimensions : un seul type de bout en bout, construite avec matrix(data, nrow, ncol) - et elle se remplit colonne par colonne sauf si tu passes byrow = TRUE.
  • Indexe avec m[ligne, col] ; une position vide signifie « toutes » ; ajoute drop = FALSE quand tu extrais une seule ligne ou colonne dans du code.
  • cbind() et rbind() assemblent des matrices à partir de vecteurs ou étendent des matrices existantes.
  • * est élément par élément, %*% est la vraie multiplication matricielle - mêmes entrées, réponses différentes, aucun avertissement.
  • rowSums() / colSums() / rowMeans() / colMeans() couvrent les résumés du quotidien.

Prochaine étape : les facteurs - comment R représente les données catégorielles, et les pièges qui vont avec.

Questions fréquentes

Comment créer une matrice en R ?

matrix(1:6, nrow = 2) remet en forme un vecteur en 2 lignes et 3 colonnes, en remplissant colonne par colonne. Ajoute byrow = TRUE pour remplir ligne par ligne à la place. Tu peux aussi assembler une matrice à partir de vecteurs : cbind() les colle en colonnes, rbind() en lignes.

Quelle est la différence entre * et %*% en R ?

* multiplie élément par élément - chaque cellule par la cellule correspondante, les formes doivent s'aligner. %*% est la vraie multiplication matricielle de l'algèbre linéaire (lignes fois colonnes, donc les dimensions internes doivent correspondre). Les deux donnent des résultats complètement différents sur les mêmes matrices, et utiliser * là où tu voulais %*% est un bug silencieux classique.

Comment obtenir une ligne ou une colonne d'une matrice en R ?

Laisse l'autre position vide : m[1, ] est la première ligne, m[, 2] la deuxième colonne. Les deux reviennent sous forme de vecteurs simples par défaut. Ajoute drop = FALSE - comme dans m[1, , drop = FALSE] - pour garder le résultat sous forme de matrice à une ligne ou une colonne, ce qui compte quand du code ultérieur attend deux dimensions.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER