r - Is it possible to use a metric (distance) unit in igraph cutoff argument? -
newbie igraph user here. i'm trying calculate betweenness values every segment (edge) in street network. ideally restrict calculations paths of less x metres considered. igraph::edge.betweenness.estimate
function has cutoff
argument restricts steps (turns) know if possible use metric distance instead.
so far closest question have been able find http://lists.nongnu.org/archive/html/igraph-help/2012-11/msg00083.html on igraph help, , suggests might not possible.
i have been using network aspatially, simple graph, have attribute of street segment length - lnklength
. reading other stackoverflow posts possible use spatial networks igraph (with of spatial packages). if lnklength used weight network solve problem?
if has ideas i'd grateful hear them.
data <- data.frame( node1 = as.factor(c(aa, ab, ac, ad, ae, af, ag, ah, ai, aj)), node2 = as.factor(c(ba, bb, bc, aa, ab, ac, ba, bb, bc, aa)), lnklength =as.numeric(c(23.05, 42.81, 77.08, 39.63, 147.87, 56.46, 13.43, 25.53, 197.19, 34.9))) data.graph <- graph.data.frame(data, directed=false, vertices=null) # attempt limit betweeness estimates on 800m btw.trunc <- edge.betweenness.estimate(d.graph, e=e(d.graph), directed = false, cutoff=20, weights = null)
i'm assuming computing geodesic betweenness scores (e.g. counts of number of times shortest path uses given edge) opposed to, current-flow betweenness (which treat graph network of electrical reisistors). think 1 solution first use 'distances' function obtain matrix of pairwise distances e.g.
distmat=distances(g,weights=g$lnklength)
now assuming have cutoff dcut, can sparsify matrix
distmat[which(distmat>dcut)]=0 distmat=as(distmat,'sparsematrix')
this allow select pairs of points consider...
frominds=row(distmat)[which(!distmat==0)] toinds=col(distmat)[which(!distmat==0)]
assuming there no 1 way streets , lnklength not directed property, have consider either upper or lower triangular portion of matrix. since 'toinds' array automatically listed in ascending order, can accomplish taking first half of frominds , toinds respectively
frominds=frominds[c(1:(length(frominds)/2)] toinds=toinds[c(1:length(toinds)/2)]
if graph directed (e.g. lnklength not same in both directions or there 1 way streets) leave frominds , toinds is. ready start assigning betweenness scores iteratively looping on index list , computing shortest_path , using returned path increment betweenness scores of appropriate edges
e(g)$betweenness=0 for(ipair in c(1:length(frominds)){ vpath=as.numeric( shortest_paths(g,weights=g$lnklength,output="vpath")$vpath[[1]]) #need convert list of path vertices list of edge indices pathlist=c(1:(2*length(vpath)-1)) pathlist[c(1:length(vpath)-1))*2]=vpath[c(2:length(vpath)))] pathlist[c(1:length(vpath)-1))*2-1]=vpath[c(1:(length(vpath)-1))] elist=get.edge.ids(g,pathlist) #increment betweenness scores of edges in elist e(g)$betweenness[elist]=e(g)$betweenness+1 }
your graph should have property 'betweenness' assigned edges using geodesic betweenness metric computed on subset of paths distance of less 'dcut'
if graph quite large, may worth while port above loop on rcpp, since take quite long time otherwise. whole new can of worms...
Comments
Post a Comment