推荐使用相同索引向量对两个向量进行子集化的方法

标签 r performance memory indexing subset

我正在寻找一种有效的方法来对具有相同索引向量的两个向量进行子集化。有效的类别可以是:

  • 错别字保存
  • 内存消耗
  • 可读性
  • 计算时间

  • 假设我有两个向量 xy
    x <- 1:10
    y <- 10:1
    

    我想覆盖 x 的值与 y 的那些当x小于 y .我可以用(1)做到这一点:
    x[x < y] <- y[x < y]
    

    但是这里我要写x < y两次,有错字的缺点是什么,在进行更新时,我可能会忘记在双方都这样做。所以我可以创建一个索引向量(2):
    idx <- x < y
    x[idx] <- y[idx]
    rm(idx)
    

    但在这里我创建了一个额外的向量,它可能需要内存和时间。我也可以使用 for-loop (3):
    for(i in seq_along(x)) {
       if(x[i] < y[i]) x[i] <- y[i]
    }
    

    这可能很慢,我不知道 seq_along(x)分配内存与否。
    我可以用 delayedAssign在像(4)这样的环境中:
    (function() {
      delayedAssign("idx", x < y)
      x[idx] <<- y[idx]
    })()
    

    或 (5):
    evalq({
      delayedAssign("idx", x < y)
      x[idx] <<- y[idx]}, envir = new.env(), enclos = parent.frame())
    

    希望在哪里delayedAssign不会创建 idx内存中的向量。基础中已经存在其他几种可能性,例如:
    x <- ifelse(x < y, y, x) #(6)
    x <- sapply(seq_along(x), function(i) {if(x[i] < y[i]) y[i] else x[i]}) #(7)
    with(data.frame(idx = x < y), x[idx] <<- y[idx]) #(8)
    
    x < y可以换成which(x < y)什么可以减少矢量大小并改善execution time .

    最后,我对所有这些方法都不满意。

    有没有推荐的方法用一个索引向量对两个向量进行子集化?对我来说,打字保存和内存消耗比执行时间更重要。

    有没有办法在执行期间查看不同方法的内存消耗,例如使用 microbenchmark查看执行时间,还是只能通过创建巨大的向量并查看系统进程来完成?

    最佳答案

    […] But here I create an additional vector



    不你不是。事实上,您创建的向量比之前的代码少一个,因为您只计算 x < y一次而不是两次。

    顺便说一句,我会看到任何显式使用 rm在代码中作为代码气味。相反,限制计算的范围,以便 idx变量是短暂的。要明确地实现这一点,您可以使用 local 1:
    x = local({
        idx = x < y
        x[idx] = y[idx]
    })
    

    (但如图所示,这将需要重新分配给 x,这会导致另一个 R 不太可能优化掉的副本;替代方法是通过 <<-assignlocal 调用中使用全局重新分配。 )

    […] where I hope that delayedAssign does not create an idxvector in memory



    再次,是什么让你这么想?当然,它会在内存中创建一个向量——毕竟,您随后会使用它。您可能会认为计算是惰性执行的,但 R 最近通过 ALTREP 获得了此功能。 ,很少有这种表达式是自动创建的,它们在这里不相关。

    1 您对 evalq 的使用是相似的,只是更复杂。 localeval.parent(quote(…)) 周围的便利包装器.

    关于推荐使用相同索引向量对两个向量进行子集化的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56752595/

    相关文章:

    r - 在 R 中修剪长字符向量的更快方法

    r - knit HTML 不会将 html 保存在vignettes/中

    java - 以大 O 表示法计算运行时间

    ios - UIViewController 已正确释放,但其 UIView 未正确释放?

    c - 释放树中动态分配的内存

    javascript - 使用 R 从带有 JavaScript 按钮的 ASP.NET 网页中抓取表格

    r - ggplot2中根据高度的条形颜色

    MySQL:在一列中存储多个 boolean 值。一个 tinyint(4) -vs- 几个 tinyint(4)

    html - 优化多个 HTML5 视频

    java - 当间接在数组中时,字节原语是否会成为内存中的字节?