Matrices et Tableaux

Matrices et Tableaux

 Dans un contexte statistique, une matrice typique dans R a des lignes correspondant à des observations, par exemple sur différentes personnes et des colonnes correspondant à des variables telles que le poids et la tension artérielle. La matrice est alors une structure de données bidimensionnelle. Mais supposons que nous avons également des données prises à différents moments, un point de données par personne par variable par temps. Le temps devient alors le troisième dimentis, en plus des lignes et des colonnes. Dans R, ces ensembles de données sont appelés des tableaux.
Comme un exemple simple, considérez les élèves et les résultats des tests. Dites que chaque test se compose de deux parties, donc nous enregistrons deux scores pour un étudiant pour chaque test. Supposons maintenant que nous ayons deux tests, et pour garder l'exemple petit, supposons que nous avons seulement trois étudiants. Voici les données pour le premier test:

  1. > firsttest
  2. [,1] [,2]
  3. [1,] 46 30
  4. [2,] 21 25
  5. [3,] 50 50
Source code

L'élève 1 a obtenu un score de 46 et 30 lors du premier test, l'étudiant 2 a marqué 21 et 25, et ainsi de suite. Voici les notes pour les mêmes étudiants sur le deuxième test:

  1. > secondtest
  2. [,1] [,2]
  3. [1,] 46 43
  4. [2,] 41 35
  5. [3,] 50 50
Source code

Maintenant, mettons les deux tests dans une seule structure de données, que nous allons appeler des tests. Nous allons organiser deux "couches" - une couche par test - avec trois lignes et deux colonnes dans chaque couche. Nous allons stocker le premier test dans la première couche et le deuxième test dans la seconde.
Dans la couche 1, il y aura trois lignes pour les scores de trois élèves sur le premier test, avec deux colonnes par rangée pour les deux parties d'un test. Nous utilisons la fonction de matrice de R pour créer la structure de données:

  1. > tests <- array(data=c(firsttest,secondtest),dim=c(3,2,2))
Source code

Dans l'argument dim = c (3,2,2), nous spécifions deux couches (c'est la seconde-deuxième), chacune consistant en trois lignes et deux colonnes. Cela devient alors un attribut de la structure de données:

  1. > attributes(tests)
  2. $dim
  3. [1] 3 2 2
Source code

Chaque élément de test comporte maintenant trois indices, plutôt que deux, comme dans le cas matriciel. Le premier sous-chapitre correspond au premier élément du vecteur $ dim, le second indice correspondant au deuxième élément du vecteur, etc. Par exemple, le score sur la deuxième partie du test 1 pour l'étudiant 3 est récupéré comme suit:

  1. > tests[3,2,1]
  2. [1] 48
Source code
La fonction d'impression de R pour les tableaux affiche la couche de données par couche:

  1. > tests
  2. , , 1
  3. [,1] [,2]
  4. [1,] 46 30
  5. [2,] 21 25
  6. [3,] 50 48
  7. , , 2
  8. [,1] [,2]
  9. [1,] 46 43
  10. [2,] 41 35
  11. [3,] 50 49
Source code

Tout comme nous avons construit notre réseau tridimensionnel en combinant deux matrices, nous pouvons construire des tableaux à quatre dimensions en combinant deux ou plusieurs tableaux à trois dimensions, et ainsi de suite.
L'une des utilisations les plus fréquentes des tableaux consiste à calculer les tableaux. Voir la section 6.3 pour un exemple d'une table tridimensionnelle.

 

En principe, les matrices ont de longueur et de dimensions fixes, et donc nous ne pouvons pas ajouter ou supprimer des lignes ou des colonnes. Cependant, les matrices peuvent être réaffectées, et nous pouvons donc atteindre le même effet que si nous avions directement fait des ajouts ou des suppressions.


