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