Skip to contents

This vignette provides a guide to using maxcovr to solve the maximum covering location problem, assuming that you can relocate facilities.

## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

The “fixed location” method provided in max_coverage is limited in that it assumes that you cannot move existing facilities. max_coverage_relocation assumes that you can move already existing facilities, but that there is some cost of removal, and a cost of installation.

To illustrate the benefits of relocation, we are first going to consider an example where the existing facilities provide no coverage to users. We identify facility locations that are really far away.

york_selected_worst_id <- york_crime %>% 
    nearest(york) %>%
    arrange(-distance) %>%
    slice(1:20) %>%
    select(desig_id) %>%
    distinct(desig_id)
    
    
# york_worst <- york_selected_worst_id %>% 
york_existing_worst <- york_selected_worst_id %>% 
    left_join(york,
              by = "desig_id")

Then we identify some really ideal locations.

york_not_selected_worst <- york %>%
    anti_join(york_existing_worst,
              by = "desig_id")

york_proposed_best <- 
 york_crime %>%
    nearest(york_not_selected_worst) %>%
    arrange(distance) %>%
    slice(1:100) %>%
    select(desig_id) %>%
    distinct(desig_id) %>%
    left_join(york,
              by = "desig_id")
york_proposed_best
## # A tibble: 101 × 7
##    desig_id  long   lat object_id pref_ref name                            grade
##    <chr>    <dbl> <dbl>     <int>    <int> <chr>                           <chr>
##  1 DYO788   -1.09  54.0      3362   463995 NA                              II*  
##  2 DYO857   -1.08  54.0      5549   463864 UNIVERSITY COLLEGE OF RIPON AN… II   
##  3 DYO857   -1.08  54.0      4212   463864 UNIVERSITY COLLEGE OF RIPON AN… II   
##  4 DYO1212  -1.08  54.0      5843   463237 NA                              II   
##  5 DYO1212  -1.08  54.0      4506   463237 NA                              II   
##  6 DYO862   -1.08  54.0      5554   463874 NA                              II   
##  7 DYO862   -1.08  54.0      4217   463874 NA                              II   
##  8 DYO1146  -1.08  54.0      5793   463399 NA                              II   
##  9 DYO1146  -1.08  54.0      4456   463399 NA                              II   
## 10 DYO1078  -1.09  54.0      5730   463443 THE ADELPHI HOTEL AND THE RAIL… II   
## # ℹ 91 more rows
york_existing_worst
## # A tibble: 21 × 7
##    desig_id   long   lat object_id pref_ref name                           grade
##    <chr>     <dbl> <dbl>     <int>    <int> <chr>                          <chr>
##  1 DYO91    -0.980  54.0      3545   328688 SANDBURN CROSS IN GROUNDS OF … II   
##  2 DYO91    -0.980  54.0      4882   328688 SANDBURN CROSS IN GROUNDS OF … II   
##  3 DYO222   -1.20   54.0      3720   331644 PEAR TREE FARMHOUSE            II   
##  4 DYO222   -1.20   54.0      5057   331644 PEAR TREE FARMHOUSE            II   
##  5 DYO1477  -0.983  54.0      6043   328687 MILEPOST APPROXIMATELY 75 MET… II   
##  6 DYO1477  -0.983  54.0      4707   328687 MILEPOST APPROXIMATELY 75 MET… II   
##  7 DYO138   -1.21   54.0      3591   331645 CROFT FARMHOUSE                II   
##  8 DYO138   -1.21   54.0      4928   331645 CROFT FARMHOUSE                II   
##  9 DYO137   -1.19   54.0      3590   331701 BOUNDARY POST AT SE 5303 5336  II   
## 10 DYO137   -1.19   54.0      4927   331701 BOUNDARY POST AT SE 5303 5336  II   
## # ℹ 11 more rows

Let’s look at the coverage of these places,

coverage(york_existing_worst,
         york_crime,
         distance_cutoff = 100)