Modification de la taille d'une matrice
Rappelons comment nous réaffecter des vecteurs pour changer leur taille:

  1. > x
  2. [1] 12 5 13 16 8
  3. > x <- c (x, 20) # ajouter 20
  4. > x
  5. [1] 12 5 13 16 8 20
  6. > x <- c (x [1: 3], 20, x [4: 6]) # insérer 20
  7. > x
  8. [1] 12 5 13 20 16 8 20
  9. > x <- x [-2: -4] # supprimez les éléments 2 et 4
  10. > x
  11. [1] 12 16 8 20
Source code

Dans le premier cas, x est à l'origine de  longueur 5, que nous avons étend  6 par conclassement et puis réaffectation. Nous n'avons pas changé littéralement la longueur de x, mais avons créé un nouveau vecteur de x, puis nous avons attribué x à ce nouveau vecteur.
Par exemple, même l'assignation x [2] <- 12 est réellement une réaffectation.
Des opérations analogues peuvent être utilisées pour modifier la taille d'une matrice. Par exemple, les fonctions rbind () (ligne) et cbind () (colonne) vous permettent d'ajouter des lignes ou des colonnes à une matrice.

  1. > one
  2. [1] 1 1 1 1
  3. > z
  4. [,1] [,2] [,3]
  5. [1,] 1 1 1
  6. [2,] 2 1 0
  7. [3,] 3 0 1
  8. [4,] 4 0 0
  9. > cbind(one,z)
  10. [1,] 1 1 1 1
  11. [2,] 1 2 1 0
  12. [3,] 1 3 0 1
  13. [4,] 1 4 0 0
Source code

Ici, cbind () crée une nouvelle matrice en combinant une colonne des 1 avec les colonnes de z. Nous choisissons d'obtenir une impression rapide, mais nous aurions pu attribuer le résultat à z (ou à une autre variable), comme suit:

  1. z <- cbind (one, z)
Source code
Notez également que nous aurions pu compter sur le recyclage:
  1. > cbind(1,z)
  2. [,1] [,2] [,3] [,4]
  3. [1,] 1 1 1 1
  4. [2,] 1 2 1 0
  5. [3,] 1 3 0 1
  6. [4,] 1 4 0 0
Source code
Ici, la valeur 1 a été recyclée dans un vecteur de quatre valeurs 1.
Vous pouvez également utiliser les fonctions rbind () et cbind () comme un moyen rapide de créer de petites matrices. Voici un exemple:
  1. > q <- cbind (c (1,2), c (3,4))
  2. > q
  3. [, 1] [, 2]
  4. [1,] 1 3
  5. [2,] 2 4
Source code
Faites attention avec rbind et cbin (), cependant. Comme créer un vecteur, créer une matrice prend du temps (les matrices sont des vecteurs, après tout). Dans le code suivant, cbind () crée une nouvelle matrice:
  1. z <- cbind (one, z)
Source code
La nouvelle matrice est réaffectée à z; c'est-à-dire que nous lui avons donné le nom z-le même nom que la matrice originale, qui est maintenant disparue. Mais le fait est que nous avons eu une pénalité temporelle dans la création de la matrice. Si nous l'avons fait répéter dans une boucle, la pénalité cumulative serait importante.
Donc, si vous ajoutez des lignes ou des colonnes une à la fois dans une boucle, et que la matrice finira par devenir grande, il est préférable d'allouer une grande matrice en premier lieu. Il sera vide d'abord, mais vous complétez les lignes ou les colonnes une à la fois, plutôt que de faire une quantité de mémoire mémorisée chaque fois.
Vous pouvez également supprimer des lignes ou des colonnes par réaffectation:

  1. > m <- matrix(1:6,nrow=3)
  2. > m
  3. [,1] [,2]
  4. [1,] 1 4
  5. [2,] 2 5
  6. [3,] 3 6
  7. > m <- m[c(1,3),]
  8. > m
  9. [,1] [,2]
  10. [1,] 1 4
  11. [2,] 3 6
Source code

 

