R - How to Get a Value of a Multi-Dimensional Array by a Vector of Indices

R - how to get a value of a multi-dimensional array by a vector of indices

Making use of a little known usage of [:

When indexing arrays by [ a single argument i can be a matrix with as many columns as there are dimensions of x; the result is then a vector with elements corresponding to the sets of indices in each row of i.

you can simply do:

pi[matrix(indexes, 1)]

Extracting values from multidimensional array

It is quite straightforward to achieve using computing on the language.

arr <- array(NA, c(2,3,5))
getArrValues <- function(x, i) {
stopifnot(is.array(x), is.numeric(i))
if (!is.integer(i)) i = as.integer(i)
li = as.list(i)[seq_along(dim(x))]
li = lapply(li, function(x) if (!is.null(x)) x else substitute())
eval(
as.call(c(list(as.name("["), as.name("x")), li))
)
}
getArrValues(arr, c(1,2,2)) # = arr[1,2,2]
getArrValues(arr, c(1,2)) # = arr[1,2,]
getArrValues(arr, c(1)) # = arr[1,,]

Just remove eval( call to investigate exact unevaluated call.

Return Indices Of Maximum Value in a Multidimensional Array in R

This provides the answer I was looking for in the format of [x1, x2, x3] where x2=20:

which( test==max(test[,20,],na.rm=T) , arr.ind = T )

If the indices in the matrix are wanted without constraining it to a 2D by setting x2=20, you can use the below line:

which( test==max(test,na.rm=T) , arr.ind = T )

If there are multiple indices sets that have the same maximum value, you can select the first set from the list with

which( test==max(test,na.rm=T) , arr.ind = T )[1,]

Accessing multidimensional Array element by vector of it's positon

You can also index by matrix. This means that you can do

x[t(y)]
# [1] 7

This does have a different behavior if you are indexing by range however. I'm not in what context you are building the index so it's hard to say exactly what would be best for your situation.

Accessing n-dimensional array in R using a function of vector of indexes

Thanks for helpful response.

I will use the following solution:

PVALUES = array(0, dim=dimensions) #Create an n-dimensional array
dimensions = c(x,y,z,...,n)

Set a value to PVALUES[x,y,z,...,n]:

y=c(x,y,z,...,n)
PVALUES[t(y)]=26

Reading a value from PVALUES[x,y,z,...,n]:

y=c(x,y,z,...,n)
data=PVALUES[t(y)]

R use matrix to select row of multidimensional array

I don't know if something like this already exists, but as mentioned in the comments, you can make use of the dimnames of your array.

It would be best if your "my_values" object were a list, as that would give you a lot of flexibility that you won't have with a vector.

Here's a possible approach. Create a function that creates a matrix that can be used to subset from your array. The function would essentially look something like this:

mat_maker <- function(array, vals) {
x <- sapply(vals, is.null)
vals[x] <- dimnames(array)[x]
as.matrix(expand.grid(vals))
}

The extraction function would be like this. (Most likely, you would just roll both of these functions together, but I thought I would share them here separately so that you can see what is going on.)

array_extractor <- function(array, vals) {
array[mat_maker(array, vals)]
}

Now, try the following examples out. Notice that the "vals" argument is a list, and that NULL is used for dimensions that are not being specified.

## All values where rowname == "D_11"
mat_maker(my_array, list("D_11", NULL, NULL))
# Var1 Var2 Var3
# [1,] "D_11" "D_21" "D_31"
# [2,] "D_11" "D_22" "D_31"
# [3,] "D_11" "D_23" "D_31"
# [4,] "D_11" "D_21" "D_32"
# [5,] "D_11" "D_22" "D_32"
# [6,] "D_11" "D_23" "D_32"
array_extractor(my_array, list("D_11", NULL, NULL))
# [1] 1 3 5 7 9 11

## All first column values from the second array object
## This is your specific example
mat_maker(my_array, list(NULL, "D_21", "D_32"))
# Var1 Var2 Var3
# [1,] "D_11" "D_21" "D_32"
# [2,] "D_12" "D_21" "D_32"
array_extractor(my_array, list(NULL, "D_21", "D_32"))
# [1] 7 8

## First two columns from all array dimensions
array_extractor(my_array, list(NULL, c("D_21", "D_22"), NULL))
# [1] 1 2 3 4 7 8 9 10

An extension of this function would be to put the dimensional attributes (including the names) back into the output. It could look something like this:

extractMe <- function(array, vals) {
x <- sapply(vals, is.null)
vals[x] <- dimnames(array)[x]
temp <- as.matrix(expand.grid(vals))
`dimnames<-`(`dim<-`(array[temp], lengths(vals)), vals)
}

Here's the usage:

extractMe(my_array, list("D_11", NULL, NULL))
# , , D_31
#
# D_21 D_22 D_23
# D_11 1 3 5
#
# , , D_32
#
# D_21 D_22 D_23
# D_11 7 9 11

extractMe(my_array, list(NULL, "D_21", "D_32"))
# , , D_32
#
# D_21
# D_11 7
# D_12 8

extractMe(my_array, list(NULL, c("D_21", "D_22"), NULL))
# , , D_31
#
# D_21 D_22
# D_11 1 3
# D_12 2 4
#
# , , D_32
#
# D_21 D_22
# D_11 7 9
# D_12 8 10

And, for cases where you want just a vector of the values, just wrap it with c:

c(extractMe(my_array, list(NULL, "D_21", "D_32")))
# [1] 7 8


Related Topics



Leave a reply



Submit