简体   繁体   中英

R apply on a matrix a function of columns and row index

I would like to apply on a matrix a function of both the value, the row index and the column index for every value in the matrix and get the transformed matrix. For example

mat<-matrix(c(1,2,3,4),2,2)    
mat
     [,1] [,2]
[1,]    1    3
[2,]    2    4

f<-function(x,i,j){x+i+j}
mat2 <- my.apply(f,mat)
mat2
     [,1] [,2]
[1,]    3    6
[2,]    5    8

The example above is for illustration purposes, f can be much more complex.

apply does not do the job, because of the way the extra arguments are handled.

apply(mat,1:2,f,seq_along(mat[,1]),seq_along(mat[1,]))
, , 1

     [,1] [,2]
[1,]    3    4
[2,]    5    6

, , 2

     [,1] [,2]
[1,]    5    6
[2,]    7    8

I can not find either a way with the lapply family. A for loop can do the job but it won't be efficient nor elegant. Any suggestions? Thanks

Try mapply

mat <- matrix(c(1, 2, 3, 4), 2, 2)
mat
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4


matrix(mapply(function(x, i, j) x + i + j, mat, row(mat), col(mat)), nrow = nrow(mat))
##      [,1] [,2]
## [1,]    3    6
## [2,]    5    8

Here is an ugly use of apply, just for some quick and dirty job. The trick is adding an additional column (or row) for row (or column) indices.

mat <- matrix(c(1, 2, 3, 4), 2, 2)
t(apply(cbind(mat, 1:nrow(mat)), 1, function(x){x[1:ncol(mat)] + 1:ncol(mat) + x[ncol(mat)+1]}))
##     [,1] [,2]
##[1,]    3    5
##[2,]    6    8

If you have a function f(x, i, j) already, you can also try:

apply(cbind(mat, 1:nrow(mat)), 1, function(x){a = numeric(); for(j in 1:ncol(mat)){a[j] = f(x[j], x[ncol(mat)+1], j)}; a})

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