Reputation: 685
I have geographic coordinates for every vertex in an iGraph object. Now I want to calculate distance between existing edges.
library(igraph)
library(ggmap)
library(geosphere)
g <- graph.ring(6)
V(grph)$postcode <- c("Johannesburg 2017",
"Rondebosch 8000",
"Durban 4001",
"Pietermaritzburg 3201",
"Jeffreys Bay 6330",
"Pretoria 0001" )
postcode_df <- geocode(V(g)$postcode, sensor = FALSE,
output = "latlon", source = "google")
V(g)$coordinate <- split(postcode_df, 1:nrow(postcode_df))
V(g)$coordinate[1]
[[1]]
lon lat
1 28.03837 -26.18825
I want to compute the distance using this general approach:
el <- get.edgelist(g, names=FALSE)
E(g)$distance <- distHaversine(V(g)$coordinate[[el[,1]]],V(g)$coordinate[[el[,2]]])
The problem is that the lon and lat in V(g)$coordinate cannot be referenced this way. I get a recursive indexing failed at level 3. Obviously I cannot nest index of one data frame within another.
str(V(g)$coordinate)
List of 6
$ :'data.frame': 1 obs. of 2 variables:
..$ lon: num 28
..$ lat: num -26.2
$ :'data.frame': 1 obs. of 2 variables:
..$ lon: num 28.3
..$ lat: num -25.8
$ :'data.frame': 1 obs. of 2 variables:
..$ lon: num 31
..$ lat: num -29.8
$ :'data.frame': 1 obs. of 2 variables:
..$ lon: num 30.4
..$ lat: num -29.7
$ :'data.frame': 1 obs. of 2 variables:
..$ lon: num 24.9
..$ lat: num -34.1
$ :'data.frame': 1 obs. of 2 variables:
..$ lon: num 28.2
..$ lat: num -25.7
The general way to compute distance between two points is
distHaversine(p1, p2, r=6378137).
p1 is defined by el[,1] and p2 by el[,2]. el[,1:2] refers to vertex number in g. So I need to extract V(g)$coordinate corresponding to el[,1] and el[,2]. Advice would be appreciated.
Upvotes: 1
Views: 483
Reputation: 16026
There's a problem here in that the split
is returning a dataframe, which we can fix by:
V(g)$coordinate <- lapply(split(postcode_df, 1:nrow(postcode_df)), unlist)
Then you're essentially needing to iterate over two lists, the coordinates of each vertex.
This is easy with map2
from purrr
.
library(purrr)
el <- get.edgelist(g, names=FALSE)
E(g)$distance <- unlist(map2(V(g)$coordinate[el[,1]], V(g)$coordinate[el[,2]], distHaversine))
Upvotes: 1