Skip to contents

Executes a spatial interaction model based on an OD data frame and user-specified function

Usage

si_calculate(
  od,
  fun,
  constraint_production,
  constraint_attraction,
  constraint_total,
  output_col = "interaction",
  ...
)

Arguments

od

A data frame representing origin-destination data, e.g. as created by si_to_od()

fun

A function that calculates the interaction (e.g. the number of trips) between each OD pair

constraint_production

Character representing column in od. This argument, when set, ensures that the outputs are 'production constrained': the total 'interaction' (e.g. n. trips) for all OD pairs is set such that the total for each zone of origin cannot go above this value.

constraint_attraction

Character representing column in od. This argument, when set, ensures that the outputs are 'attraction constrained': the total 'interaction' (e.g. n. trips) for all OD pairs is set such that the sum of trips to destination is equal to the mean value per destination.

constraint_total

Single number representing the total interaction. This argument, when set, ensures that the sum of the interaction calculated will equal the value given.

output_col

Character string containing the name of the new output column. "interaction" by default.

...

Arguments passed to fun

Value

An sf data frame

Examples

od = si_to_od(si_zones, si_zones, max_dist = 4000)
#> Converting p to centroids
#> lon-lat points
fun_dd = function(d = "distance_euclidean", beta = 0.3) exp(-beta * d / 1000)
fun_dd(d = (1:5) * 1000)
#> [1] 0.7408182 0.5488116 0.4065697 0.3011942 0.2231302
od_dd = si_calculate(od, fun = fun_dd, d = distance_euclidean)
plot(od$distance_euclidean, od_dd$interaction)

fun = function(O, n, d, beta) O * n * exp(-beta * d / 1000)
od_output = si_calculate(od, fun = fun, beta = 0.3, O = origin_all, 
  n = destination_all, d = distance_euclidean)
head(od_output)
#> Simple feature collection with 6 features and 28 fields
#> Geometry type: LINESTRING
#> Dimension:     XY
#> Bounding box:  xmin: -1.704658 ymin: 53.90066 xmax: -1.346497 ymax: 53.92906
#> Geodetic CRS:  WGS 84
#>           O         D distance_euclidean origin_geo_name origin_lad11cd
#> 1 E02002330 E02002330              0.000       Leeds 001      E08000035
#> 2 E02002330 E02002331           3579.804       Leeds 001      E08000035
#> 3 E02002331 E02002331              0.000       Leeds 002      E08000035
#> 4 E02002331 E02002330           3579.804       Leeds 002      E08000035
#> 5 E02002332 E02002332              0.000       Leeds 003      E08000035
#> 6 E02002332 E02002333           1582.213       Leeds 003      E08000035
#>   origin_lad_name origin_all origin_bicycle origin_foot origin_car_driver
#> 1           Leeds       2809             52         300              2170
#> 2           Leeds       2809             52         300              2170
#> 3           Leeds       2387             53         469              1573
#> 4           Leeds       2387             53         469              1573
#> 5           Leeds       2471             39         341              1666
#> 6           Leeds       2471             39         341              1666
#>   origin_car_passenger origin_motorbike origin_train_tube origin_bus
#> 1                  138               10                36         89
#> 2                  138               10                36         89
#> 3                  132               16                10        126
#> 4                  132               16                10        126
#> 5                  147               19                75        166
#> 6                  147               19                75        166
#>   origin_taxi_other destination_geo_name destination_lad11cd
#> 1                14            Leeds 001           E08000035
#> 2                14            Leeds 002           E08000035
#> 3                 8            Leeds 002           E08000035
#> 4                 8            Leeds 001           E08000035
#> 5                18            Leeds 003           E08000035
#> 6                18            Leeds 004           E08000035
#>   destination_lad_name destination_all destination_bicycle destination_foot
#> 1                Leeds            2809                  52              300
#> 2                Leeds            2387                  53              469
#> 3                Leeds            2387                  53              469
#> 4                Leeds            2809                  52              300
#> 5                Leeds            2471                  39              341
#> 6                Leeds            3743                  80              529
#>   destination_car_driver destination_car_passenger destination_motorbike
#> 1                   2170                       138                    10
#> 2                   1573                       132                    16
#> 3                   1573                       132                    16
#> 4                   2170                       138                    10
#> 5                   1666                       147                    19
#> 6                   2340                       193                    26
#>   destination_train_tube destination_bus destination_taxi_other
#> 1                     36              89                     14
#> 2                     10             126                      8
#> 3                     10             126                      8
#> 4                     36              89                     14
#> 5                     75             166                     18
#> 6                    221             335                     19
#>                         geometry interaction
#> 1 LINESTRING (-1.400108 53.92...     7890481
#> 2 LINESTRING (-1.400108 53.92...     2290854
#> 3 LINESTRING (-1.346497 53.92...     5697769
#> 4 LINESTRING (-1.346497 53.92...     2290854
#> 5 LINESTRING (-1.704658 53.91...     6105841
#> 6 LINESTRING (-1.704658 53.91...     5753720
plot(od$distance_euclidean, od_output$interaction)

od_pconst = si_calculate(od, fun = fun, beta = 0.3, O = origin_all,
  n = destination_all, d = distance_euclidean, constraint_production = origin_all)
# Origin totals in OD data should equal origin totals in zone data
library(dplyr)
#> 
#> 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
origin_totals_zones = od_pconst |>
  group_by(geo_code = O) |>
  summarise(all_od = sum(interaction)) |>
  sf::st_drop_geometry()
zones_joined = left_join(si_zones, origin_totals_zones)
#> Joining with `by = join_by(geo_code)`
plot(zones_joined$all, zones_joined$all_od)

plot(od_pconst$distance_euclidean, od_pconst$interaction)

plot(od_pconst["interaction"], logz = TRUE)

od_dd = si_calculate(od, fun = fun_dd, d = distance_euclidean, output_col = "res")
head(od_dd$res)
#> [1] 1.0000000 0.3416593 1.0000000 0.3416593 1.0000000 0.6220942
od_dd = si_calculate(od, fun = fun_dd, d = distance_euclidean, constraint_total = 10)
sum(od_dd$interaction)
#> [1] 10