简体   繁体   中英

Multiply elements of a matrix with vector values

I have a matrix M, I want to create 3 additional matrices where each additional matrix has certain 3x3 column-slices of M multiplied by values in a vector, I will then store the resulting 3 new matrices in a list .

##create the initial matrix
M <- matrix(1:20, nrow = 4)

    [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

## coordinates in the matrix I want to alter 
iy <- c(1, 2, 3)
ix <- c(1, 4, 5)
coords <- as.data.frame(cbind(ix, iy))


## multiplier values
multis <- c(0.1, 2, 100)

Pseudo code of what I want to do

mapply (function(multis, cords) {multis * M[coords$iy, coords$ix]})

what the result should look like

  [[1]]
     [,1] [,2] [,3] [,4] [,5]
[1,]  0.1    5    9 13.0 17.0
[2,]  2.0    6   10  1.4 18.0
[3,]  3.0    7   11 15.0  1.1
[4,]  4.0    8   12 16.0 20.0

[[2]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    2    5    9   13   17
[2,]    2    6   10   28   18
[3,]    3    7   11   15   38
[4,]    4    8   12   16   20

[[3]]
[,1] [,2] [,3] [,4] [,5]
[1,]  100    5    9   13   17
[2,]    2    6   10 1400   18
[3,]    3    7   11   15 1900
[4,]    4    8   12   16   20

First you need to coerce coords to a matrix for indexing, then reverse the column order. Then it's just a simple lapply() loop.

coords <- as.matrix(coords)[, 2:1]
lapply(multis, function(x) {
    M[coords] <- M[coords] * x
    M
})

resulting in

[[1]]
     [,1] [,2] [,3] [,4] [,5]
[1,]  0.1    5    9 13.0 17.0
[2,]  2.0    6   10  1.4 18.0
[3,]  3.0    7   11 15.0  1.9
[4,]  4.0    8   12 16.0 20.0

[[2]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    2    5    9   13   17
[2,]    2    6   10   28   18
[3,]    3    7   11   15   38
[4,]    4    8   12   16   20

[[3]]
     [,1] [,2] [,3] [,4] [,5]
[1,]  100    5    9   13   17
[2,]    2    6   10 1400   18
[3,]    3    7   11   15 1900
[4,]    4    8   12   16   20

Another solution is to use a defined function and use a sapply for each multis :

##create the initial matrix
M <- matrix(1:20, nrow = 4)

## coordinates in the matrix I want to alter 
Y <- c(1, 2, 3)
X <- c(1, 4, 5)
coords <- as.data.frame(cbind(X, Y))

## multiplier values
multis <- c(0.1, 2, 100)

## Modifying the specific coordinates.
modif.one.matrix <- function(one_multis, coords, M) {
    M_out <- M
    for(one_coord in 1:nrow(coords)) {
        M_out[coords$Y[one_coord], coords$X[one_coord]] <- M[coords$Y[one_coord], coords$X[one_coord]] * one_multis
    }
    return(M_out)
}

## Modifying one matrix
modif.one.matrix(multis[1], coords, M)
#     [,1] [,2] [,3] [,4] [,5]
#[1,]  0.1    5    9 13.0 17.0
#[2,]  2.0    6   10  1.4 18.0
#[3,]  3.0    7   11 15.0  1.9
#[4,]  4.0    8   12 16.0 20.0

## Modifying all the matrices
sapply(multis, modif.one.matrix, coords, M, simplify = FALSE)

#[[1]]
#     [,1] [,2] [,3] [,4] [,5]
#[1,]  0.1    5    9 13.0 17.0
#[2,]  2.0    6   10  1.4 18.0
#[3,]  3.0    7   11 15.0  1.9
#[4,]  4.0    8   12 16.0 20.0
#
#[[2]]
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    2    5    9   13   17
#[2,]    2    6   10   28   18
#[3,]    3    7   11   15   38
#[4,]    4    8   12   16   20
#
#[[3]]
#     [,1] [,2] [,3] [,4] [,5]
#[1,]  100    5    9   13   17
#[2,]    2    6   10 1400   18
#[3,]    3    7   11   15 1900
#[4,]    4    8   12   16   20

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM