【问题标题】:Vectorize calculation of cell number in a hexagonal grid六边形网格中单元格数的矢量化计算
【发布时间】:2017-02-05 22:48:39
【问题描述】:

我知道在 R 中使用 for 循环通常是不必要的,因为它支持向量化。我想尽可能高效地编程,关于以下示例代码的问题。

我有一个六边形网格,我正在计算单元格的数量,在我的示例中从 1 到 225 计数,从左下角开始,向右移动。所以单元格 16 被放置在单元格 1 的正上方一个位偏移。 见快照:

因此,如果我有 Y 坐标,则 X 坐标必须是圆角或天花板。在我的应用程序中,用户指出单元格,我保存它并在 for 循环中遍历单元格以确定他选择的单元格,如下所示,用户将选择 Xcells 和 Ycells 的玩具输入值:

gridsize <- 15 

 Xcells <-c(0.8066765, 1.8209879, 3.0526517, 0.5893240)
 Ycells <-c(0.4577802, 0.4577802, 0.5302311, 1.5445425)

 clicks <- length(Xcells)
 cells <-vector('list', clicks)

这对应于单元格 1 2 3 和 16。4 次点击。现在确定单元格数:

  Y <- ceiling(Ycells)
      for(i in 1:clicks){
        if(Y[i]%%2==1){
           X[i] <- round(Xcells[i])
        }
      else{
         X[i]<- ceiling(Xcells[i])
         }

      #determine the cell numbers and store in predefined list
      cells[[i]] <- (Y[i]-1)*gridsize + X[i]
       }

因此,如果 Y 是“偶数”,则 X 必须四舍五入,如果 Y 是“非偶数”,则它必须是上限值。

有没有办法通过使用矢量化而不使用 for 循环来做到这一点?

【问题讨论】:

  • 你还没有在任何地方定义X。除此之外,感谢这个好问题和不要求 dplyr 解决方案而是解决问题本身 - 这些天在 SO 上百万分之一......
  • 我认为这个参考可能会有所帮助:redblobgames.com/grids/hexagons
  • @DavidArenburg,这有必要吗?不确定我是否可以这样说,但是:X 没有在声明X[i] &lt;- round(..) 中定义自己
  • X[i] &lt;- round(..) 如果您不预定义 X &lt;- ceiling(Xcells) 就像您对 Y 所做的那样,则将无法工作。所以不知道你说的 necessary 是什么意思
  • 嗯,Xcells 是预定义的,在我发布的示例中,X 被指定为 Xcells 的圆形/天花板。我同意不是很微妙,但它确实“起作用”(我的意思是我最后得到一个 X 向量......)。但是,我发布这个问题的原因当然是这样做。谢谢大卫的帮助。

标签: r for-loop vectorization


【解决方案1】:

您可以按如下方式对其进行矢量化

(Y - 1) * gridsize + ifelse(Y %% 2 == 1, round(Xcells), ceiling(Xcells))
# [1]  1  2  3 16

(我不确定预先计算 round(Xcells)ceiling(Xcells) 是否会进一步改善这一点 - 你可以尝试)


另一个选项(如果你想避免ifelse)可能是

(Y - 1) * gridsize + cbind(ceiling(Xcells), round(Xcells))[cbind(1:length(Xcells), Y %% 2 + 1)]
# [1]  1  2  3 16

【讨论】:

  • 我其实很喜欢这里的ifelse,它看起来很干净,你可以很容易地看到这行代码应该做什么(对于经验不足的编码人员,我认为这是一个优势)。谢谢。
  • ifelse 确实很干净,但它有some issues。我尽量避免它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多