I’m finding inconsistent results when executing the function below for a vector of inputs. It appears that the output columns are re-ordered when the vectorized input is used. Is there a better way to vectorize this function?
func <- function(t, alpha) { exp(matrix(-rep(t,7), ncol=7)*1:7*alpha) }
# correct
rbind(func(3, 0.02), func(4, 0.02))
#incorrect
func(c(3, 4), 0.02)
> rbind(func(3, 0.02), func(4, 0.02))
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0.9417645 0.8869204 0.8352702 0.7866279 0.7408182 0.6976763 0.6570468
[2,] 0.9231163 0.8521438 0.7866279 0.7261490 0.6703200 0.6187834 0.5712091
> func(c(3, 4), 0.02)
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0.9417645 0.8352702 0.7408182 0.6570468 0.8869204 0.7866279 0.6976763
[2,] 0.8521438 0.7261490 0.6187834 0.9231163 0.7866279 0.6703200 0.5712091
There’s nothing incorrect or inconsistent about the results, only your understanding of R’s recycling rules and how element-by-element operations are applied. 😉
R stores and operates on objects in column-major order (including recycling rules). Your example would only work if R were row-major order. Column-major ordering means
matrix(-rep(t,7), ncol=7)*1:7produces results like:This is because, internally, a matrix is just a vector with
dimattribute. You can see this by running:See how the first two elements of the vector are the first column of the matrix? That’s why you get “inconsistent” results when you multiply by
1:7. You’re really asking R to do:Turn it back into a “matrix” via:
If you want to take advantage of the recycling rules, you need to start with the transpose of your current matrix. Then multiply by
1:7and transpose that result. Speaking of transpose, you may want to avoid naming variablest, since that’s the name of the transpose function.