## # A tibble: 1 × 7
##   distance_within n_cov n_not_cov prop_cov prop_not_cov dist_avg dist_sd
##             <dbl> <int>     <int>    <dbl>        <dbl>    <dbl>   <dbl>
## 1             100     0      1814        0            1    5674.   1040.

So these are worst placements - we should choose some better facilities. However, if we consider the possibility that we could move these existing facilities to better locations, then we might be able to save a lot of money! We can do this with max_coverage_relocation.

Here we use max_coverage_relocation, which is similar in form to max_coverage.

Here, we specify:

  • existing_facility with york_existing_worst
  • proposed_facility with york_proposed_best
  • user is york_crime,
  • distance_cutoff is 100 - for 100m

instead of specifying n_added, as in max_coverage, we specify three cost_ parameters:

  • cost_install is the cost of buying a new facility and installing it
  • cost_removal is the cost of removing a facility and installing it in a new location
  • cost_total is the total available money to spend.

Here we state that the installation cost is 10, the remocal cost is 1, and the total available cost is 10. There is only enough total resources to install one facility.

system.time(
mc_relocate_worst <-  max_coverage_relocation(
    existing_facility = york_existing_worst,
    proposed_facility = york_proposed_best,
    user = york_crime,
    distance_cutoff = 100,
    cost_install = 500,
    cost_removal = 100,
    cost_total = 1000)
)
##    user  system elapsed 
##   0.462   0.011   0.474
mc_relocate_worst
## 
## ----------------------------------------- 
## Model Fit: maxcovr relocation model 
## ----------------------------------------- 
## model_used:        max_coverage_relocation 
## existing_facility: york_existing_worst 
## proposed_facility: york_proposed_best 
## user:              york_crime 
## distance_cutoff:   100 
## cost_install:      500 
## cost_removal:     100 
## cost_total:        1000 
## solver:            lpSolve 
## -----------------------------------------
summary(mc_relocate_worst)
## 
## --------------------------------------- 
## Model Fit: maxcovr relocation model 
## --------------------------------------- 
## Distance Cutoff: 100m 
## Facilities: 
##     Added:       10 
##     Removed:     10L 
## Coverage (Previous): 
##     # Users:     260   (0) 
##     Proportion:  0.1433 (0) 
## Distance (m) to Facility (Previous): 
##        Avg:      1720 (5674) 
##        SD:       1542 (1040) 
## Costs: 
##     Total:       1000 
##     Install:     500 
##     Removal:  100 
## ---------------------------------------
dim(york_existing_worst)
## [1] 21  7
dim(york_proposed_best)
## [1] 101   7
mc_relocate_worst$existing_facility[[1]]
## # A tibble: 21 × 8
##    desig_id   long   lat object_id pref_ref name              grade is_relocated
##    <chr>     <dbl> <dbl>     <int>    <int> <chr>             <chr> <lgl>       
##  1 DYO91    -0.980  54.0      3545   328688 SANDBURN CROSS I… II    FALSE       
##  2 DYO91    -0.980  54.0      4882   328688 SANDBURN CROSS I… II    FALSE       
##  3 DYO222   -1.20   54.0      3720   331644 PEAR TREE FARMHO… II    FALSE       
##  4 DYO222   -1.20   54.0      5057   331644 PEAR TREE FARMHO… II    FALSE       
##  5 DYO1477  -0.983  54.0      6043   328687 MILEPOST APPROXI… II    FALSE       
##  6 DYO1477  -0.983  54.0      4707   328687 MILEPOST APPROXI… II    FALSE       
##  7 DYO138   -1.21   54.0      3591   331645 CROFT FARMHOUSE   II    FALSE       
##  8 DYO138   -1.21   54.0      4928   331645 CROFT FARMHOUSE   II    FALSE       
##  9 DYO137   -1.19   54.0      3590   331701 BOUNDARY POST AT… II    FALSE       
## 10 DYO137   -1.19   54.0      4927   331701 BOUNDARY POST AT… II    FALSE       
## # ℹ 11 more rows
mc_relocate_worst$proposed_facility[[1]]
## # A tibble: 101 × 8
##    desig_id  long   lat object_id pref_ref name               grade is_installed
##    <chr>    <dbl> <dbl>     <int>    <int> <chr>              <chr>        <dbl>
##  1 DYO788   -1.09  54.0      3362   463995 NA                 II*              0
##  2 DYO857   -1.08  54.0      5549   463864 UNIVERSITY COLLEG… II               0
##  3 DYO857   -1.08  54.0      4212   463864 UNIVERSITY COLLEG… II               0
##  4 DYO1212  -1.08  54.0      5843   463237 NA                 II               1
##  5 DYO1212  -1.08  54.0      4506   463237 NA                 II               0
##  6 DYO862   -1.08  54.0      5554   463874 NA                 II               0
##  7 DYO862   -1.08  54.0      4217   463874 NA                 II               0
##  8 DYO1146  -1.08  54.0      5793   463399 NA                 II               1
##  9 DYO1146  -1.08  54.0      4456   463399 NA                 II               0
## 10 DYO1078  -1.09  54.0      5730   463443 THE ADELPHI HOTEL… II               0
## # ℹ 91 more rows
mc_relocate_worst$facilities_selected[[1]]
## # A tibble: 21 × 7
##    desig_id   long   lat object_id pref_ref name                           grade
##    <chr>     <dbl> <dbl>     <int>    <int> <chr>                          <chr>
##  1 DYO91    -0.980  54.0      3545   328688 SANDBURN CROSS IN GROUNDS OF … II   
##  2 DYO91    -0.980  54.0      4882   328688 SANDBURN CROSS IN GROUNDS OF … II   
##  3 DYO222   -1.20   54.0      3720   331644 PEAR TREE FARMHOUSE            II   
##  4 DYO222   -1.20   54.0      5057   331644 PEAR TREE FARMHOUSE            II   
##  5 DYO1477  -0.983  54.0      6043   328687 MILEPOST APPROXIMATELY 75 MET… II   
##  6 DYO1477  -0.983  54.0      4707   328687 MILEPOST APPROXIMATELY 75 MET… II   
##  7 DYO138   -1.21   54.0      3591   331645 CROFT FARMHOUSE                II   
##  8 DYO138   -1.21   54.0      4928   331645 CROFT FARMHOUSE                II   
##  9 DYO137   -1.19   54.0      3590   331701 BOUNDARY POST AT SE 5303 5336  II   
## 10 DYO137   -1.19   54.0      4927   331701 BOUNDARY POST AT SE 5303 5336  II   
## # ℹ 11 more rows