La façon naturelle de se référer aux lignes et aux colonnes dans une matrice est via les nombres de lignes et de colonnes. Toutefois, vous pouvez également donner des noms à ces entités. Voici un exemple:

  1. > z
  2. [,1] [,2]
  3. [1,] 1 3
  4. [2,] 2 4
  5. NULL
  6. > colnames(z) <- c("a","b")
  7. > z
  8. a b
  9. [1,] 1 3
  10. [2,] 2 4
  11. [1] "a" "b"
  12. > z[,"a"]
  13. [1] 1 2
Source code

Comme vous le voyez ici, ces noms peuvent ensuite être utilisés pour référencer des colonnes spécifiques. La fonction rowndames () fonctionne de manière similaire.
Nommer les lignes et les colonnes est généralement moins important lors de l'écriture du code R pour les applications générales, mais cela peut être utile lors de l'analyse d'un ensemble de données spécifiques.

Dans le monde des statistiques, la réduction des dimensions est une bonne chose, avec de nombreuses procédures statistiques visant à bien le faire. Si nous travaillons avec, par exemple, 10 variétés et que nous pouvons réduire ce nombre à 3 qui capte toujours l'essence de nos données, nous sommes heureux.
Cependant, dans R, quelque chose d'autre pourrait mériter la réduction de la dimension du nom que nous pouvons parfois souhaiter éviter. Disons que nous avons une matrice à quatre rangées et que nous extrayons une ligne:

  1. > z
  2. [,1] [,2]
  3. [1,] 1 5
  4. [2,] 2 6
  5. [3,] 3 7
  6. [4,] 4 8
  7. > r <- z[2,]
  8. > r
  9. [1] 2 6
Source code

Cela semble inoffensif, mais notez le format dans lequel R a affiché r. C'est un format vectoriel, pas un format matriciel. En d'autres termes, r est un vecteur de longueur 2, et non une matrice 1-par-2. Nous pouvons le confirmer de plusieurs façons:

  1. $dim
  2. [1] 4 2
  3. NULL
  4. > str(z)
  5. int [1:4, 1:2] 1 2 3 4 5 6 7 8
  6. > str(r)
  7. int [1:2] 2 6
Source code

Ici, R nous informe que z a des numéros de lignes et de colonnes, alors que r ne le fait pas. De même, str () nous dit que z a des indices allant en 1: 4 et 1: 2, pour les lignes et les colonnes, alors que les indices de r sont tout simplement en 1: 2. Aucun doute à ce sujet-r est un vecteur, pas une matrice.
Cela semble naturel, mais dans de nombreux cas, cela entraînera des problèmes dans les programmes qui font beaucoup d'opérations matricielles. Vous pouvez constater que votre code fonctionne bien en général mais échoue dans un cas particulier. Par exemple, supposons que votre code extrait une sous-matrice d'une matrice donnée puis effectue des opérations matricielles sur la sous-matrice. Si la sous-matrice n'a qu'une seule ligne, R en fera un vecteur, ce qui pourrait ruiner votre calcul.
Heureusement, R a un moyen de supprimer cette réduction de dimension: l'argument de baisse. Voici un exemple, en utilisant la matrice z d'en haut:

  1. > r <- z[2,, drop=FALSE]
  2. > r
  3. [,1] [,2]
  4. [1,] 2 6
  5. > dim(r)
  6. [1] 1 2
Source code
Maintenant, r est une matrice 1-par-2, pas un vecteur à deux éléments.
Pour ces raisons, vous pourriez trouver utile d'inclure systématiquement l'argument drop = FALSE dans tout votre code de matrice.
Pourquoi pouvons-nous parler de laisser tomber comme un argument? Parce que [est en fait une fonction, comme c'est le cas pour les opérateurs comme +. Considérez le code suivant:

  1. > z[3,2]
  2. [1] 7
  3. > "["(z,3,2)
  4. [1] 7
Source code
Si vous avez un vecteur que vous souhaitez être traité comme une matrice, vous pouvez utiliser la fonction as.matrix (), comme suit:

  1. > u
  2. [1] 1 2 3
  3. > v <- as.matrix(u)
  4. NULL
  5. $dim
  6. [1] 3 1
Source code