问题
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 rbind
ed 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