2016-07-28 73 views
1

我正在尝试为节点列表创建网络邻居的数据集。我虽然我可以用lapply函数做这个,我使用neighbors命令。作为一个增加的复杂性,我的一些查找节点不在图中,但我无法让它工作。lapply函数查找igraph中的邻居(当不是所有节点都找到时)

下面是一个例子:

edgelist <- read.table(text = " 
A B 
B C 
C D 
D E 
C F 
F G") 

testlist <- read.table(text = " 
A 
H 
C 
D 
J") 

testlist2 <- read.table(text = " 
A 
C 
B 
D 
E") 

library(igraph) 
graph <- graph.data.frame(edgelist) 
str(graph) 

neighbors<- lapply(testlist2, function(p) { #Each pledge_id 
    temp=neighbors(graph,p) #Find all the neighbors for that pledge 
    return(temp) 
}) 

neighbors<- lapply(testlist, function(p) { #Each pledge_id 
    temp=neighbors(graph,p) #Find all the neighbors for that pledge 
    return(temp) 
}) 

不幸的是,这将返回在这两种情况下一派胡言。我错过了什么?

我所需的输出会是这样的:

lookupnode neighbor 
A B 
H . 
C D 
C F 
D E 
J . 

我知道最终我需要在某个地方加一个临时= data.table :: rbindlist(TEMP)的命令,但我不认为正在造成h。。

回答

5

的一件事是你创建与read.table功能data.frame并通过在data.framelapply所以它遍历每个矢量,在data.frameV1载体的不元素。

其次,V1列是一个因子(h/t到因子提示的@Psidom)。

第三,neighbors()函数将返回(从我的推算)需要迭代的图顶点并返回name属性。

然后,正如你提到的,这些都需要rbind编入data.frame

get_neighbors <- function(graph, n) { 

    do.call(rbind, lapply(n, function(x) { 

    if (x %in% V(graph)$name) { 

     nb <- neighbors(graph, x) 

     if (length(nb) > 0) { 
     data.frame(lookupnode=x, 
        neighbor=nb$name, # h/t @MrFlick for this shortcut 
        stringsAsFactors=FALSE) 
     } else { 
     data.frame(lookupnode=x, neighbor=NA, stringsAsFactors=FALSE) 
     } 

    } else { 
     data.frame(lookupnode=x, neighbor=NA, stringsAsFactors=FALSE) 
    } 

    })) 

} 

get_neighbors(graph, as.character(testlist$V1)) 
## lookupnode neighbor 
## 1   A  B 
## 2   H  <NA> 
## 3   C  D 
## 4   C  F 
## 5   D  E 
## 6   J  <NA> 

get_neighbors(graph, as.character(testlist2$V1)) 
## lookupnode neighbor 
## 1   A  B 
## 2   C  D 
## 3   C  F 
## 4   B  C 
## 5   D  E 
## 6   E  <NA> 

我不知道是否可以的Gabor矢量化的C面neighbors()

UPDATE:

ego解决方案是唯一的不同一点点:

get_ego <- function(g, v, n=2) { 
    do.call(rbind, lapply(v, function(x) { 
    if (x %in% V(g)$name) { 
     data.frame(node=x, 
       ego_n=sapply(ego(g, n, x), function(y) { V(g)[y]$name }), 
       stringsAsFactors=FALSE) 
    } else { 
     data.frame(node=x, ego_n=NA, stringsAsFactors=FALSE) 
    } 
    })) 
} 
+1

你可以用'邻居= NB $ name'的data.frame内,而不是'sapply' – MrFlick

+1

这是伟大的!当然这是一个数据框。哎呦。另外在%V(图)$ name中有'x%'是关键,并且在本项目的其他地方对我会很有用。谢谢! – Danielle

+0

这对一级邻居(这是我问的)非常有效,但是如果我在'ego'函数'ego(图形2,x)'中替换'',它会返回一个包含类“igraph.vs”的1的列表。长度为1,所以它仍然会触发第一个if语句,但错误“data.frame(lookupnode = x,neighbor = nb $ name,stringsAsFactors = FALSE)中的错误: 参数意味着不同的行数:1,0”暗示我不能将它强制转换为data.frame。在这种情况下你将如何修改? – Danielle