Convert an origin-destination (OD) matrix to a long-format data frame
with columns from, to, and flow.
Arguments
- od_matrix
A numeric matrix with origin-destination flows. Rows represent origins, columns represent destinations. The matrix should be square (same number of rows and columns).
- nodes
(Optional) Numeric or integer vector of node IDs in the graph matching the rows and columns of the matrix. If provided, must have length equal to both
nrow(od_matrix)andncol(od_matrix). Whennodesis provided, these IDs are used directly, ignoring row and column names. This is particularly useful when mapping zone-based OD matrices to graph node IDs (e.g., usingst_nearest_featureto find nearest graph nodes). If omitted, row and column names (if present) will be used as node IDs, coerced to integer if possible. If names are not available or cannot be coerced to integer, sequential integers will be used.- sort
Sort long OD-matrix in ascending order of from and to columns. This can have computational benefits, e.g., when multithreading with
method = "AoN".
Value
A data frame with columns:
from- Origin node ID (integer)to- Destination node ID (integer)flow- Flow value (numeric)
Only rows with finite, positive flow values are included.
Details
This function converts a square OD matrix to long format, which is required by
run_assignment(). The behavior depends on whether nodes
is provided:
When nodes is provided:
The
nodesvector is used directly as node IDs for both origins and destinationsRow and column names are ignored (but must match if both are present)
This is the recommended approach when working with zone-based OD matrices that need to be mapped to graph nodes, as it ensures the node IDs match those in the graph
When nodes is omitted:
Row and column names are extracted from the matrix (if available)
Names are coerced to integer if possible; if coercion fails or names are missing, sequential integers are used
This approach works well when the matrix row/column names already correspond to graph node IDs
In both cases, the function:
Creates a long-format data frame with all origin-destination pairs
Filters out non-finite and zero flow values
The function is useful for converting OD matrices to the long format required by
run_assignment().
Examples
library(flownet)
library(sf)
# Load existing network and convert to graph
africa_net <- africa_network[!africa_network$add, ]
graph <- linestrings_to_graph(africa_net)
nodes <- nodes_from_graph(graph, sf = TRUE)
# Map cities/ports to nearest network nodes
nearest_nodes <- nodes$node[st_nearest_feature(africa_cities_ports, nodes)]
# Example 1: Simple gravity-based OD matrix
od_mat <- outer(africa_cities_ports$population, africa_cities_ports$population) / 1e12
dimnames(od_mat) <- list(nearest_nodes, nearest_nodes)
od_long <- melt_od_matrix(od_mat)
head(od_long)
#> from to flow
#> 1 1 1 10.3925963
#> 2 1 6 0.3804031
#> 3 1 8 4.6445025
#> 4 1 11 3.1488124
#> 5 1 13 0.6058467
#> 6 1 15 0.4982475
# Example 2: Using nodes argument (when matrix has zone IDs, not node IDs)
# Here zones are 1:n_cities, nodes argument maps them to graph nodes
dimnames(od_mat) <- NULL
od_long2 <- melt_od_matrix(od_mat, nodes = nearest_nodes)
head(od_long2)
#> from to flow
#> 1 1 1 10.3925963
#> 2 1 6 0.3804031
#> 3 1 8 4.6445025
#> 4 1 11 3.1488124
#> 5 1 13 0.6058467
#> 6 1 15 0.4982475
