상호 ID로 한 도시에서 다른 도시까지의 거리

Aug 20 2020

나는 spatial.data를 전혀 이해하지 못합니다. 공부를했는데 뭔가 빠졌어요.

내가 가진 무엇 : data.frame enterprises아이디, parent_subsidiary, city_cod : 열로.

내가 필요로하는 것 : 부모의 도시에서 보조 도시까지의 평균과 최대 거리.

전의:

    id         |     mean_dist     | max_dist
 1111          |         25km      |     50km    
 232           |        110km      |    180km  
 333           |          0km      |      0km  

내가 한 일 :

library("tidyverse")
library("sf")
# library("brazilmaps")   not working anymore
library("geobr")


parent <- enterprises %>% filter(parent_subsidiary==1) 
subsidiary <- enterprises %>% filter(parent_subsidiary==2) 

# Cities - polygons 
m_city_br <- read_municipality(code_muni="all", year=2019)

# or shp_city<- st_read("/BR_Municipios_2019.shp")

# data.frame with the column geom
map_parent  <- left_join(parent, m_city_br, by=c("city_cod"="code_muni"))
map_subsidiary <- left_join(subsidiary, m_city_br, by=c("city_cod"="code_muni"))



st_distance(map_parent$geom[1],map_subsidiary$geom[2]) %>% units::set_units(km)
# it took a long time and the result is different from google.maps
# is it ok?!


# To do by ID -- I also stucked here

distance_p_s <- data.frame(id=as.numeric(),subsidiar=as.numeric(),mean_dist=as.numeric(),max_dist=as.numeric())

id_v <- as.vector(parent$id) for (i in 1:length(id_v)){ test_p <- map_parent %>% filter(id==id_v[i]) test_s <- map_subsidiary %>% filter(id==id_v[i]) total <- 0 value <- 0 max <- 0 l <- 0 l <- nrow(test_s) for (j in 1:l){ value <- as.numeric(round(st_distance(test_p$geom[1],test_s$geom[j]) %>% units::set_units(km),2))
          
         total <- total + value
         ifelse(value>max,max<-value,NA)
      }
  

  mean_dist <- total/l
  done <- data.frame(id=id[i],subsidiary=l,mean_dist=round(mean_dist,2),max_dist=max)
  distance_p_s <- rbind(distance_p_s,done)
  
  rm(done)
  
}
}



맞아? 도시의 중심을 계산하고 거리를 계산할 수 있습니까?

데이터 예 : structure(list(id = c("1111", "1111", "1111", "1111", "232", "232", "232", "232", "3123", "3123", "4455", "4455", "686", "333", "333", "14112", "14112", "14112", "3633", "3633","77172","77172"), parent_subsidiary = c("1","2", "2", "2", "1", "2", "2", "2", "1", "2", "1", "2", "1", "2", "1", "1", "2", "2", "1", "2","1","2"), city_cod = c(4305801L,4202404L, 4314803L, 4314902L, 4318705L, 1303403L, 4304507L, 4314100L, 2408102L, 3144409L, 5208707L, 4205407L, 5210000L, 3203908L, 3518800L, 3118601L, 4217303L, 3118601L, 5003702L, 5205109L,4111407L,4110102L)), row.names = c(NA, 22L), class = "data.frame")

추신 : 이것은 브라질 도시입니다 https://github.com/ipeaGIT/geobr/tree/master/r-package

답변

1 ElioDiaz Aug 20 2020 at 23:19

당신이 변환되면 map parentmap subsidiarysf기능 (객체 st_as_sf()하도록 통화 st_distance거리 행렬을 반환합니다, 당신은 단지를 얻을 필요 max하고 mean각 행에 대해.

googlemaps 거리의 차이에 대해 st_distance"직선"거리 (이 경우에는 상당히 큰 원 거리)를 반환하는 반면 Google은 경로를 따라 거리를 제공합니다.

library("tidyverse")
library("sf")
# library("brazilmaps")   not working anymore
library("geobr")
library(janitor)

parent <- enterprises %>% filter(parent_subsidiary==1) 
subsidiary <- enterprises %>% filter(parent_subsidiary==2) 

map_parent  <- left_join(parent, m_city_br, by=c("city_cod"="code_muni")) %>%
  st_as_sf()
map_subsidiary <- left_join(subsidiary, m_city_br, by=c("city_cod"="code_muni")) %>%
  st_as_sf()

dist_matrix = st_distance(map_parent, map_subsidiary)


dist_matrix %>% as.data.frame() %>% 
  set_names(map_subsidiary$name_muni) %>% janitor::clean_names() %>% mutate(id = map_parent$id) %>% rowwise() %>% 
  mutate(max_d = max(blumenau:catalao), mean_d = mean(blumenau:catalao)) %>%
  select(id, mean_d, max_d)

Source: local data frame [8 x 3]
Groups: <by row>

# A tibble: 8 x 3
  id      mean_d    max_d
  <chr>    <dbl>    <dbl>
1 1111   751800. 1128379.
2 232    812441. 1279803.
3 3123  2283090. 2726233.
4 4455   625060. 1083423.
5 686    671740. 1127195.
6 333    491425.  553784.
7 14112  640124.  897345.
8 3633   735219.  756007.