Home > Back-end >  Fast way to swap a matrix of indices with their corresponding values in R
Fast way to swap a matrix of indices with their corresponding values in R

Time:08-24

I have a 20000x100 matrix that stores index numbers ranging from 1 to 40000. I want to switch the indices with their corresponding values. I store index-value couples in another data table. As it takes a lot of time and I need to repeat this process with different set of values I want to learn the fastest way to do this switching process.

A reproducible example (very slow):

set.seed(42)
bigmatrix = matrix(round(runif(20, 1, 100)), ncol = 5)

# bigmatrix
#     [,1] [,2] [,3] [,4] [,5]
#[1,]   92   65   66   94   98
#[2,]   94   52   71   26   13
#[3,]   29   74   46   47   48
#[4,]   83   14   72   94   56


couples = data.frame(id = c(1:100),
                     val = runif(100))
# head(couples)
# id        val
# 1  1 0.90403139
# 2  2 0.13871017
# 3  3 0.98889173
# 4  4 0.94666823
# 5  5 0.08243756
# 6  6 0.51421178

for (i in c(1:nrow(bigmatrix))) {
    for (j in c(1:ncol(bigmatrix))) {
        bigmatrix[i, j] <- couples[couples$id == bigmatrix[i, j], ]$val
    }
} 

# bigmatrix

#          [,1]      [,2]         [,3]      [,4]      [,5]
# [1,] 0.8368016 0.7758234 0.5636468416 0.4527316 0.3556660
# [2,] 0.4527316 0.1404791 0.6674265147 0.9575766 0.3881083
# [3,] 0.9709666 0.9330341 0.1894739354 0.2712866 0.8281585
# [4,] 0.2165673 0.6851697 0.0002388966 0.4527316 0.7193558

edit: I can also arrange the couples data such that it is a list of numbers with list[index] = val but if there is a way to do it without any for loops it would be great.

CodePudding user response:

Try

matrix(
  couples$val[match(bigmatrix,couples$id)],
  nrow=nrow(bigmatrix)
)

          [,1]      [,2]         [,3]      [,4]      [,5]
[1,] 0.8368016 0.7758234 0.5636468416 0.4527316 0.3556660
[2,] 0.4527316 0.1404791 0.6674265147 0.9575766 0.3881083
[3,] 0.9709666 0.9330341 0.1894739354 0.2712866 0.8281585
[4,] 0.2165673 0.6851697 0.0002388966 0.4527316 0.7193558

CodePudding user response:

This should be fast:

library(data.table)
setDT(couples, key = 'id')
bigmatrix[] <- couples[c(bigmatrix)]$val

#           [,1]      [,2]         [,3]      [,4]      [,5]
# [1,] 0.8368016 0.7758234 0.5636468416 0.4527316 0.3556660
# [2,] 0.4527316 0.1404791 0.6674265147 0.9575766 0.3881083
# [3,] 0.9709666 0.9330341 0.1894739354 0.2712866 0.8281585
# [4,] 0.2165673 0.6851697 0.0002388966 0.4527316 0.7193558
  • Related