Search code examples
rgisspatial

Is there a neat way in R to get a weighted geographical centroid?


I'm aware of the gCentroid function from the rgeos package that gives the geographical centroid of a bunch of longitude, latitude points... but what if I wanted to assign a weight to those points, how would I find the weighted centroid?

e.g., Say I want to find the best place to meet up... I have 10 people in London, 2 in Leeds, 5 in Glasgow. How do I find the place that is the least combined effort?


Solution

  • You could just make a spatial object where each point represents a person and then have 10 points for London, 2 for Leeds and 5 for Glasgow. The gCentroid function will then weight appropriately.

    Here's an example.

    library(dplyr)
    library(rgeos)
    library(sp)
    
    # Locations of cities
    city_locations <- tibble(  
        Name = c("London", "Glasgow", "Leeds"),
        lat = c(51.507222, 55.860916, 53.799722),
        lon = c(-0.1275,-4.251433,-1.549167)
    )
    # More elegant way to repeat cities
    people_counts <- c(rep('London', 10), rep('Glasgow', 5), rep('Leeds', 2))
    
    # Code to join repeated cities with lat and lon
    people <- 
        tibble(Name=people_counts) %>% 
        left_join(city_locations, by='Name') 
    
    # make a spatial points data frame
    people_sp <- SpatialPointsDataFrame(people, coords = people[c('lon', 'lat')], proj4string = CRS('EPSG:4326'))
    
    # find the centroid
    pub <- gCentroid(people_sp)
    pub$Name <- 'Centroid'
    
    library(mapview)
    # plot on a map
    mapview(people_sp) + mapview(pub, col.regions='red')
    

    Looks like somewhere just north of Derby.

    UK

    Derby