【问题标题】:Fast extraction of rows in R快速提取 R 中的行
【发布时间】:2016-08-19 00:28:30
【问题描述】:

我有许多二进制矩阵,我想从中提取三行的所有可能组合到一个列表中。然后我想对每个提取的行组合的列求和。

我目前的方法如下,但速度极慢。

set.seed(123)
x <-  matrix(sample(0:1, 110 * 609, replace = TRUE), 110, 609)
row.combinations <- t(combn(nrow(x),3))
extracted.row.combns <- lapply(1:nrow(row.combinations), FUN = function(y) x[c(row.combinations[y,1],row.combinations[y,2],row.combinations[y,3]),])
summed.rows <- lapply(extracted.row.combns, colSums)

如何加快速度?

【问题讨论】:

    标签: r performance matrix combinations extraction


    【解决方案1】:

    使用?combn 和一个内联函数作为参数,我可以在我当前的机器上在 5 秒内运行这个分析:

    combn(nrow(x), 3, FUN=function(r) colSums(x[r,]), simplify=FALSE)
    

    【讨论】:

    • @ZheyuanLi - 诚然,我这里有一台相当强大的机器 :-) 216K 提取 15 秒虽然相当快。
    • 这在我的机器上似乎比较慢。 library(microbenchmark)microbenchmark( extracted.row.combns &lt;- lapply(1:nrow(row.combinations), FUN = function(y) x[c(row.combinations[y,1],row.combinations[y,2],row.combinations[y,3]),]), summed.rows &lt;- lapply(extracted.row.combns, colSums) ) # total = 4.13 msmicrobenchmark(summed.rows &lt;- combn(nrow(x), 3, FUN=function(r) colSums(x[r,]), simplify=FALSE)) # total = 5.43 ms
    • @SNSBMS1 - 5.43 毫秒?这听起来不对。此外,您的基准测试完全排除了您的 combn 调用并直接跳到第二行。
    • 糟糕,我的错。 microbenchmark( row.combinations &lt;- t(combn(nrow(x),3)), extracted.row.combns &lt;- lapply(1:nrow(row.combinations), FUN = function(y) x[c(row.combinations[y,1],row.combinations[y,2],row.combinations[y,3]),]), summed.rows &lt;- lapply(extracted.row.combns, colSums), unit = "s" ) # total = 7.3 smicrobenchmark(summed.rows &lt;- combn(nrow(x), 3, FUN=function(r) colSums(x[r,]), simplify=FALSE), unit = "s") # total = 5.34s
    【解决方案2】:

    我们可以使用来自gRbasecombnPrim 加快这一进程。

    library(gRbase)
    lapply(combnPrim(nrow(x), 3, simplify = FALSE), function(r) colSums(x[r,]))
    

    基准测试

    system.time(x1 <- combn(nrow(x), 3, FUN=function(r) colSums(x[r,]), simplify=FALSE))
    #  user  system elapsed 
    #  6.46    0.21    6.67 
    
    system.time(x2 <- lapply(combnPrim(nrow(x), 3, simplify = FALSE), 
                         function(r) colSums(x[r,])))
    # user  system elapsed 
    #  4.61    0.22    4.83 
    

    【讨论】:

    • 没听说过这个包 - 有用!尽管这在更大的矩阵上变得超级慢,例如matrix(sample(0:1, 609 * 110, replace = TRUE), 609, 110)
    • @SNSBMS1 在您发布的一个示例中,它比combn效率更高
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    相关资源
    最近更新 更多