Les paires de fonctions suivantes génèrent-elles exactement les mêmes résultats?
Paire 1) names()
& colnames()
Paire 2) rownames()
& row.names()
Comme disait Oscar Wilde
La consistance est le dernier refuge de l'inimaginable.
R est plus un langage évolué que conçu, alors ces choses arrivent. names()
et colnames()
fonctionnent sur un data.frame
mais names()
ne fonctionne pas sur une matrice:
R> DF <- data.frame(foo=1:3, bar=LETTERS[1:3])
R> names(DF)
[1] "foo" "bar"
R> colnames(DF)
[1] "foo" "bar"
R> M <- matrix(1:9, ncol=3, dimnames=list(1:3, c("alpha","beta","gamma")))
R> names(M)
NULL
R> colnames(M)
[1] "alpha" "beta" "gamma"
R>
Juste pour développer un peu l'exemple de Dirk:
Il est utile de penser à un cadre de données comme une liste avec des vecteurs de longueur égale. C'est probablement pourquoi names
fonctionne avec un bloc de données mais pas une matrice.
L'autre fonction utile est dimnames
qui renvoie les noms de chaque dimension. Vous remarquerez que la fonction rownames
ne renvoie en fait que le premier élément de dimnames
.
En ce qui concerne rownames
et row.names
: Je ne peux pas faire la différence, bien que rownames
utilise dimnames
tandis que row.names
a été écrit en dehors de R. Ils semblent également fonctionner avec des tableaux de dimension supérieure:
>a <- array(1:5, 1:4)
> a[1,,,]
> rownames(a) <- "a"
> row.names(a)
[1] "a"
> a
, , 1, 1
[,1] [,2]
a 1 2
> dimnames(a)
[[1]]
[1] "a"
[[2]]
NULL
[[3]]
NULL
[[4]]
NULL
Je pense que l'utilisation de colnames
et rownames
est la solution la plus logique. Voici pourquoi.
Utiliser names
présente plusieurs inconvénients. Vous devez vous rappeler que cela signifie "noms de colonnes" et que cela ne fonctionne qu'avec un cadre de données. Vous devrez donc appeler colnames
chaque fois que vous utilisez des matrices. En appelant colnames
, vous ne devez vous souvenir que d’une seule fonction. Enfin, si vous regardez le code pour colnames
, vous verrez qu'il appelle names
dans le cas d'un bloc de données, de sorte que le résultat est identique.
rownames
et row.names
renvoie les mêmes valeurs pour le cadre de données et les matrices; la seule différence que j’ai repérée, c’est que là où il n’ya pas de noms, rownames
affichera "NULL" (comme le fait colnames
), mais row.names
le retourne de manière invisible. Comme il n’ya pas beaucoup de choix entre les deux fonctions, rownames
gagne pour des raisons d’esthétique, puisqu’il est plus joli avec colnames
. (En outre, pour le programmeur paresseux, vous enregistrez un caractère de frappe.)
Et une autre extension:
# create dummy matrix
set.seed(10)
m <- matrix(round(runif(25, 1, 5)), 5)
d <- as.data.frame(m)
Si vous souhaitez attribuer de nouveaux noms de colonne, vous pouvez procéder comme suit: data.frame
:
# an identical effect can be achieved with colnames()
names(d) <- LETTERS[1:5]
> d
A B C D E
1 3 2 4 3 4
2 2 2 3 1 3
3 3 2 1 2 4
4 4 3 3 3 2
5 1 3 2 4 3
Toutefois, si vous exécutez la commande précédente sur matrix
, vous allez tout gâcher:
names(m) <- LETTERS[1:5]
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 3 2 4 3 4
[2,] 2 2 3 1 3
[3,] 3 2 1 2 4
[4,] 4 3 3 3 2
[5,] 1 3 2 4 3
attr(,"names")
[1] "A" "B" "C" "D" "E" NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[20] NA NA NA NA NA NA
Comme la matrice peut être considérée comme un vecteur bidimensionnel, vous n'attribuerez des noms qu'aux cinq premières valeurs (vous ne voulez pas le faire, n'est-ce pas?). Dans ce cas, vous devriez vous en tenir à colnames()
.
Donc là...