r - Distance Matrix from second variable using get.shortest.paths() -
i go 1 step further question (find total of second variable related distance of route get.shortest.paths()). how 1 matrix of distances between nodes, when 'shortest' path found using newcost variable?
(my experience igraph limited).
df2 = rbind(c(234,235,21.6,75), c(234,326,11.0,35), c(235,241,14.5,78), c(326,241,8.2,98), c(241,245,15.3,75), c(234,245,38.46,65)) df2 = as.data.frame(df2) names(df2) = c("start_id","end_id","newcost","distance") require(igraph) g2 <- graph.data.frame(df2, directed=false) tmp2 = shortest.paths(g2,weights=e(g2)$newcost) tmp2 #this gives matrix of newcost-weighted shortest distances
where use how find paths, using optimal.path <- get.shortest.paths
, , using sum(e(g2, path = optimal.path)$distance)
create matrix of distances
what edgelist of distances node pairs, like:
startid endid shortestdist 234 235 75 234 245 208
what tricky problem newcost used find shortest paths, want sum of variable - distance variable on each shortest path between node pairs.
ok, first let me make clear not igraph
user myself. nevertheless thought question interesting thought i'd take look. , find no easy solution problem having. ended making helper functions make process possible. there chance i've re-coded functionality inside igraph
not find it.
let me first define get.shortest.paths.for.all
not return shortest path lengths given attribute, return shortest path vertices in graph. here's code
get.shortest.paths.for.all<-function(graph, attr) { paths<-lapply(1:(vcount(graph)-1), function(i) { get.all.shortest.paths( graph, weights=get.edge.attribute(g2,attr), = v(graph)[i], = v(graph)[(i+1):vcount(graph)] )$res }) unsplit(paths, rep.int(seq_along(paths), sapply(paths, length))) }
now let me define get.path.dist.matrix
takes graph , list of paths (like 1 returned get.shortest.paths.for.all
) , calculate distance given attribute between each of paths
get.path.dist.matrix<-function(graph, path, attr) { dd<-get.adjacency(graph, attr=attr) uniqs <- numeric(0) if (is.list(path)) { starts<-sapply(path, head, 1) ends<-sapply(path, tail, 1) uniqs <- unique(sort(c(starts,ends))) } else { uniqs <- c(head(path,1), tail(path,1)) } m<-matrix(0, nrow=length(uniqs), ncol=length(uniqs), dimnames=list(v(graph)$name[uniqs],v(graph)$name[uniqs])) for(pp in path) { m[pp[1], pp[length(pp)]]<-sum(dd[embed(pp,2)]) } m+t(m) }
using sample data, use them this
paths <- get.shortest.paths.for.all(g2, "newcost") get.path.dist.matrix(g2, paths,"distance") # 234 235 326 241 245 # 234 0 75 35 133 208 # 235 75 0 176 78 153 # 326 35 176 0 98 173 # 241 133 78 98 0 75 # 245 208 153 173 75 0
which seems reasonable , distinct shortest.paths(g2,weights=e(g2)$distance)
. try test functions, see
all(tmp2==get.path.dist.matrix(g2, paths,"newcost"))
so feel free try these out , let me know if see problems or possible improvements.
Comments
Post a Comment