Jim Slonder Jim Slonder - 1 month ago 5
R Question

Using mapply over a matrix when the function makes use of elemets' location in the matrix

I want to use

mapply
to apply
fun
to all elements of a matrix. I'm not sure how to use
mapply
when the function to be applied makes use of each elements' location in the matrix.

fun <- function(theta, mat, i, j){
sum_nearby <- function(mat,i,j,dist){
if (j - dist < 1) mat[i, j + dist]
else if (j + dist > ncol(mat)) mat[i, j - dist]
else mat[i, j - dist] + mat[i, j + dist]
}
g0 <- -2*mat[i,j]
g1 <- g0*sum_nearby(mat,i,j,1)

-log1p(exp(theta %*% c(g0, g1)))
}

Answer

Try mapply over the row and column indices like this where fun is the function defined in the question. The result is a numeric vector v:

# test inputs
theta <- 1:2
mat <- as.matrix(BOD)

v <- mapply(fun, row(mat), col(mat), MoreArgs = list(theta = theta, mat = mat))

Then it can be summed like this sum(v) or reshaped into a matrix with the same dimensions as mat like this: replace(mat, TRUE, v) or array(v, dim(mat)) or matrix(v, nrow(mat)) or 0*mat+v

Note: Alternatives would be to use outer returning a matrix having the same dimensions as mat:

outer(1:nrow(mat), 1:ncol(mat), Vectorize(function(i, j) fun(theta, mat, i, j)))

or apply returning a vector as in mapply solution above:

apply(cbind(c(row(mat)), c(col(mat))), 1, function(ix) fun(theta, mat, ix[1], ix[2]))