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 argumenti
can be a matrix with as many columns as there are dimensions ofx
; the result is then a vector with elements corresponding to the sets of indices in each row ofi
.
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
Dividing Each Cell in a Data Set by the Column Sum in R
Combining More Than 2 Columns by Removing Na's in R
Match Two Columns with Two Other Columns
Count Common Words in Two Strings
Number of Rows Each Data Frame in a List
Adding Counts of a Factor to a Dataframe
Shortcut Using Lm() in R for Formula
Remove Duplicate Rows of a Matrix or Dataframe
Include Text Control Characters in Plotmath Expressions
Print Tibble with Column Breaks as in V1.3.0
R Ggplot Ordering Bars in "Barplot-Like " Plot
How to Create a Bar and Line Plot with R Dygraphs
Create a Histogram for Weighted Values
Convert Vector to Matrix Without Recycling
How to Specify the Size/Layout of a Single Plot to Match a Certain Grid in R