How to insert values ​​from a vector into a matrix using column order?

I want to insert a set of n values ​​expressed as a vector into the corresponding set of places in the matrix. The real application includes inserting a set of sea surface temperature values ​​n into the image of the region, which is presented in the form of a grid with a size nkn x ncol> n, for which I have identified n water pixels that should receive temperature values, The problem I'm faced, lies in the fact that the temperature values ​​are ordered as if they were from the main matrix of the column, and not to order the rows, to index the grid R.

Here is an example of a toy that 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 will be sooner:

  [,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 believe that I could play with the transpose of the grid by performing a permutation and then moving it back, but I think that would be a better way to approach this problem.

+7
r matrix-indexing
source share
4 answers

Here are a couple of options, each of which works with 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 
+6
source share

One way to do this is to create a new matrix with the required data by specifying byrow=TRUE when it is created. To do this, you need to create an intermediate vector for storing and modifying the grid data:

 grid <- matrix(rep(0,16),ncol=4) ## temps <- c(9,9,9,9,9) locs <- c(2,3,4,6,7) ## #vgrid <- as.numeric(grid) vgrid <- c(grid) vgrid[locs] <- temps ## > matrix(vgrid,ncol=ncol(grid),byrow=TRUE) [,1] [,2] [,3] [,4] [1,] 0 9 9 9 [2,] 0 9 9 0 [3,] 0 0 0 0 [4,] 0 0 0 0 
+3
source share

If you have a square matrix, you can write a small 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, it's a little more complicated.

+3
source share

You can do some work with indexes. First, we create a sequence of matrix lengths by the number of columns. Then we iteratively add 1 to the sequence. We do this for the number of rows. Then a subset of this vector for the location vector will give us the location in the matrix.

 x <- seq(1, length(grid), ncol(grid)) grid[sapply(0:(nrow(grid)-1), "+", x)[locs]] <- 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 
+3
source share

All Articles