Using a smaller reproducible example
set.seed(123)
M <- matrix(sample(1:6, size = 10 * 5, replace = TRUE), ncol = 5)
You could try the already fully optimized matrixStats::rowRanges
function
matrixStats::rowRanges(M)
# [,1] [,2]
# [1,] 1 6
# [2,] 3 6
# [3,] 3 5
# [4,] 3 6
# [5,] 1 6
# [6,] 1 6
# [7,] 2 5
# [8,] 1 6
# [9,] 2 4
# [10,] 1 6
Or base R vectorized max.col
function
cbind(M[cbind(1:nrow(M), max.col(-M))],
M[cbind(1:nrow(M), max.col(M))])
# [,1] [,2]
# [1,] 1 6
# [2,] 3 6
# [3,] 3 5
# [4,] 3 6
# [5,] 1 6
# [6,] 1 6
# [7,] 2 5
# [8,] 1 6
# [9,] 2 4
# [10,] 1 6
Another semi-vectorized base R approach it to use pmin/pmax
combined with do.call
(which offers possible NA
handling too), but that will require converting your matrix to a data.frame
(not recommended)
DF <- as.data.frame(M)
cbind(do.call(pmin.int, c(na.rm = TRUE, DF)),
do.call(pmax.int, c(na.rm = TRUE, DF)))
# [,1] [,2]
# [1,] 1 6
# [2,] 3 6
# [3,] 3 5
# [4,] 3 6
# [5,] 1 6
# [6,] 1 6
# [7,] 2 5
# [8,] 1 6
# [9,] 2 4
# [10,] 1 6
As R being a vectorized language, by row operations will be often slow, thus either try vectorizing or use a package such as Rcpp in order to write compiled C/C++ loops (as was done in the first case)
In most radical cases, you still have hope to greatly optimize your loop using the compiler package
As regarding to your for
loop (as was already mentioned by @PereG) you have a syntax error. Instead of for(i in nrow(X))
this should be for(i in 1:nrow(X))
. Otherwise you are operating only on the last row.