merv - 5 months ago 29
R Question

# How to store multidimensional subscript as variable in R

Suppose I have a matrix,

``````mat <- matrix((1:9)^2, 3, 3)
``````

I can slice the matrix like so

``````> mat[2:3, 2]
[1] 25 36
``````

How does one store the subscript as a variable? That is, what should
`my_sub`
be, such that

``````> mat[my_sub]
[1] 25 36
``````

A
`list`
gets "invalid subscript type" error. A vector will lose the multidimensionality. Seems like such a basic operation to not have a primitive type that fits this usage.

I know I can access the matrix via vector addressing, which means converting from
`[2:3, 2]`
to
`c(5, 6)`
, but that mapping presumes knowledge of matrix shape. What if I simply want
`[2:3, 2]`
for any matrix shape (assuming it is at least those dimensions)?

Here are some alternatives. They both generalize to higher dimenional arrays.

1) matrix subscripting If the indexes are all scalar except possibly one, as in the question, then:

``````mi <- cbind(2:3, 2)
mat[mi]

# test
identical(mat[mi],   mat[2:3, 2])
## [1] TRUE
``````

In higher dimensions:

``````a <- array(1:24, 2:4)
mi <- cbind(2, 2:3, 3)
a[mi]

# test
identical(a[mi],   a[2, 2:3, 3])
## [1] TRUE
``````

It would be possible to extend this to eliminate the scalar restriction using:

``````L <- list(2:3, 2:3)
array(mat[as.matrix(do.call(expand.grid, L))], lengths(L))
``````

however, in light of (2) which also uses `do.call` but avoids the need for `expand.grid` it seems unnecessarily complex.

2) do.call This approach does not have the scalar limitation. `mat` and `a` are from above:

``````L2 <- list(2:3, 1:2)
do.call("[", c(list(mat), L2))

# test
identical(do.call("[", c(list(mat), L2)),   mat[2:3, 1:2])
## [1] TRUE

L3 <- list(2, 2:3, 3:4)
do.call("[", c(list(a), L3))

# test
identical(do.call("[", c(list(a), L3)),   a[2, 2:3, 3:4])
## [1] TRUE
``````

This could be made prettier by defining:

```````%[%` <- function(x, indexList) do.call("[", c(list(x), indexList))
mat %[% list(2:3, 1:2)
a %[% list(2, 2:3, 3:4)
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download