Question

I'm new to this site. I was wondering if anyone had experience with turning a list of grid coordinates (shown in example code below as df). I've written a function that can handle the job for very small data sets but the run time increases exponentially as the size of the data set increases (I think 800 pixels would take about 25 hours). It's because of the nested for loops but I don't know how to get around it.

## Dummy Data
x <- c(1,1,2,2,2,3,3)
y <- c(3,4,2,3,4,1,2)
df <- as.data.frame(cbind(x,y))
df

## Here's what it looks like as an image
a <- c(NA,NA,1,1)
b <- c(NA,1,1,1)
c <- c(1,1,NA,NA)
image <- cbind(a,b,c)
f <- function(m) t(m)[,nrow(m):1]
image(f(image))

## Here's my adjacency matrix function that's slowwwwww
adjacency.coordinates <- function(x,y) {
  df <- as.data.frame(cbind(x,y))
  colnames(df) = c("V1","V2")
  df <- df[with(df,order(V1,V2)),]
  adj.mat <- diag(1,dim(df)[1])
  for (i in 1:dim(df)[1]) {
    for (j in 1:dim(df)[1]) {
      if((df[i,1]-df[j,1]==0)&(abs(df[i,2]-df[j,2])==1) | (df[i,2]-df[j,2]==0)&(abs(df[i,1]-df[j,1])==1)) {
        adj.mat[i,j] = 1
      }
    }
  }
  return(adj.mat)
}

## Here's the adjacency matrix
adjacency.coordinates(x,y)

Does anyone know of a way to do this that will work well on a set of coordinates a couple thousand pixels long? I've tried conversion to SpatialGridDataFrame and went from there but it won't get the adjacency matrix correct. Thank you so much for your time.

Was it helpful?

Solution

While I thought igraph might be the way to go here, I think you can do it more simply like:

result <- apply(df, 1, function(pt) 
  (pt["x"] == df$x &  abs(pt["y"] - df$y) == 1) |
  (abs(pt["x"] - df$x) == 1 &  pt["y"] == df$y)    
)
diag(result) <- 1

And avoid the loopiness and get the same result:

> identical(adjacency.coordinates(x,y),result)
[1] TRUE
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top