Reputation: 75
I have a simple question that I seem to not be able to wrap my head around. I have a 3D array (an image stack) and I am trying to do a projection onto 2D array (e.g. a maximum intensity projection for an image stack). To do this, I have a matrix of indices which indicate the z-stack to use for each pixel.
For example, I have a 3D array which looks like this:
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 5 7
[2,] 6 8
And a "selection matrix" which looks like this:
[,1] [,2]
[1,] 1 1
[2,] 2 2
The result of this selection should then be
[,1] [,2]
[1,] 1 3
[2,] 6 8
i.e. the matrix indicates from which "z-columns" of the array to extract the values.
I know this should be a stupid simple thing but I'm drawing a blank on how to do this. Thank you in advance!
Upvotes: 2
Views: 46
Reputation: 7445
One way to do this is to use multi-dimensional array indexing via cbind
:
Here is your data and selection matrix:
d <- array(1:8,c(2,2,2))
selec <- matrix(c(1,2,1,2),2,2)
First construct a grid of your selection matrix indices:
selec.ind <- expand.grid(1:nrow(selec),1:ncol(selec))
Then use this with the selection matrix values to access d
:
out <- matrix(d[cbind(selec.ind$Var1,selec.ind$Var2,as.vector(selec))], nrow(selec), ncol(selec))
## [,1] [,2]
##[1,] 1 3
##[2,] 6 8
Finally, reshape the result back to the size of the selection matrix.
This will work with any size selection matrix and any number of layers in z
.
Upvotes: 1
Reputation: 4761
This only works for array with 2 third dimensions (dim=c(...,...,2)
)
The data:
ar=array(data=c(1,2,3,4,5,6,7,8),dim = c(2,2,2))
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 5 7
[2,] 6 8
selec=matrix(c(1,2,1,2),nrow = 2,ncol = 2)
[,1] [,2]
[1,] 1 1
[2,] 2 2
We use ifelse
ifelse(selec==1,ar[,,1],ar[,,2])
[,1] [,2]
[1,] 1 3
[2,] 6 8
Upvotes: 0