Question

Let's say I have a matrix, mat.

mat <- matrix(1:5, nrow = 10, ncol = 3, byrow = TRUE)

And I have some sort of function that I want to apply, in this case by column.

getRMSE <- function(true, est) {
    sqrt(mean((true - est)^2))
}

(This function is just the most recent example, but I've had this exact same conundrum at least 5 more times.)

If you want to apply a function over a matrix, you use apply. But what if you want to apply a function over a matrix with different values for 'x' in the apply?

In this case, the goal would be that apply would perform the equivalent of this:

getRMSE(mat[,1], 1)
getRMSE(mat[,2], 2)
getRMSE(mat[,3], 3)

But I always run into problems when giving a vector as a supplementary argument to the function. Obviously

apply(mat, 2, getRMSE, c(1,2,3))

isn't going to work, because it will recycle the numbers within the columns, too. But

apply(mat, 2, getRMSE, rep(c(1,2,3), 25)) 

also doesn't work, which I thought at least had a shot.

Was it helpful?

Solution

You could use mapply where x would be your matrix column, and y the constant. I didn't bother with converting the matrix into a list the smart way, so I have to use unlist inside the function.

mat <- matrix(1:5, nrow = 10, ncol = 3, byrow = TRUE)

mat.list <- apply(mat, MARGIN = 2, FUN = list)

mapply(FUN = function(x, y) {
  sqrt(mean((unlist(x) - y)^2))
}, x = mat.list, y = list(1, 2, 3))

[1] 2.449490 1.732051 1.414214

OTHER TIPS

In this specific case, just roll the "est" values out to a matrix that matches the "true" values. Then you can subtract matrices (which R will automatically do componentwise) and use apply(), or here, colMeans():

> true <- matrix(1:5, nrow = 10, ncol = 3, byrow = TRUE)
> est <- matrix(1:3,nrow=nrow(true),ncol=ncol(true),byrow=TRUE)
> sqrt(colMeans((true-est)^2))
[1] 2.449490 1.732051 1.414214
> 

In more general cases involving lists, mapply() may be helpful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top