| Title: | Analysis of Stream Network Topology and Order |
|---|---|
| Description: | Provides tools for analyzing stream networks, including graph construction, calculation of Link Magnitude, D-LINK, and export of spatial data. The Link Magnitude (Shreve stream order) method follows Shreve (1966) <doi:10.1086/627137>. The D-LINK metric follows Osborne & Wiley (1992) <doi:10.1139/f92-076>. |
| Authors: | Diogo S. B. Rocha [aut, cre], Renata T. Capellão [aut] |
| Maintainer: | Diogo S. B. Rocha <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-10-06 10:20:07 UTC |
| Source: | https://github.com/diogosbr/rgdrivers |
Adds a D_LINK column to a table of stream reaches, representing the
order value (e.g. Link Magnitude) of the downstream reach.
calculate_dlink(df, col_id, col_downstream, col_order)calculate_dlink(df, col_id, col_downstream, col_order)
df |
Data frame containing the stream network reaches |
col_id |
Name of the column with the unique reach ID (e.g. "cotrecho") |
col_downstream |
Name of the column with the downstream reach ID (e.g. "nutrjus") |
col_order |
Name of the column with the reach order (e.g. "link_mag", "order", etc.) |
The same df, with a new D_LINK column
Osborne, L. L., & Wiley, M. J. (1992). Influence of Tributary Spatial Position on the Structure of Warmwater Fish Communities. Canadian Journal of Fisheries and Aquatic Sciences, 49(4), 671-681. doi:10.1139/f92-076.
Smith, T. A., & Kraft, C. E. (2005). Stream Fish Assemblages in Relation to Landscape Position and Local Habitat Variables. Transactions of the American Fisheries Society, 134(2), 430-440. doi:10.1577/T03-051.1.
Thornbrugh, D. J., & Gido, K. B. (2010). Influence of spatial positioning within stream networks on fish assemblage structure in the Kansas River basin, USA. Canadian Journal of Fisheries and Aquatic Sciences, 67(1), 143-156. doi:10.1139/f09-169.
df <- data.frame( id = c(1, 2, 3), downstream = c(2, 3, NA), order = c(1, 2, 3) ) calculate_dlink(df, col_id = "id", col_downstream = "downstream", col_order = "order")df <- data.frame( id = c(1, 2, 3), downstream = c(2, 3, NA), order = c(1, 2, 3) ) calculate_dlink(df, col_id = "id", col_downstream = "downstream", col_order = "order")
Calculates the Link Magnitude (also known as Shreve stream order) for each reach of a stream network, assuming the network is represented as a directed acyclic graph (DAG). The Link Magnitude of a reach corresponds to the total number of independent paths from the headwaters to that reach, summing the values of its predecessors.
calculate_link_magnitude(graph)calculate_link_magnitude(graph)
graph |
Directed |
A named integer vector with the Link Magnitude of each node (reach) in the network.
Shreve, R. L. (1966). Statistical Law of Stream Numbers. The Journal of Geology, 74(1), 17-37. doi:10.1086/627137.
g <- igraph::make_graph(edges = c("1", "2", "2", "3", "3", "4"), directed = TRUE) calculate_link_magnitude(g)g <- igraph::make_graph(edges = c("1", "2", "2", "3", "3", "4"), directed = TRUE) calculate_link_magnitude(g)
Calculates the distance from each stream reach to the outlet using directed graphs.
calculate_outlet_distance(network, outlet, weight = "length_km")calculate_outlet_distance(network, outlet, weight = "length_km")
network |
|
outlet |
Vector of node IDs that represent the outlet |
weight |
Name of the edge weight attribute (e.g. 'length_km') |
Named vector with accumulated distances to the outlet
g <- igraph::graph_from_edgelist( matrix(c("1", "2", "2", "3", "3", "4"), byrow = TRUE, ncol = 2), directed = TRUE ) igraph::E(g)$length_km <- c(2, 3, 4) calculate_outlet_distance(g, outlet = "4", weight = "length_km")g <- igraph::graph_from_edgelist( matrix(c("1", "2", "2", "3", "3", "4"), byrow = TRUE, ncol = 2), directed = TRUE ) igraph::E(g)$length_km <- c(2, 3, 4) calculate_outlet_distance(g, outlet = "4", weight = "length_km")
Builds an igraph graph from an sf or SpatVector object
containing stream reaches. Requires columns with unique reach IDs and their
respective downstream reach IDs.
create_network_graph(network, col_id, col_downstream)create_network_graph(network, col_id, col_downstream)
network |
|
col_id |
Name of the column with the unique ID of each reach |
col_downstream |
Name of the column with the downstream reach ID |
Directed igraph object representing the stream network
library(igraph) library(sf) lines <- st_sfc( st_linestring(matrix(c(0,0, 1,1), ncol = 2, byrow = TRUE)), st_linestring(matrix(c(1,1, 2,2), ncol = 2, byrow = TRUE)), st_linestring(matrix(c(2,2, 3,3), ncol = 2, byrow = TRUE)) ) data <- data.frame(id = c(1, 2, 3), downstream = c(2, 3, NA)) network <- st_sf(data, geometry = lines) g <- create_network_graph(network, col_id = "id", col_downstream = "downstream") plot(g)library(igraph) library(sf) lines <- st_sfc( st_linestring(matrix(c(0,0, 1,1), ncol = 2, byrow = TRUE)), st_linestring(matrix(c(1,1, 2,2), ncol = 2, byrow = TRUE)), st_linestring(matrix(c(2,2, 3,3), ncol = 2, byrow = TRUE)) ) data <- data.frame(id = c(1, 2, 3), downstream = c(2, 3, NA)) network <- st_sf(data, geometry = lines) g <- create_network_graph(network, col_id = "id", col_downstream = "downstream") plot(g)
Builds an igraph object from an sf object of stream reaches
with ID and downstream ID columns.
create_stream_network( sf_reaches, col_id = "cotrecho", col_downstream = "nutrjus", col_length = NULL )create_stream_network( sf_reaches, col_id = "cotrecho", col_downstream = "nutrjus", col_length = NULL )
sf_reaches |
|
col_id |
Name of the column with the reach ID (e.g. "cotrecho") |
col_downstream |
Name of the column with the downstream reach ID (e.g. "nutrjus") |
col_length |
(Optional) Name of the column with line length, used as edge weight |
Directed igraph object
library(sf) lines <- st_sfc( st_linestring(matrix(c(0,0, 1,1), ncol = 2, byrow = TRUE)), st_linestring(matrix(c(1,1, 2,2), ncol = 2, byrow = TRUE)), st_linestring(matrix(c(2,2, 3,3), ncol = 2, byrow = TRUE)) ) data <- data.frame( cotrecho = c(1, 2, 3), nutrjus = c(2, 3, NA), length = c(0.5, 1.2, 2.0) ) sf_reaches <- st_sf(data, geometry = lines) g <- create_stream_network( sf_reaches, col_id = "cotrecho", col_downstream = "nutrjus", col_length = "length" ) plot(g)library(sf) lines <- st_sfc( st_linestring(matrix(c(0,0, 1,1), ncol = 2, byrow = TRUE)), st_linestring(matrix(c(1,1, 2,2), ncol = 2, byrow = TRUE)), st_linestring(matrix(c(2,2, 3,3), ncol = 2, byrow = TRUE)) ) data <- data.frame( cotrecho = c(1, 2, 3), nutrjus = c(2, 3, NA), length = c(0.5, 1.2, 2.0) ) sf_reaches <- st_sf(data, geometry = lines) g <- create_stream_network( sf_reaches, col_id = "cotrecho", col_downstream = "nutrjus", col_length = "length" ) plot(g)
Inserts new columns (e.g. link_mag, D_LINK) into a
SpatVector object from an updated data.frame and writes it to
disk.
write_network_with_orders( original_vector, updated_df, col_id, additional_cols, output_path, overwrite = TRUE )write_network_with_orders( original_vector, updated_df, col_id, additional_cols, output_path, overwrite = TRUE )
original_vector |
Original |
updated_df |
Data frame containing the reach IDs and the new columns |
col_id |
Name of the column with the unique reach identifier (e.g. "cotrecho") |
additional_cols |
Vector with the names of the columns to add to the vector |
output_path |
Full path to save the file to (e.g. "output.gpkg") |
overwrite |
Logical, if TRUE allows overwriting an existing file |
NULL (writes file to disk)
lines <- terra::vect(c( "LINESTRING(0 0, 1 1)", "LINESTRING(1 1, 2 2)" ), crs = "EPSG:4326") lines$id <- c(1, 2) updated_df <- data.frame(id = c(1, 2), link_mag = c(1, 2), D_LINK = c(2, NA)) output_file <- tempfile(fileext = ".gpkg") write_network_with_orders( original_vector = lines, updated_df = updated_df, col_id = "id", additional_cols = c("link_mag", "D_LINK"), output_path = output_file ) file.exists(output_file)lines <- terra::vect(c( "LINESTRING(0 0, 1 1)", "LINESTRING(1 1, 2 2)" ), crs = "EPSG:4326") lines$id <- c(1, 2) updated_df <- data.frame(id = c(1, 2), link_mag = c(1, 2), D_LINK = c(2, NA)) output_file <- tempfile(fileext = ".gpkg") write_network_with_orders( original_vector = lines, updated_df = updated_df, col_id = "id", additional_cols = c("link_mag", "D_LINK"), output_path = output_file ) file.exists(output_file)