| Title: | Bayesian CAR Models for Road-Segment Traffic |
|---|---|
| Description: | Tools for simulating and modeling traffic flow on road networks using spatial conditional autoregressive (CAR) models. The package represents road systems as graphs derived from 'OpenStreetMap' data <https://www.openstreetmap.org/> and supports network-based spatial dependence, basic preprocessing, and visualization for spatial traffic analysis. |
| Authors: | Madison Ell [aut, cre] |
| Maintainer: | Madison Ell <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.1 |
| Built: | 2026-05-30 05:19:16 UTC |
| Source: | https://github.com/cran/trafficCAR |
Adds predicted traffic outcomes (e.g. speed or volume) and relative congestion measures to a road network.
augment_roads(fit, roads, probs = c(0.025, 0.975), keep_geometry = TRUE)augment_roads(fit, roads, probs = c(0.025, 0.975), keep_geometry = TRUE)
fit |
a 'traffic_fit' object from 'fit_traffic()'. |
roads |
an sf object or data.frame with a segment id column. |
probs |
length-2 numeric for equal-tail intervals. |
keep_geometry |
logical; if FALSE drops sf geometry. |
roads with added columns: predicted_mean, predicted_lo, predicted_hi, relative_congestion
Constructs an undirected adjacency matrix 'A' where segments are neighbors if they share a node (endpoint). Intended to be used after 'roads_to_segments()'.
build_adjacency(segments, crs_m = 3857, tol = 0, verbose = FALSE)build_adjacency(segments, crs_m = 3857, tol = 0, verbose = FALSE)
segments |
An 'sf' with LINESTRING geometries and (optionally) 'seg_id'. |
crs_m |
Metric CRS used when 'segments' is lon/lat (for robust node keys). Default 3857. |
tol |
Nonnegative numeric tolerance for snapping node coordinates (in meters if projected). If 0, uses exact coordinates. Default 0. |
verbose |
Logical; emit simple messages. Default FALSE. |
Isolates (degree 0) are kept (all-zero rows/cols). Connected components are returned for ICAR sum-to-zero centering per component.
A list with:
Sparse symmetric adjacency matrix ('dgCMatrix').
Integer vector component id (length n). Isolates are their own components.
Logical vector (length n).
Build a road network graph from sf LINESTRING data
build_network( roads_sf, crs_out = 3857, node_intersections = FALSE, snap_tol = 0, simplify = TRUE )build_network( roads_sf, crs_out = 3857, node_intersections = FALSE, snap_tol = 0, simplify = TRUE )
roads_sf |
An sf object with LINESTRING geometry |
crs_out |
Integer EPSG code for projected CRS |
node_intersections |
Logical; if TRUE, "node" the linework by splitting at interior intersections/junctions (via 'sf::st_union()'), so that crossings and T-junctions become graph nodes even when they are not endpoints. This may increase the number of edge segments. |
snap_tol |
Nonnegative numeric; optional snapping tolerance (in projected CRS units) used to merge nearly identical endpoints. Use 0 to disable. |
simplify |
Logical; if TRUE, remove self-loops and parallel edges. |
A list with components:
roads: cleaned sf object
nodes: sf POINT object with node_id
edges: sf LINESTRING object with from, to, length
graph: igraph object
A: sparse adjacency matrix
Constructs the precision matrix for an intrinsic CAR (ICAR) or proper CAR model:
car_precision( A, type = c("icar", "proper"), rho = 0.99, tau = 1, symmetrize = FALSE, check = TRUE )car_precision( A, type = c("icar", "proper"), rho = 0.99, tau = 1, symmetrize = FALSE, check = TRUE )
A |
Square adjacency/weight matrix (base matrix or a 'Matrix' sparse type). Diagonal entries are ignored (set to 0). |
type |
Either '"icar"' or '"proper"'. |
rho |
Spatial dependence parameter for proper CAR. Ignored for ICAR. |
tau |
Positive scalar precision multiplier. |
symmetrize |
If 'TRUE', replaces 'A' by '(A + t(A))/2' before construction. |
check |
If 'TRUE', performs basic validation and warnings. |
For ICAR, set 'type = "icar"' (internally uses ).
For proper CAR, set 'type = "proper"' and choose 'rho' so that
is positive definite (no automatic spectral checks are performed).
A symmetric sparse precision matrix 'Q' (class '"dsCMatrix"').
A <- matrix(0, 4, 4) A[1,2] <- A[2,1] <- 1 A[2,3] <- A[3,2] <- 1 A[3,4] <- A[4,3] <- 1 Q_icar <- car_precision(A, type = "icar", tau = 1) Q_prop <- car_precision(A, type = "proper", rho = 0.9, tau = 2)A <- matrix(0, 4, 4) A[1,2] <- A[2,1] <- 1 A[2,3] <- A[3,2] <- 1 A[3,4] <- A[4,3] <- 1 Q_icar <- car_precision(A, type = "icar", tau = 1) Q_prop <- car_precision(A, type = "proper", rho = 0.9, tau = 2)
Convenience wrapper around 'osmdata' to download road geometries and return an 'sf' object that can be passed into 'roads_to_segments()'.
fetch_osm_roads( place, key = "highway", value = NULL, extra_tags = NULL, layer = c("osm_lines", "osm_multilines", "osm_polygons", "osm_multipolygons"), quiet = TRUE, ... )fetch_osm_roads( place, key = "highway", value = NULL, extra_tags = NULL, layer = c("osm_lines", "osm_multilines", "osm_polygons", "osm_multipolygons"), quiet = TRUE, ... )
place |
A character place name (passed to 'osmdata::getbb()') or a bounding box object accepted by 'osmdata::opq()'. |
key |
OSM feature key to query. Default is '"highway"'. |
value |
Optional character vector of OSM feature values. For example, 'c("primary", "secondary")'. |
extra_tags |
Optional named list of additional tags passed to 'osmdata::add_osm_feature()'. |
layer |
Which OSM layer to return. Defaults to '"osm_lines"'. |
quiet |
Logical; suppress osmdata messages. Default TRUE. |
... |
Additional arguments passed to 'osmdata::osmdata_sf()'. |
An 'sf' object with road geometries.
Fits a Gaussian regression with a CAR/ICAR latent effect:
with and
, where and
. For ICAR, .
fit_car( y, A, X = NULL, type = c("icar", "proper"), rho = 0.99, tau = 1, n_iter = 2000, burn_in = floor(n_iter/2), thin = 1, beta_init = NULL, x_init = NULL, sigma2_init = NULL, b0 = NULL, B0 = NULL, a0 = 2, b0_sigma = 1, center_icar = TRUE, verbose = FALSE )fit_car( y, A, X = NULL, type = c("icar", "proper"), rho = 0.99, tau = 1, n_iter = 2000, burn_in = floor(n_iter/2), thin = 1, beta_init = NULL, x_init = NULL, sigma2_init = NULL, b0 = NULL, B0 = NULL, a0 = 2, b0_sigma = 1, center_icar = TRUE, verbose = FALSE )
y |
Numeric response vector of length |
A |
Square |
X |
Optional |
type |
Either |
rho |
Spatial dependence parameter for proper CAR. Ignored for ICAR. |
tau |
Positive scalar precision multiplier. |
n_iter |
Total MCMC iterations. |
burn_in |
Number of initial iterations to discard. |
thin |
Keep every |
beta_init |
Optional initial |
x_init |
Optional initial latent field |
sigma2_init |
Optional initial |
b0 |
Prior mean for |
B0 |
Prior covariance for |
a0 |
Shape parameter for inverse-gamma prior on |
b0_sigma |
Scale parameter for inverse-gamma prior on |
center_icar |
Logical; if |
verbose |
Logical; print coarse progress updates. |
The sampler updates , (if X is provided), and
using Gibbs steps.
A list of class "trafficCAR_fit" with elements:
drawsList with MCMC draws x, beta, sigma2.
keepIteration indices that were saved.
type, rho, tau
Model hyperparameters used.
y = X beta + x + epsilon
This is a thin wrapper around fit_car() that:
1) preprocesses the outcome (log/per-distance options),
2) fits the Gaussian CAR model,
3) returns a traffic-flavored object that can be augmented back onto roads.
fit_traffic( data, roads = NULL, A = NULL, segment_id_col = "segment_id", outcome = c("speed", "travel_time"), outcome_col = NULL, distance_col = NULL, per_distance = FALSE, transform = c("log", "identity"), X = NULL, ... )fit_traffic( data, roads = NULL, A = NULL, segment_id_col = "segment_id", outcome = c("speed", "travel_time"), outcome_col = NULL, distance_col = NULL, per_distance = FALSE, transform = c("log", "identity"), X = NULL, ... )
data |
data.frame with at least 'segment_id' and the outcome column. |
roads |
optional; an sf object or similar that contains adjacency info already used by your 'fit_car()' pipeline (depends on your package design). |
A |
adjacency matrix or object accepted by 'fit_car()' (recommended explicit). |
segment_id_col |
character; column in 'data' used to join back to roads. |
outcome |
character; one of "speed" or "travel_time". |
outcome_col |
optional character; if NULL uses 'outcome'. |
distance_col |
optional character; used only for travel_time when per_distance=TRUE. |
per_distance |
logical; only for travel_time. |
transform |
character; "log" or "identity". |
X |
optional design matrix; if NULL, uses intercept-only. |
... |
passed to 'fit_car()' (e.g., type="proper"/"icar", rho, priors, n_iter, burn, etc.) |
An object of class 'traffic_fit' containing the underlying fit and transform metadata.
Projects onto the subspace orthogonal to the constant vector.
icar_sum_to_zero(Q)icar_sum_to_zero(Q)
Q |
ICAR precision matrix |
Constrained precision matrix
Constructs the intrinsic CAR precision matrix
where is a scaling constant chosen so that the
geometric mean of the marginal variances equals 1.
intrinsic_car_precision( A, tau = 1, scale = TRUE, symmetrize = FALSE, check = TRUE )intrinsic_car_precision( A, tau = 1, scale = TRUE, symmetrize = FALSE, check = TRUE )
A |
Square adjacency/weight matrix. |
tau |
Positive scalar precision multiplier. |
scale |
Logical; if 'TRUE', applies Besag scaling. |
symmetrize |
If 'TRUE', replaces 'A' by '(A + t(A))/2'. |
check |
If 'TRUE', performs basic validation and warnings. |
The resulting precision matrix is singular with rank deficiency equal to the number of connected components.
A symmetric sparse precision matrix ('"dsCMatrix"').
Sørbye, S. H. and Rue, H. (2014). Scaling intrinsic Gaussian Markov random field priors.
Displays standard traffic quantities such as predicted speed, predicted volume, or relative congestion on an interactive map.
map_roads_interactive( sf_aug, value = c("predicted_speed", "predicted_volume", "relative_congestion"), engine = "leaflet" )map_roads_interactive( sf_aug, value = c("predicted_speed", "predicted_volume", "relative_congestion"), engine = "leaflet" )
sf_aug |
An 'sf' object returned by 'augment_roads()'. |
value |
Character scalar. One of: '"predicted_speed"', '"predicted_volume"', '"relative_congestion"'. |
engine |
Currently only '"leaflet"' is supported. |
A leaflet widget.
Interactive map with multiple standard traffic layers
map_roads_interactive_layers( sf_aug, values = c("predicted_speed", "relative_congestion") )map_roads_interactive_layers( sf_aug, values = c("predicted_speed", "relative_congestion") )
sf_aug |
sf object with road geometries |
values |
Character vector of traffic measures to include. |
leaflet widget
Computes Moran's I statistic for model residuals using the model adjacency.
moran_residuals( fit, type = c("raw", "structured", "unstructured"), nsim = 199, method = c("analytic", "permutation") )moran_residuals( fit, type = c("raw", "structured", "unstructured"), nsim = 199, method = c("analytic", "permutation") )
fit |
A 'traffic_fit' object. |
type |
Residual type: "raw" or "unstructured". |
nsim |
Number of permutations for permutation test. |
method |
"analytic" or "permutation". |
An object of class 'traffic_moran'.
MCMC diagnostic plots
plot_mcmc_diagnostics(fit)plot_mcmc_diagnostics(fit)
fit |
traffic_fit |
A list with components:
A 'ggplot' object of diagnostic summaries.
A data frame with columns 'parameter' and 'ess', giving the effective sample size for each parameter..
Plot observed vs predicted traffic values
plot_observed_fitted(fit, data)plot_observed_fitted(fit, data)
fit |
traffic_fit |
data |
data.frame |
ggplot
Plot predicted traffic outcome on road network
plot_predicted(fit, roads)plot_predicted(fit, roads)
fit |
traffic_fit |
roads |
sf with segment_id |
ggplot
Shows systematic deviations after accounting for covariates.
plot_relative_congestion(fit, roads)plot_relative_congestion(fit, roads)
fit |
traffic_fit |
roads |
sf |
ggplot
Static map of road-segment traffic measures
plot_roads_static( sf_aug, value = c("predicted_speed", "predicted_volume", "relative_congestion") )plot_roads_static( sf_aug, value = c("predicted_speed", "predicted_volume", "relative_congestion") )
sf_aug |
sf object with road geometries |
value |
One of "predicted_speed", "predicted_volume", or "relative_congestion" |
ggplot object
Plots road geometries colored by an augmented numeric column (e.g., posterior mean predictions or relative congestion).
plot_traffic_map(roads_aug, fill = c("predicted_mean", "relative_congestion"))plot_traffic_map(roads_aug, fill = c("predicted_mean", "relative_congestion"))
roads_aug |
An 'sf' object returned by [augment_roads()]. |
fill |
Character scalar. Which column of 'roads_aug' to map. One of '"predicted_mean"' or '"relative_congestion"'. |
An invisible copy of 'roads_aug', returned as an 'sf' object with the augmented columns. The function is called for its plotting side effect.
Computes simple posterior predictive checks comparing observed statistics to replicated data: mean, variance, and tail probabilities.
ppc_summary(fit, stats = c("mean", "var", "tail"), probs = c(0.05, 0.95))ppc_summary(fit, stats = c("mean", "var", "tail"), probs = c(0.05, 0.95))
fit |
A 'traffic_fit' object. |
stats |
Statistics to compute: "mean", "var", "tail". |
probs |
Tail probabilities for "tail" statistic. |
An object of class 'traffic_ppc'.
Computes raw, structured (spatial), or unstructured residuals from a fitted trafficCAR model.
## S3 method for class 'traffic_fit' residuals(object, type = c("raw", "structured", "unstructured"), ...)## S3 method for class 'traffic_fit' residuals(object, type = c("raw", "structured", "unstructured"), ...)
object |
A 'traffic_fit' object. |
type |
Residual type: "raw", "structured", or "unstructured". |
... |
Unused. |
Numeric vector of residuals.
A collection of example road network datasets provided as 'sf' objects. These datasets are intended for demonstration, testing, and benchmarking.
An object of class sf.
Each dataset contains LINESTRING road geometries suitable for use with
roads_to_segments() and related functions.
Included datasets:
Small example road network.
Road network for College Station, TX.
Takes an 'sf' object of LINESTRING/MULTILINESTRING road geometries and returns a segment-level 'sf' with stable segment IDs and metric lengths.
roads_to_segments( roads, crs_m = 3857, keep_attrs = NULL, drop_zero = TRUE, split_at_intersections = FALSE, verbose = FALSE )roads_to_segments( roads, crs_m = 3857, keep_attrs = NULL, drop_zero = TRUE, split_at_intersections = FALSE, verbose = FALSE )
roads |
An 'sf' object with LINESTRING or MULTILINESTRING geometries. |
crs_m |
Metric CRS used for length calculation (and intersection splitting) when 'roads' is lon/lat. Default 3857. For best accuracy, pass a local UTM EPSG. |
keep_attrs |
Optional character vector of non-geometry columns to keep. If 'NULL', keeps all attributes. |
drop_zero |
Logical; drop segments with non-positive length. Default TRUE. |
split_at_intersections |
Logical; if TRUE, split lines at all intersections. Implemented via GEOS noding ('sf::st_union' + 'sf::st_cast') Default FALSE. |
verbose |
Logical; emit simple messages about dropped rows. Default FALSE. |
v1 behavior: * Drops Z/M dimensions * Casts MULTILINESTRING -> LINESTRING (one row per linestring) * Optionally splits at intersections (noding) when 'split_at_intersections=TRUE' * Computes 'length_m' in meters (projects if lon/lat) * Drops empty and (optionally) zero-length segments
An 'sf' with columns: * 'seg_id' integer 1..n * 'length_m' numeric meters * geometry LINESTRING plus kept attributes.
Model:
sample_proper_car( y, A, rho = 0.99, n_iter, burn = 0L, thin = 1L, a_tau = 1, b_tau = 1, a_kappa = 1, b_kappa = 1, init = NULL, symmetrize = FALSE, check = TRUE )sample_proper_car( y, A, rho = 0.99, n_iter, burn = 0L, thin = 1L, a_tau = 1, b_tau = 1, a_kappa = 1, b_kappa = 1, init = NULL, symmetrize = FALSE, check = TRUE )
y |
Numeric vector of observations (length n). |
A |
Adjacency matrix (dense or sparse). Diagonal ignored. |
rho |
Proper CAR dependence parameter (must satisfy car_precision checks). |
n_iter |
Integer number of iterations. |
burn |
Integer burn-in iterations to drop (default 0). |
thin |
Integer thinning interval (default 1). |
a_tau, b_tau
|
Gamma(shape, rate) prior for tau. |
a_kappa, b_kappa
|
Gamma(shape, rate) prior for kappa. |
init |
Optional list with elements x, tau, kappa. |
symmetrize |
Passed to car_precision(). |
check |
Passed to car_precision(). |
List with x (matrix), tau, kappa, and settings.
Simplify a built network object by removing parallel edges (and loops)
simplify_network(net, keep_edge = c("first", "shortest"))simplify_network(net, keep_edge = c("first", "shortest"))
net |
A network list returned by [build_network()]. |
keep_edge |
Which edge to keep when multiple edges connect the same unordered node pair. One of "first" or "shortest". |
A network list with updated 'edges', 'graph', and 'A' (and the same 'nodes').
Construct spatial weights matrix
weights_from_adjacency( A, style = c("binary", "row-standardized"), symmetrize = FALSE )weights_from_adjacency( A, style = c("binary", "row-standardized"), symmetrize = FALSE )
A |
Adjacency matrix. |
style |
One of "binary" or "row-standardized". |
symmetrize |
Passed to adjacency coercion. |
Sparse weight matrix.