Как создать матрицу смежности из координат сетки в R?

Я новичок на этом сайте. Мне было интересно, есть ли у кого-нибудь опыт поворота списка координат сетки (показанного в примере кода ниже как df). Я написал функцию, которая может справиться с заданием для очень маленьких наборов данных, но время выполнения увеличивается экспоненциально по мере увеличения размера набора данных (я думаю, 800 пикселей займут около 25 часов). Это из-за вложенных циклов for, но я не знаю, как это обойти.

## 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)

Кто-нибудь знает способ сделать это, который будет хорошо работать с набором координат длиной в пару тысяч пикселей? Я пробовал преобразовать в SpatialGridDataFrame и пошел оттуда, но это не даст правильной матрицы смежности. Большое вам спасибо за ваше время.


person Logan    schedule 18.04.2013    source источник
comment
OP, по-видимому, хочет получить матрицу смежности графа, вершины которого являются пикселями изображения (x и y - координаты пикселей; в примере 7 пикселей) с краем между двумя пикселями, если они являются соседями. Это подграф двумерной сетки. (Изображение может быть воспроизведено как: im <- matrix(FALSE,5,5); im[cbind(x,y)] <- TRUE; image(im).)   -  person Vincent Zoonekynd    schedule 18.04.2013


Ответы (1)


Хотя я думал, что igraph может быть здесь, я думаю, вы можете сделать это проще, например:

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

И избегайте зацикливания и получите тот же результат:

> identical(adjacency.coordinates(x,y),result)
[1] TRUE
person thelatemail    schedule 18.04.2013
comment
но ваша результирующая матрица не совпадает с желаемым результатом adjacency.coordinates(x,y)... - person Ben; 18.04.2013
comment
@Ben - я понимаю это - он действительно копирует вызов оператора image и генерирует adjacency matrix в соответствии с определением в Википедии. Честно говоря, я не понимаю, что представляет собой результат функции adjacency.coordinates(x,y). - person thelatemail; 18.04.2013
comment
Привет всем! Большое спасибо за ответ. Моя adjacency.coordinates основана на том факте, что при сравнении двух наборов координат наборы являются смежными, если разница между значениями x равна 0, а значения y равны 1, или наоборот. Возможно, это не лучшее объяснение. Все, что я действительно хочу сделать, это выяснить, как получить матрицу смежности из списка координат. Просто врезался в стену... Еще раз всем спасибо. - person Logan; 18.04.2013
comment
Потрясающий. Это полностью работает. В сочетании с функциями graph.adjacency() и clusters() igraph я могу разделить все кластеры на изображении и проанализировать их отдельно. - person Logan; 18.04.2013
comment
Это решение проверяет 4 соседа для каждой вершины в сетке. Любая идея о том, как будет выглядеть решение с 8 соседями? - person Javier de la Rosa; 13.09.2017
comment
FWIW, условие для проверки 8-окрестности будет (abs(pt["x"] - df$x) <= 1 & abs(pt["y"] - df$y) <= 1) - person Javier de la Rosa; 13.09.2017