Is there a standard attribute for the names of the dimensions of an array? (eg 3D array -> 3 names)

[Edit: I think R itself suggests the answer; see below.]

Suppose I have a 3D array such as

myarray <- array(1:8, dim=c(2,2,2), dimnames=list(letters[1:2], letters[3:4], letters[5:6]))
myarray
## , , e
##   c d
## a 1 3
## b 2 4
##
## , , f
##   c d
## a 5 7
## b 6 8

I would like to name its three dimensions, for example 'X', 'Y', 'Z'. Note the difference with naming the values of each dimension, which is what dimnames already does.

I suppose I could either just add a custom attribute, eg dimensions:

attr(myarray, 'dimensions') <- c('X','Y','Z')

str(myarray)
## int [1:2, 1:2, 1:2] 1 2 3 4 5 6 7 8
## - attr(*, "dimnames")=List of 3
##  ..$ : chr [1:2] "a" "b"
##  ..$ : chr [1:2] "c" "d"
##  ..$ : chr [1:2] "e" "f"
## - attr(*, "dimensions")= chr [1:3] "X" "Y" "Z"

or I could name the existing dimnames attribute:

names(dimnames(myarray)) <- c('X', 'Y', 'Z')

str(myarray)
## int [1:2, 1:2, 1:2] 1 2 3 4 5 6 7 8
## - attr(*, "dimnames")=List of 3
##  ..$ X: chr [1:2] "a" "b"
##  ..$ Y: chr [1:2] "c" "d"
##  ..$ Z: chr [1:2] "e" "f"

My question is: Is there a standard R attribute already designed for this? Or, if not, do you see any advantage in either approach above over the other? Or can think of a better approach? Cheers!

Edit: As an example application, one might want to use apply on some of the dimensions of the array, and having character names may provide for a user-friendlier interface. For instance, myarray could be an array of frequencies over three variates 'X', 'Y', 'Z'. One might want the array of marginal frequencies for the variates 'X', 'Z', marginalizing out 'Y':

indices <- match(c('X','Z'), names(dimnames(myarray)))

apply(myarray, indices, sum)
##    Z
## X   e  f
##   a 4 12
##   b 6 14

Edit 2: The help of apply says, about the MARGIN argument:

Where X has named dimnames, it can be a character vector selecting dimension names.

So it looks like names(dimnames(...)) <- ... is the way to go!

  • 3

    array(1:8, dim=c(2,2,2), dimnames=list(x = letters[1:2], y = letters[3:4], z = letters[5:6]))

    – 

  • @rawr great, even better, cheers!

    – 

  • 2

    programmatically i would prefer the names(dimnames(...)) <- ... version

    – 

  • 1

    @pglpm great that you found some solutions – its better practice on SO to post the solution as an answer yourself as opposed to edit your question. This will help others in the future. Glad you got what you needed!

    – 




  • 1

    @jpsmith Completely agree, I just wanted to wait a little in case someone wrote a more complete and informative solution, maybe mentioning other aspects of R I didin’t know about 🙂

    – 

Leave a Comment