A: What objects does the Names() attribute apply to?

Asked

Viewed 1,789 times

4

I’m a little confused by the role of attribute names() on different objects.

In addition to normal use, in data.frames, I see in the examples of help(names) which can also be used for vectors (both numerical and string) and lists. But for matrices names(M) returns NULL. See these examples:

# vetor numérico
names(islands)
islands

#vertor textual
a <- c("a","b")
names(a) <- c("Na","Nb")
a

#listas
z <- list(a = 1, b = "c", c = 1:3)
names(z)

#data.frames
x <-  data.frame(V1=c(1,2,3),V2=c(3,2,1))
names(x)
x

#matrizes:
y <- as.matrix(x)
names(y)
y

Can factors also have names? Because only matrices don’t have "Names"? colnames() and rownames() are different attributes of names()?

2 answers

3

Matrices may have names also. Almost everything can have names in the R. The simplest way to think about these issues is the following: the names refers to the name of the element of the object. AND rownames and colnames are names of dimensions of the object.

Vectors, matrices and arrays

For example, in a vector, the names assigns a name to each element vector.

x <- 1:10
names(x) <- paste0("elemento", 1:10)
x
 elemento1  elemento2  elemento3  elemento4  elemento5  elemento6  elemento7  elemento8 
         1          2          3          4          5          6          7          8 
 elemento9 elemento10 
         9         10 

And now you can use the name to select the element:

x["elemento1"]
elemento1 
        1 

An array (or an array) is nothing more than an array with a further attribute: dimensions. Let’s transform the vector x above in a 2 x 5 matrix. Now you can name all matrix elements with Names, as well as name the dimensions, that is, rows and columns, using rownames and colnames respectively:

dim(x) <- c(2, 5)
names(x) <- paste0("elemento", 1:10)
rownames(x) <- paste0("linha", 1:2)
colnames(x) <- paste0("coluna", 1:5)
x
       coluna1 coluna2 coluna3 coluna4 coluna5
linha1       1       3       5       7       9
linha2       2       4       6       8      10
attr(,"names")
 [1] "elemento1"  "elemento2"  "elemento3"  "elemento4"  "elemento5"  "elemento6" 
 [7] "elemento7"  "elemento8"  "elemento9"  "elemento10"

See that now you can subset with the names of both elements and dimensions:

x["elemento10"]
elemento10 
        10 
x[,"coluna5"]
linha1 linha2 
     9     10 

Matrices have only two dimensions. For more than two dimensions we have the array. Let’s transform the previous matrix into an array 2 X 5 x 1. With the array you can continue using rownames and colnames to name the first and second dimension. To name the third dimension, you will use dimnames:

dim(x) <- c(2, 5, 1)
names(x) <- paste0("elemento", 1:10)
rownames(x) <- paste0("linha", 1:2)
colnames(x) <- paste0("coluna", 1:5)
dimnames(x)[[3]] <- "terceira dimensão"
x
, , terceira dimensão

       coluna1 coluna2 coluna3 coluna4 coluna5
linha1       1       3       5       7       9
linha2       2       4       6       8      10

attr(,"names")
 [1] "elemento1"  "elemento2"  "elemento3"  "elemento4"  "elemento5"  "elemento6"  "elemento7"  "elemento8" 
 [9] "elemento9"  "elemento10"

The dimanames is the primitive function for dimensions. So obviously you could name both the rows and columns also with dimnames.

# Nomeando linhas e colunas usando dimnames
dimnames(x)[[1]] <- paste0("linha", 1:2)
dimnames(x)[[2]] <- paste0("coluna", 1:5)

Lists and data.frames

If you create the list z <- list(a = 1, b = "c", c = 1:3), note that its elements have the names a, b and c, and that’s what the Naames returns.

names(z)
[1] "a" "b" "c"

Data.frame is a list too, with an attribute row.names and with the restriction that all elements must have the same size. Let’s transform z in a date.frame:

z <- as.data.frame(z)
  a b c
1 1 c 1
2 1 c 2
3 1 c 3

Now it’s clear because in data.frame the names is equal to colnames. This is because data.frame is nothing more than a list and the columns are the list elements.

Finally, factors are vectors, and may have names normally.

2

Your question is related to data structures.

Look at Hadley’s book: http://adv-r.had.co.nz/Data-structures.html

names is an attribute type (which are the metadata in R), which serves to name elements of an array. Thus, you can assign names using names, both for atomic vectors (usually constructed with c()) as for lists (usually built with list()). Thus, an object with class data.frame is a list, which in turn is a vector, so it can receive the attribute names.

Matrices, however, are a special case of arrays. An array (usually consisting of array()) is a vector that has the attribute dim.

Thus, it is possible to assign names to a array or matrix, but that means assigning a name to each element, not to columns or rows. For example:

x <- matrix(c(1,2,3,4,5,6), nrow=2)
attributes(x)
names(x) <- c('a', 'b', 'c') # atribui nomes aos três primeiros elementos do array
attributes(x)
colnames(x) <- c('a', 'b', 'c') # atribui nomes das colunas do array (dimensão 2)
attributes(x)

dim(x) <- NULL # transforma a matriz em vetor atômico (os nomes são dropados)
names(x) <- c('a', 'b', 'c') # atribui nomes aos três primeiros elementos do vetor
attributes(x)

Although it is possible to assign names to each of the elements of a array, this may not be useful, which is why there are generalizations rownames and colnames.

I think now we can answer your questions.

  • A factor is an array of integer numbers with attributes class and levels. So, since it is an array, it can have yes names. See for example x <- factor(c(a='A',b='B',c='C'))
  • Matrices are not born with names probably because it is useless to name each element of the vector. You may notice that creating a matrix from a named vector, for example: matrix(c(a=1,b=2,c=3,d=4,e=5,f=5), nrow=2) throws away the attribute names. However, matrices can receive names yes.
  • colnames and rownames are in fact different attributes of names, and are on the list dimnames.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.