Karl Broman was surprised that x[[c(5, 3)]]
in R was the same as x[[5]][[3]]
. And it was in 2013. It reminded me of a similar thing that surprised me a couple of months ago. I have used R for more than 10 years, and for the first time I had discovered that for a matrix x
and a two-column integer index matrix i
(each row of i
is a pair of row and column indices to index x
), x[i]
returns the vector c(x[i[1, 1], i[1, 2]], x[i[2, 1], i[2, 2]], ..., x[i[n, 1], i[n, 2]])
. Actually I had been searching for this way of indexing for years, and I didn’t know it was this simple! In the past, I was using an awkward loop like:
n = nrow(i)
y = numeric(n)
for (k in seq_len(n)) {
y[k] = x[i[k, 1], i[k, 2]]
}
y
That was both ugly and inefficient. After someone asked me this question again a couple of months ago, I came up with a slightly more elegant solution but perhaps even more inefficient:
diag(x[i[, 1], i[, 2]])
The perfect answer is x[i]
, both elegant and efficient. I learned this from another person’s answer to the same question. Then I looked at the help page ?`[`
, and realized it was well-documented:
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
.
The example I gave above was just a special case: x
could be an array of more than two dimensions, and does not have to be a matrix (a matrix is a special case of an array).
R help pages have too much hidden power. You have to carefully unfold and read them.