lapply function to look up neighbors in igraph (when not all nodes are found)

佐手、 提交于 2019-12-11 07:39:28

问题


I am trying to create a data set of network neighbors for a list of nodes. I though I could do this with an lapply function where I use the neighbors command. As an added complication, some of my lookup nodes aren't in the graph, but I can't get it to work regardless.

Here is an example:

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

Unfortunately, this returns hogwash in both cases. What am I missing?

My desired output would be something like this:

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

I know eventually I need to add a temp=data.table::rbindlist(temp) command in somewhere, but I don't think that is causing the hogwash.


回答1:


One thing is that you're creating a data.frame with the read.table functions and passing in that data.frame to lapply so it's iterating over the each vector, not the elements of the V1 vector in the data.frame.

Second, that V1 column is a factor (h/t to @Psidom for the factor hint).

Third, the neighbors() function is going to return graph vertices which (from my reckoning) need to be iterated over and have the name attribute returned.

Then, as you suggest, these need to be rbinded into a 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>

I wonder if Gabor can vectorize neighbors() on the C-side.

UPDATE:

The ego solution is only a tad different:

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


来源:https://stackoverflow.com/questions/38645671/lapply-function-to-look-up-neighbors-in-igraph-when-not-all-nodes-are-found

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!