You can then start to toy with the different pricings if you like.

system.time(
mc_relocate_worst_eq <-  max_coverage_relocation(
    existing_facility = york_existing_worst,
    proposed_facility = york_proposed_best,
    user = york_crime,
    distance_cutoff = 100,
    cost_install = 10,
    cost_removal = 100,
    cost_total = 10)
)
##    user  system elapsed 
##   0.279   0.020   0.299
mc_relocate_worst_eq
## 
## ----------------------------------------- 
## Model Fit: maxcovr relocation model 
## ----------------------------------------- 
## model_used:        max_coverage_relocation 
## existing_facility: york_existing_worst 
## proposed_facility: york_proposed_best 
## user:              york_crime 
## distance_cutoff:   100 
## cost_install:      10 
## cost_removal:     100 
## cost_total:        10 
## solver:            lpSolve 
## -----------------------------------------
summary(mc_relocate_worst_eq)
## 
## --------------------------------------- 
## Model Fit: maxcovr relocation model 
## --------------------------------------- 
## Distance Cutoff: 100m 
## Facilities: 
##     Added:       1 
##     Removed:     0L 
## Coverage (Previous): 
##     # Users:     44   (0) 
##     Proportion:  0.0243 (0) 
## Distance (m) to Facility (Previous): 
##        Avg:      2071 (5674) 
##        SD:       1521 (1040) 
## Costs: 
##     Total:       10 
##     Install:     10 
##     Removal:  100 
## ---------------------------------------