从 R 中的大型矩阵或 data.table 中按索引提取单行的最快方法?

nag*_*emi 1 database r matrix data.table

目标背景:
我需要对具有数百万行的大型 R 对象的特定单独行执行计算。这些计算涉及一系列矩阵乘法。这些计算本身经过优化,可以快速运行,并且我的代码的进一步优化需要克服快速选择我们将执行计算的行的瓶颈。

问题:
我找到的用于从 data.table 或其他 R 对象中选择特定行的每个方法的运行速度都比我在该行上执行的计算慢得多。这里有一个有点类似的问题(R中矩阵的快速子集),推荐的解决方案是在Rcpp中对矩阵本身进行计算,而不提取行。这需要我用 C++ 重写所有计算,如果有足够有效的方法在 R 中按索引对行进行子集化,我希望避免这种情况。

示例代码

library(dplyr)
library(data.table)
data(mtcars) # for a replicable example

mtcars_data_table <- as.data.table(mtcars) # Convert to data.table
rownames(mtcars) <- seq(1, nrow(mtcars)) # Change row names to numerical index for each row

i = 1 # Set a dummy iterator variable to one to demonstrate code as it would be used inside a for loop

microbenchmark(mtcars_data_table[i,], times=10000) # The data.frame way
microbenchmark(mtcars_data_table[i], times=10000) # The data.table way
microbenchmark(slice(mtcars_data_table, i), times=10000) # The dplyr way
Run Code Online (Sandbox Code Playgroud)

结果示例:

Unit: microseconds
                   expr     min      lq     mean   median       uq      max neval
 mtcars_data_table[i, ] 238.923 255.494 282.0608 264.7255 281.4325 24862.53 10000
 mtcars_data_table[i] 235.83 249.797 296.2472 255.278 264.972 325892.1 10000
 slice(mtcars_data_table, i) 583.154 618.833 642.1725 630.209 639.1015 8099.179 10000
Run Code Online (Sandbox Code Playgroud)

寻求帮助: 最快的方法的运行时间比对行执行的计算要长一个数量级。如果我不能解决这个瓶颈,我就不能使用 R 来解决这个问题。R中有更快的方法吗?如果 R 中没有比所示方法更快的方法,那么是否有使用 Python 的更快方法?

注意:计算本身没有显示,因为我认为它们与问题无关,但它们与用于矩阵形式的多元线性回归的矩阵乘法非常相似。

Tho*_*ing 5

我认为你可以尝试矩阵方式:

t(mtcars_data_table)[,i]
Run Code Online (Sandbox Code Playgroud)

基准

microbenchmark(mtcars_data_table[i,], # The data.frame way 
               mtcars_data_table[i], # The data.table way
               slice(mtcars_data_table, i), # The dplyr way
               t(mtcars_data_table)[,i], # the matrix way
               times=1000,
               unit = "relative")
Run Code Online (Sandbox Code Playgroud)

这样

Unit: relative
                        expr       min       lq     mean   median       uq      max neval
      mtcars_data_table[i, ] 13.584019 9.782873 9.453554 9.368050 9.408398 1.715470  1000
        mtcars_data_table[i] 13.593420 9.795455 9.288266 9.276130 9.445648 1.353841  1000
 slice(mtcars_data_table, i)  5.024677 4.046672 3.798823 3.848777 3.832374 1.447337  1000
   t(mtcars_data_table)[, i]  1.000000 1.000000 1.000000 1.000000 1.000000 1.000000  1000
Run Code Online (Sandbox Code Playgroud)