Расчет географического расстояния до края в iGraph

У меня есть географические координаты для каждой вершины в объекте iGraph. Теперь я хочу рассчитать расстояние между существующими краями.

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

Я хочу вычислить расстояние, используя этот общий подход:

el <- get.edgelist(g, names=FALSE)
E(g)$distance <- distHaversine(V(g)$coordinate[[el[,1]]],V(g)$coordinate[[el[,2]]])

Проблема в том, что таким образом нельзя ссылаться на долготу и широту в координате V (g) $. Я получаю ошибку рекурсивного индексирования на уровне 3. Очевидно, я не могу вложить индекс одного фрейма данных в другой.

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

Общий способ вычисления расстояния между двумя точками:

distHaversine(p1, p2, r=6378137).

p1 определяется el [, 1], а p2 - el [, 2]. el [, 1: 2] относится к номеру вершины в g. Поэтому мне нужно извлечь координату V (g) $, соответствующую el [, 1] и el [, 2]. Совет будет оценен.


person aterhorst    schedule 22.06.2017    source источник


Ответы (1)


Здесь есть проблема в том, что split возвращает фрейм данных, который мы можем исправить следующим образом:

V(g)$coordinate <- lapply(split(postcode_df, 1:nrow(postcode_df)), unlist)

Тогда вам, по сути, нужно перебрать два списка, координаты каждой вершины.

Это легко сделать с map2 из 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))
person alexwhan    schedule 22.06.2017
comment
Это дает ответ во вложенном списке. Мне нужно разложить все, чтобы E (g) $ distance возвращало один список значений. - person aterhorst; 22.06.2017
comment
g ‹- graph.ring (10) V (g) $ w‹ - 1:10 # # el ‹- get.edgelist (g, names = FALSE) # E (g) $ w‹ - V (g) $ w [el [, 1]] * V (g) $ w [el [, 2]] - person aterhorst; 22.06.2017