使用带有 Rcpp 的名称填充矩阵

Fill matrix using names with Rcpp

假设向量的命名元素 - 存储在列表中 - 应该分配给矩阵的匹配列(参见下面的示例)。

library(microbenchmark)
set.seed(123)
myList <- list()
for(i in 1:10000) {
 myList[[i]] <- list(sample(setNames(rnorm(5), sample(LETTERS[1:5])), ceiling(runif(1,1,4))))
}

myMatrix <- matrix(NA, ncol = 5, nrow = 10000)
colnames(myMatrix) <- LETTERS[1:5]
for(i in 1:10000) {
 myMatrix[i, match(names(myList[[i]][[1]]), colnames(myMatrix))] <- myList[[i]][[1]] 
}
myList[[6]][[1]]
myMatrix[6,]

microbenchmark(for(i in 1:10000) {myMatrix[i, match(names(myList[[i]][[1]]), colnames(myMatrix))] <- myList[[i]][[1]]}, times = 10)

在此示例中,将 10,000 个向量的元素分配给矩阵的匹配列。

问题

作业很慢(大约3.5秒)!

问题

如何在 R 或 Rcpp 中加快此过程?

使用包 data.table 中的 rbindlist。它可以通过匹配列名来绑定。

library(microbenchmark)
n <- 10000
set.seed(123)
myList <- list()
for(i in 1:n) {
  myList[[i]] <- list(sample(setNames(rnorm(5), sample(LETTERS[1:5])), ceiling(runif(1,1,4))))
}

myMatrix <- matrix(NA, ncol = 5, nrow = n)
colnames(myMatrix) <- LETTERS[1:5]

library(data.table)
microbenchmark(match = for(i in 1:n) {myMatrix[i, match(names(myList[[i]][[1]]), colnames(myMatrix))] <- myList[[i]][[1]]}, 
               rbindlist = {
                 myMatrix1 <- as.matrix(rbindlist(lapply(myList, 
                                                         function(x) as.list(unlist(x))), 
                                                  fill = TRUE))
                 myMatrix1 <- myMatrix1[, order(colnames(myMatrix1))]
                 },
               times = 10)
#Unit: milliseconds
#     expr        min         lq       mean     median         uq        max neval cld
#    match 1392.52949 1496.40382 1599.63584 1605.39080 1690.98410 1761.67322    10   b
#rbindlist   48.76146   50.29176   51.66355   51.10672   53.75465   54.93798    10  a

all.equal(myMatrix, myMatrix1)
#TRUE