merv - 27 days ago 9

R Question

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

`my_sub`

`> mat[my_sub]`

[1] 25 36

A

`list`

I know I can access the matrix via vector addressing, which means converting from

`[2:3, 2]`

`c(5, 6)`

`[2:3, 2]`

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