Vectorization of the calculation of the cell number in the hexagonal grid

I know that using for-loop in R is often unnecessary as it supports vectorization. I want to program as efficient as possible, there for my question regarding the following code example.

I have a hexagonal grid, and I calculate the number of cells, this number is from 1 to 225 in my example, starting from the lower left corner, and goes to the right. Thus, cell 16 is placed with a bit offset directly above cell 1. see snapshot: An example of a grid I'm working with

Therefore, if I have a Y coordinate, the X coordinate should be either rounded or ceiling. In my application, the user indicates the cells, I also save this in the for loop, passing through the cells to determine the cells that he selected, as follows, with the input values ​​of the toys for Xcells and Ycells that the user would select:

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) 

This corresponds to cell 1 2 3 and 16. 4 clicks. Now, to determine the cell numbers:

  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] } 

So, if Y is β€œeven,” X should be rounded, and if Y is β€œnot even,” that should be the ceiling value.

Is there a way to do this without a for loop using a vector?

+5
source share
1 answer

You can vectorize it as follows

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

(I'm not sure that precalculating round(Xcells) and ceiling(Xcells) will improve this a bit more - you can try)


Another option (if you want to avoid ifelse ) might be

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

Source: https://habr.com/ru/post/1257369/


All Articles