I want to insert a set of n values expressed as a vector into a corresponding set of locations in a matrix. The real-world application involves inserting a set of n sea surface temperature values into an image of a region that is represented as a grid with dimension nrow x ncol > n in for which I have identified the n water pixels that should receive the temperature values. The problem I've run into is that the temperature values are ordered as if they were from a column-major matrix rather than the row-major ordering used to index the R grid.
Here is a toy example of what I mean.
> grid <- matrix(0,4,4)
> grid # define the base grid
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 0 0 0 0
[3,] 0 0 0 0
[4,] 0 0 0 0
> temps <- c(9,9,9,9,9) # we have 5 temperature values
> locs <- c(2,3,4,6,7) # locations in the base grid that are water
> grid[locs] <- temps # not really what I want - substitution in row-major order
> grid
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 9 9 0 0
[3,] 9 9 0 0
[4,] 9 0 0 0
The desired result would be rather:
[,1] [,2] [,3] [,4]
[1,] 0 9 9 9
[2,] 0 9 9 0
[3,] 0 0 0 0
[4,] 0 0 0 0
I suppose I could play with transposing the grid, doing the substitution and then transposing it back, but I'd think there would be a better way to approach this problem.
Here are a couple of options, each of which works on matrices of arbitrary dimension:
arrayIndByRow <- function(ind, dim) {
arrayInd(ind, rev(dim))[,2:1]
}
grid[arrayIndByRow(locs, dim(grid))] <- temps
grid
# [,1] [,2] [,3] [,4]
# [1,] 0 9 9 9
# [2,] 0 9 9 0
# [3,] 0 0 0 0
# [4,] 0 0 0 0
f <- function(ind, dim) {
nr <- dim[1]
nc <- dim[2]
ii <- ind - 1
((ii %/% nc) + 1) + nr*(ii %% nc)
}
grid[f(locs, dim(grid))] <- 1:5
grid
# [,1] [,2] [,3] [,4]
# [1,] 0 1 2 3
# [2,] 0 4 5 0
# [3,] 0 0 0 0
# [4,] 0 0 0 0
If you have a square matrix, you could write a little modulo function that replaces your numbers with the correct ones:
new_num <- function(x,num_rows){
x = x - 1
row <- x %/% num_rows
column <- x %% num_rows
newnum <- column * num_rows + row + 1
return(newnum)
}
temps <- c(9,9,9,9,9)
locs <- c(2,3,4,6,7)
new_locs <- new_num(locs,4)
M <- matrix(0,4,4)
M[new_locs] <- temps
You can do this with a non-square matrix too, it's just a bit harder.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With