[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!
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!
programmatically i would prefer the
names(dimnames(...)) <- ...
version@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!
@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 🙂