Как работать со списками разной длины? - PullRequest
1 голос
/ 31 мая 2019

Вопрос был начат здесь .

У меня есть ненаправленный граф g с n<100 вершинами.График прост.Координаты всех вершин являются целыми числами (x_i, y_i), i=1, 2,..., n, множество ребер предопределено, это отрезки с длиной 1 единица.Степень вершин может быть 2, 3 или 4.

library(igraph)

g <- graph_from_literal(1-2-3-4-5-6-7-8-1, 8-9-4)
B <- t(matrix(c(0,0, 0,1, 0,2, -1,2, -2,2, -2,1, -2,0, -1,0, -1,1), nrow =2));

V(g)$id <- seq_len(vcount(g))

V(g)$x <- B[,1]; V(g)$y <- B[,2]

plot(g, layout=as.matrix(B))

enter image description here

Мне нужно установить новый атрибут длявершина атрибута corner.

Мы говорим, что вершина i является вершиной corner, если ее степень равна 2, и два инцидентных ребра не лежат на одной прямой.На графике выше вершины 1, 3, 5, 7 являются угловыми вершинами, а остальные вершины 2, 4, 6, 8, 9 не угловые.

Я нашел список вершин, степень которых равна 2.

idv <- V(g)[strength(g)==2]; idv # 1 2 3 5 6 7 9

Затем был найден список соседних вершин для i -ой вершины и создан новый атрибут:

neigh<-neighborhood(g, nodes=idv); neigh
V(g)$corner <- 0

Моя попытка

for(i in idv){
    ifelse(V(g)[neigh[[i]][2]]$x == V(g)[neigh[[i]][3]]$x || 
           V(g)[neigh[[i]][2]]$y == V(g)[neigh[[i]][3]]$y, 
    V(g)[neigh[[i]][1]]$corner <- 0, 
    V(g)[neigh[[i]][1]]$corner <- 1)}

Но у меня есть ошибка Error in neigh[[i]] : subscript out of bounds

В общем случае длина neigh меньше или равна длине V(g)$id:

length(neigh)     # 7
length(V(g)$id)   # 9

АЯ не могу сравнить координаты (x_i, y_i).

Вопрос. Как работать со списками разной длины?

1 Ответ

1 голос
/ 31 мая 2019

В этом конкретном случае одним из решений было бы связать i из idv с элементом neigh. Например, neigh[[i]][2] можно переписать как neigh[i == idv][[1]][2]], и всего у нас будет

for(i in idv){
  ifelse(V(g)[neigh[i == idv][[1]][2]]$x == V(g)[neigh[i == idv][[1]][3]]$x || 
           V(g)[neigh[[i]][2]]$y == V(g)[neigh[i == idv][[1]][3]]$y, 
         V(g)[neigh[i == idv][[1]][1]]$corner <- 0, 
         V(g)[neigh[i == idv][[1]][1]]$corner <- 1)}

Однако, это довольно запутанно и трудно читать. Вместо этого мы можем использовать тот факт, что каждый из idv имеет одинаковое количество соседей и neigh может быть преобразован в матрицу:

neigh <- do.call(rbind, neigh)

Тогда у нас просто есть

V(g)$corner[neigh[, 1]] <- V(g)[neigh[, 2]]$x != V(g)[neigh[, 3]]$x &
  V(g)[neigh[, 2]]$y != V(g)[neigh[, 3]]$y
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...