merv 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
be, such that

> mat[my_sub]
[1] 25 36

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]
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)?

Answer Source

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)

# 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)

# 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(, L))], lengths(L))

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

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

L2 <- list(2:3, 1:2)"[", c(list(mat), L2))

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

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

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

This could be made prettier by defining:

`%[%` <- function(x, indexList)"[", 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