2010-02-17 19 views

risposta

56

Come Oscar Wilde diceva

coerenza è l'ultimo rifugio del banale.

R è più di un linguaggio evoluto piuttosto che progettato, quindi queste cose accadono. names() e colnames() lavorare su un data.frame ma names() non funziona su una 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> 
+0

Grazie per la risposta con un esempio. Quindi vuol dire che è sempre conveniente usare 'colnames()' invece di 'names()'? C'è una situazione simile per i nomi delle file? –

+2

Ci sono differenze tra i tipi di dati. – Jay

+5

Emerson disse: "Una consistenza sciocca è la follia delle piccole menti, adorata da piccoli statisti, filosofi e teologi: con coerenza una grande anima non ha semplicemente nulla da fare". –

8

Giusto per espandere un po 'sull'esempio di Dirk:

Aiuta a pensare ad un frame di dati come un elenco con uguale lunghezza vettori. Questo è probabilmente il motivo per cui names funziona con un frame di dati ma non con una matrice.

L'altra funzione utile è dimnames che restituisce i nomi per ogni dimensione. Si noterà che la funzione rownames restituisce effettivamente il primo elemento da dimnames.

Per quanto riguarda rownames e row.names: non riesco a capire la differenza, anche se rownames utilizza dimnames mentre row.names è stato scritto al di fuori di R. Entrambi sembrano anche di lavorare con più elevati matrici dimensionali:

>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 
+1

Questa è una risposta migliore. Lo Snark è divertente, ma la conoscenza è più utile. un 'data.frame' è utilizzabile sia come elenco di colonne che come matrice, ovvero ogni colonna ha la stessa lunghezza ed è possibile estrarre singole righe o sottoinsiemi di righe. –

5

penso che usare colnames e rownames ha più senso; Ecco perché.

L'utilizzo di names presenta diversi svantaggi. Devi ricordare che significa "nomi di colonne" e funziona solo con il frame dei dati, quindi dovrai chiamare lo colnames ogni volta che usi le matrici. Chiamando colnames, è sufficiente ricordare una funzione. Infine, se si guarda il codice per colnames, si vedrà che chiama lo names nel caso di un frame di dati, quindi l'output è identico.

rownames e row.names restituiscono gli stessi valori per il frame di dati e le matrici; l'unica differenza che ho notato è che dove non ci sono nomi, rownames stamperà "NULL" (come fa colnames), ma row.names lo restituisce in modo invisibile. Dal momento che non c'è molto da scegliere tra le due funzioni, rownames vince sulla base dell'estetica, dal momento che si accoppia più elegantemente con colnames. (Inoltre, per il programmatore pigro, si salva un carattere di digitazione.)

2

E un'altra espansione:

# create dummy matrix 
set.seed(10) 
m <- matrix(round(runif(25, 1, 5)), 5) 
d <- as.data.frame(m) 

Se si desidera assegnare nuovi nomi delle colonne si può fare seguenti sul 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 

Se, invece esegue il comando precedente su matrix, è' ll cose incasinare:

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 

Dal matrice può b E considerato come vettore bidimensionale, assegnerai nomi solo ai primi cinque valori (non vuoi farlo, vero?). In questo caso, è necessario attenersi a colnames().

Quindi ...