如何使用具有不同长度的列表?

时间:2019-05-31 11:17:48

标签: r list for-loop igraph lapply

问题已开始here

我有一个g个顶点的无向图n<100。该图很简单。所有顶点的坐标均为整数(x_i, y_i), i=1, 2,..., n,边集已预定义,它们是长度为1单位的线段。 顶点的度可以是234

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属性设置新的顶点属性。

我们说顶点icorner顶点,如果其度为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 个答案:

答案 0 :(得分:1)

In this specific case, one solution would be to relate i from idv with an element of neigh. For instance, neigh[[i]][2] could be rewritten as neigh[i == idv][[1]][2]] and in total we have

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

However, that is quite convoluted and hard to read. Instead we may exploit the fact that each of idv have the same number of neighbours and neigh can be transformed into a matrix:

neigh <- do.call(rbind, neigh)

Then we simply have

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