【问题标题】:get element index inside apply在apply中获取元素索引
【发布时间】:2014-01-15 19:51:59
【问题描述】:

我有一个网格。对于网格的每个元素,我根据它们的内容绘制符号。我做到了:

for (i in 1:nx) { # to each column
    x1 <- xmin + (i-1)*size #size is the lateral size of the quadricules = 0.5
    x2 <- xmin + i*size
    for (j in 1:ny) { # to each row
        y1 <- ymin + (j-1)*size
        y2 <- ymin + j*size
        nind <- nrow(mam[which(mam$LAT >= y1 & mam$LAT < y2 & mam$LON >= x1 & mam$LON < x2),]) # number of rows in table "mam" inside the given limits (x1,y1,x2,y2)
        if (nind == 1) {
            rect(x1+gap,y1+gap,x2-gap,y2-gap) # gap is about 0.1
            segments(x1+gap,y1+gap,x2-gap,y2-gap)
        } else if (nind == 2) {
            rect(x1+gap,y1+gap,x2-gap,y2-gap)
            segments(x1,y2,x2,y1)
        } else if (nind == 3) {
            rect(x1+gap,y1+gap,x2-gap,y2-gap)
            segments(x1,y1,x2,y2)
            segments(x1,y2,x2,y1)
        }
    }
}

它工作正常,并产生

忘记颜色。这里绘制的是黑色的小方块。但它需要的时间太长,而且对于某些操作 apply 似乎更快(尽管有些人说这不再是真的了......我不确定)。

我的问题是:如何使用 apply 来做到这一点?我需要函数内部的“i”参数,所以我知道将在哪里绘制正方形。但是还没找到怎么获取。在其他类似的问题中,答案总是关于使用其他一些函数,比如 outer() 或 R 自然矢量化......但我认为这些在这里不起作用。提前致谢!

【问题讨论】:

  • 你不会通过将它移动到任何应用函数来加速绘图。不过,使用 rectsegments 中存在的固有矢量化可能会为您带来一些速度。但是,通常情况下,创建图形的瓶颈是实际绘图,可能没有办法加快速度。
  • 我不得不不同意你的观点,因为我可以看到正在绘制的符号,并且当存在没有符号的间隙时,无论如何该函数需要太长时间才能跨越该间隙(不绘制任何东西)。但我会尝试你提到的矢量化。谢谢。
  • 不,您看到的延迟与 apply 和 for 循环之间的差异无关。应用版本仍然需要循环遍历这些索引,没有任何东西可以绘制,而且它不会更快。
  • 有些人仍然说 *apply 在某些情况下更快。参见,例如:stackoverflow.com/a/3584290/1086511
  • 我知道这一点,但你的情况与那个例子完全不同。相信我,绘制图形的缓慢部分是实际绘制图形,无论您使用什么循环语义,都必须这样做。

标签: r loops maps apply


【解决方案1】:

虽然我同意切换到 *pply 可能不会加快您的速度,但您可以这样做:

nx <- 1:10
ny <- 1:10

mapply(
  function(i, j) {
    x1 <- xmin + (i-1) * size #size is the lateral size of the quadricules = 0.5
    x2 <- xmin + i*size
    y1 <- ymin + (j-1)*size
    y2 <- ymin + j*size
    # do whatever
  },
  i=rep(nx, each=length(ny)), 
  j=rep(ny, length(nx))
)

要意识到的主要事情是,您可以通过使用 rep (带或不带 each 参数)轻松地预先创建 i 和 j 的每个组合。

一般来说,*pply 相对于其他方法的关键速度优势是预先分配存储结果所需的内存,因此在迭代时不会有不断增长的对象。在您的情况下,您没有写入对象,因此这不适用。

其他好处是代码清晰和编码简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多