[R-sig-Geo] while loop help

Takatsugu Kobayashi tkobayas at indiana.edu
Fri Jan 25 06:15:47 CET 2008


Hi, I must apologize both for this lengthy thread and for posting a 
thread based on the same example I have been using. 

I successfully created a code that re-arrange 10*10 grid cells of the 
same size into new grid cells of varying sizes.  Now I am attempting to 
create grid cells of the same size that are larger than the orignal 
10*10 grid cells, which means the total number of cells is a lot less 
than 100.  So If I would like to re-arrange a 10*10 grid cells by 
combining 4 cells, the number of new grid cells will be 25.

The function I created below stops with errors. It stops when a single 
cell is isolated after its cell's 1st order nearest neighbors are 
already taken.  I guess I could come up with a mathematical way of 
avoiding it, but I just wanted to loop it until no single cells are 
isolated, which means all new cells have the size equal to n.nb (the 
number of cells to be combined).

I would like to use the function below in a while loop or repeat loop, 
and when single cells are isolated I want to tell a code to start over 
the while loop from the beginning.  Because when I set the number of 
cells to be combined to 4, there are 25 sets of new grid cells (100/4), 
I know there is a solution rather than a code being trapped in an 
infinite looping.

So my question is how can I set up a code such that it starts over when 
errors occur?

Again, I am sorry for this lengthy thread. 

Thank you.

Taka

### Include necessary packages
library(sp)
library(maptools)
library(PBSmapping)


### Define parameters for a grid
start.point <- -0
cco <- c(start.point,start.point)
csize <- c(1,1)
n <- 10 #abs(cco[1]*2)+1
cnum <- c(n,n)
grd <- GridTopology(cco, csize, cnum)
r.grd <- as(grd, "SpatialPolygons")
r.grd.ps <- SpatialPolygons2PolySet(r.grd)


### Subset the grid into n*n single cells
### I use r.grd.ps over r.grd because I did not know how to clip out 
Slot "coords" from SpatialPolygons
### I tried lapply(slot(r.grd, "polygons"), function(x) slot(x, 
"coords")), but cannot obtain this slot

subPoly <- list()
coords <- list()
for (i in 1:n^2)
 {
  beg <- 5*i-4; end <- 5*i
  sP <- r.grd.ps[beg:end,]
  subPoly[[i]] <- sP
  cds <- calcCentroid(sP)
  coords[[i]] <- cbind(cds$X, cds$Y)
 }


### 1st order continuity neighbors
knn.nb <- list()
res <- vector("numeric",length=n^2)

for (ki in 1:n^2)
 for (ji in 1:n^2)
  {{
   ## Find the cells whose boundaries share with jth cell
   res[ji] <- 
length(which(subPoly[[ki]][1:4,4]%in%subPoly[[ji]][1:4,4]&subPoly[[ki]][1:4,5]%in%subPoly[[ji]][1:4,5]))  

   res[ki] <- 0
   ## Identify which cells are k-nearest neighbors excluding the 
reference zone
   knn.nb[[ki]] <- which(res>1)  
  }}


### Clip individual polygons and merge some of them based on adjacency 
weights
## Fixed number of cells to be combined excluding the jth cell
n.nb <- 3

maup <- function (knn.nb, n.nb)
{
## j for subPoly ID: input
j <- 1
## k for randomPoly ID: output
k <- 1
## A vector of subPoly IDs
sample.cell <- 1:n^2
## A list in which to store combined Polygons
randomPoly <- list()
## A vector of cell areas: for making sure all cells have the size of 
n.nb =4
areaPoly <-numeric(n^2/n.nb)

  while (all(areaPoly != n.nb))
        {
         ## Retrieve at most 5 contiguous neighbors
         j <- min(which(!is.nan(sample.cell)))
 
         ## Pick one nearest neighbor of jth cell randomly, including 
the jth cell
         d1.id <- which(!is.nan(knn.nb[[j]]))
         d1 <- knn.nb[[j]][d1.id]
         d1.rand <- round(runif(1,0.5,length(d1)))
         d1 <-  d1[d1.rand]
         nb.list <- append(j, d1)

         for (k.nb in 2:n.nb)
             {
              ## Pick one nearest neighbor of j+1th cell randomly
              ## Repeat till n.nb and append every cells chosen
              ## d as nearest neighbors
              d_id <- nb.list[k.nb]
              d_k_id <- which(!is.nan(knn.nb[[d_id]]))
              d_k <- knn.nb[[d_id]][d_k_id]
              non_overlap_id <- which(d_k%in%nb.list)
              d_k <- d_k[-non_overlap_id]
              dk.rand <- round(runif(1,0.5,length(d_k)))
              dk <- d_k[dk.rand]
              nb.list <- append(nb.list, dk)
             }

        ## Remove cells that are already taken
        sample.cell[nb.list] <- NaN
   
        for (ord in 1: n^2)
            {
             id.check <- which(knn.nb[[ord]]%in%nb.list)
             if (length(id.check)>0)
                {  
                knn.nb[[ord]][id.check] <- NaN
                }   
            }


        ## JoinPolys allows to join two of the same polysets
        joinedPoly <- joinPolys(subPoly[[j]],subPoly[[nb.list[2]]],"UNION")
   
        for (pl in 3:(n.nb+1)) # +1 means the jth cell
            {      
             joinedPoly <- 
joinPolys(joinedPoly,subPoly[[nb.list[pl]]],"UNION")       
            }

        ## PID should be single and unique
        randomPoly[[k]] <- combinePolys(joinedPoly)
        randomPoly[[k]]$PID <- k

      areaPoly[k] <- calcArea(randomPoly[[k]])[,3]
 
      k <- k+1
      }
}




More information about the R-sig-Geo mailing list