Reputation: 253
For the code below, I want to store the (a*b)
for each edge in a vector op1
and after that to store all vectors in a list opp1
. According to the given data: I should have 5 vectors op1
each one with a different length (for example: length(op1[1]=3)
while the rest of vectors of length 2
like length(op1[2]=2)
) and I will have one list opp1
contain the vectors of different lengths.
Storing the values in the vectors is OK but my problem is when storing these vectors, the resulted list contain the vectors but with the same length, i.e opp1
list consist of all op1
vectors with length 3 so there is a strange value added from no where.
library(igraph)
graph<-matrix(c(4,3,4,1,4,2,3,2,3,1),ncol=2,byrow=TRUE)
g<-graph.data.frame(d = graph, directed = FALSE)
v1<-c()
v2<-c()
n1<-list()
n2<-list()
op1<-c()
opp1<-list()
for (edge in 1:length(E(g))){
v1[edge] <- ends(graph = g, es = edge)[1]
v2[edge] <- ends(graph = g, es = edge)[2]
n1[[edge]] <- names(neighbors(g, v1[edge], mode = "all"))
n2[[edge]] <- names(neighbors(g, v2[edge], mode = "all"))
for (neighbor in 1:length(n2[[edge]])){
a<-as.numeric(v2[edge])
b<-as.numeric(n2[[edge]][neighbor])
c<-(a*b)
op1[neighbor]<-c
}
opp1[[edge]]<-op1
}
The list opp1
is:
opp1
[[1]]
[1] 12 3 6
[[2]]
[1] 4 3 6
[[3]]
[1] 8 6 6
[[4]]
[1] 8 6 6
[[5]]
[1] 4 3 6
while it should be:
opp1
[[1]]
[1] 12 3 6
[[2]]
[1] 4 3
[[3]]
[1] 8 6
[[4]]
[1] 8 6
[[5]]
[1] 4 3
Is there any advice how to fix the code, also is there another way to do the same work in a different way especially to save time and memory when working on big data. Thanks in advance.
Upvotes: 1
Views: 3177
Reputation: 5017
You have to initialize op1
inside the first for loop in the way to have a clean op1
in each cycle, like this:
for (edge in 1:length(E(g))){
op1<-c()
v1[edge] <- ends(graph = g, es = edge)[1]
v2[edge] <- ends(graph = g, es = edge)[2]
n1[[edge]] <- names(neighbors(g, v1[edge], mode = "all"))
n2[[edge]] <- names(neighbors(g, v2[edge], mode = "all"))
for (neighbor in 1:length(n2[[edge]])){
a<-as.numeric(v2[edge])
b<-as.numeric(n2[[edge]][neighbor])
c<-(a*b)
op1[neighbor]<-c
}
opp1[[edge]]<-op1
}
Your output:
opp1
[[1]]
[1] 12 3 6
[[2]]
[1] 4 3
[[3]]
[1] 8 6
[[4]]
[1] 8 6
[[5]]
[1] 4 3
Without for loop is better and faster:
n<-length(E(g))
v1x<-unlist(lapply(lapply(c(1:n),ends,graph=g),"[[",1))
v2x<-unlist(lapply(lapply(c(1:n),ends,graph=g),"[[",2))
n1x<-lapply(lapply(v1x,neighbors,graph=g,mode="all"),names)
b<-Map(as.numeric,lapply(lapply(v2x,neighbors,graph=g,mode="all"),names))
a<-mapply(rep, as.numeric(v2x), lapply(n2x,length))
opp1<-Map('*',a,b)
opp1
[[1]]
[1] 12 3 6
[[2]]
[1] 4 3
[[3]]
[1] 8 6
[[4]]
[1] 8 6
[[5]]
[1] 4 3
Upvotes: 2