Reputation: 365
In MATLAB and numpy, you can index a vector by an array of indices and get a result of the same shape out, e.g.
A = [1 1 2 3 5 8 13];
B = [1 2; 2 6; 7 1; 4 4];
A(B)
## ans =
##
## 1 1
## 1 8
## 13 1
## 3 3
or
import numpy as np
a = np.array([1, 1, 2, 3, 5, 8, 13])
b = np.reshape(np.array([0, 1, 1, 5, 6, 0, 3, 3]), (4, 2))
a[b]
## array([[ 1, 1],
## [ 1, 8],
## [13, 1],
## [ 3, 3]])
However, in R, indexing a vector by an array of indices returns a vector:
a <- c(1, 1, 2, 3, 5, 8, 13)
b <- matrix(c(1, 2, 7, 4, 2, 6, 1, 4), nrow = 4)
a[b]
## [1] 1 1 13 3 1 8 1 3
Is there an idiomatic way in R to perform vectorized lookup that preserves array shape?
Upvotes: 2
Views: 142
Reputation: 3501
Option 1: if we do not need to keep the original values in b, we could simply
"Caveat: the values in b will be over-written"
b[] = a[b]
b
# [,1] [,2]
# [1,] 1 1
# [2,] 1 8
# [3,] 13 1
# [4,] 3 3
Option 2: if want to retain the values in b, An easy workaround could be
c = b # copy b to c
c[] = a[c]
c
# [,1] [,2]
# [1,] 1 1
# [2,] 1 8
# [3,] 13 1
# [4,] 3 3
Actually I found Option 2 is easy to follow and clean.
Upvotes: 1
Reputation: 52687
You can't specify dimensions through subsetting alone in R (AFAIK). Here is a workaround:
`dim<-`(a[b], dim(b))
Produces:
[,1] [,2]
[1,] 1 1
[2,] 1 8
[3,] 13 1
[4,] 3 3
dim<-(...)
just allows us to use the dimension setting function dim<-
for its result rather than side effect as is normally the case.
You can also do stuff like:
t(apply(b, 1, function(idx) a[idx]))
but that will be slow.
Upvotes: 2
Reputation: 12684
This is not very elegant, but it works
matrix(a[b],nrow=nrow(b))
Upvotes: 2