1

I want to take a vector describing the location of a cell in an array, ie "x=c(row, column)", and return the scalar index of that location. While this can be done with arithmetic, I'm trying to keep my code relatively easily to read. It seems weird to me that arrayInd will turn your scalar index into a location vector, but I can't turn a location vector back into a scalar index.

Example code:

x <- array(seq(0.1,2.7,1), dim=c(3,3,3))
locVec <- c(3,1,1)
mysteryFunc(locVec)

which would return 3.

arrayInd(x[[mysteryFunc(locVec)]], .dim=dim(x)) 

returns locVec

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • Can you show a small example. Perhaps you need to use `cbind` i.e. `df1[cbind(row, column)]` – akrun Sep 09 '20 at 03:04
  • It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Sep 09 '20 at 03:04
  • 1
    It would be good if you could add some examples to make this clearer. While that duplicate covers the same ground, it is hard to follow at best. Here's an attempt at data: `mat <- matrix(1:10, ncol=2); sca <- (5:8); loc <- (arrayInd(sca, .dim=dim(mat)));` and an answer - `replace(mat, , seq_along(mat))[loc]` – thelatemail Sep 09 '20 at 03:24
  • 1
    Yep, code above still works, just need to make sure that `locVec` is a matrix - `replace(x, , seq_along(x))[ matrix(locVec, nrow=1) ]` – thelatemail Sep 09 '20 at 04:01

1 Answers1

0

Upgrading my comment to an answer since this has got no attention for months, and the previously suggested duplicate seems rather difficult to follow.

Using your example array x, you can replace the whole object with a sequence from 1 to length(x) via seq_along(x), then use a matrix containing the indexes (row/col/stratum/etc...) to extract the index. E.g.:

locVec <- c(3,1,1)
replace(x, , seq_along(x))[ matrix(locVec, nrow=1) ]
#[1] 3

Which matches your expected output. You can do this for multiple values too by adding more rows to your matrix selection:

locMat <- matrix(c(3,1,1,2,2,2), nrow=2, byrow=TRUE)
locMat
#     row  col  stratum
#     [,1] [,2] [,3]
#[1,]    3    1    1
#[2,]    2    2    2

replace(x, , seq_along(x))[ locMat ]
#[1]  3 14

If you want to package it up as a nice function:

Indarray <- function(x, i) replace(x, , seq_along(x))[ i ]
Indarray(x, locMat)
#[1]  3 14
thelatemail
  • 91,185
  • 12
  • 128
  • 188