2

I don't understand spatial.data at all. I have been studying but I'm missing something.

What I have: data.frame enterprises with the columns: id, parent_subsidiary, city_cod.

What I need: the mean and the max distance from the parent's city to the subsidiary cities.

Ex:

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

What I did :

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)
  
}
}



Is it right? Can I calculate the centroid of the cities and than calculate the distance?

Data example: 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")

PS: this is Brazilian cities https://github.com/ipeaGIT/geobr/tree/master/r-package

1 Answer 1

1

Once you convert the map parentand map subsidiary to sf objects (with function st_as_sf() your call to st_distance will return a distance matrix; then you just need to get the max and mean for each row.

About the difference between googlemaps distance, st_distanceis returning "straight" distance (in this case it is rather great circle distance), while google gives you the distance along a route.

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.
3
  • Thanks a lot ! Just a few quesitons: why you used the name of the city max(blumenau:catalao)? And if you use this to see the distance from code_muni==4111407 to code_muni==4110102, the distance is 0, but is another city (Imbituva, PR,Brasil - Ivaí, PR,Brasil)
    – RxT
    Aug 20, 2020 at 16:34
  • 1
    blumenao:catalao are the names of the 1st to 12th variables (to exclude variable id), 1:12 or .[,1:12] didn't work
    – Elio Diaz
    Aug 20, 2020 at 16:38
  • I added a new line in the exemple with the code_muni with the error.
    – RxT
    Aug 20, 2020 at 17:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.