| Title: | Ecological Limit Function Model Generation and Analysis Toolkit |
|---|---|
| Description: | A toolset for generating Ecological Limit Function (ELF) models and evaluating potential species loss resulting from flow change, based on the 'elfgen' framework. ELFs describe the relation between aquatic species richness (fish or benthic macroinvertebrates) and stream size characteristics (streamflow or drainage area). Journal publications are available outlining framework methodology (Kleiner et al. (2020) <doi:10.1111/1752-1688.12876>) and application (Rapp et al. (2020) <doi:10.1111/1752-1688.12877>). |
| Authors: | Joseph Kleiner [aut] (ORCID: <https://orcid.org/0000-0003-4837-7678>), Robert Burgholzer [ctb] (ORCID: <https://orcid.org/0000-0002-7290-4928>), Connor Brogan [cre] (ORCID: <https://orcid.org/0000-0001-9377-1805>) |
| Maintainer: | Connor Brogan <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 2.3.5 |
| Built: | 2026-05-28 07:58:00 UTC |
| Source: | https://github.com/harpgroup/elfgen |
This applies the Piecewise Iterative elfgen method. This approach uses an iterative algorithm to identify shifts in the relation between maximum richness and stream size. A user specifies a "quantile" for isolating an upper subset of the data. A user also identifies a bounding range between two x-values ("blo" = "bound low", "bhi" = "bound high") in which the upper subest of data is believed to contain a breakpoint. (Note: Small datasets may not contain a breakpoint)
bkpt_pwit(watershed.df, quantile, blo, bhi)bkpt_pwit(watershed.df, quantile, blo, bhi)
watershed.df |
A dataframe of sites with ecological and hydrologic data |
quantile |
Specified value for the quantile of interest - 0.95 refers to the 95th percentile |
blo |
A "bound low" value, or the lower bound of the piecewise range |
bhi |
A "bound high" value, or the upper bound of the piecewise range |
See: Lemoine, N. 2012. "R for Ecologists: Putting Together a Piecewise Regression." https://www.r-bloggers.com/r-for-ecologists-putting-together-a-piecewise-regression/ The R Book, Second Edition. Michael J. Crawley. 2013 John Wiley & Sons, Ltd. Published 2013 by John Wiley & Sons, Ltd.
Breakpoint value is returned
#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) bkpt_pwit(watershed.df,0.85,100,300)#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) bkpt_pwit(watershed.df,0.85,100,300)
This applies the Ymax elfgen method. This approach treats the maximum observed species richness value as the breakpoint. This function begins by locating the point with the highest y-value in the full dataset, then utilizing the associated x-value as the breakpoint.
bkpt_ymax(watershed.df)bkpt_ymax(watershed.df)
watershed.df |
A dataframe of sites with ecological and hydrologic data |
Breakpoint value is returned
#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) bkpt_ymax(watershed.df)#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) bkpt_ymax(watershed.df)
Given a dataframe of flow metric and richness metric data (Typically retrieved from the DEQ VAHydro database), removes all sites where the ratio of Drainage Area:Mean Annual Flow is greater than 1000, also aggregates to the maximum richness value at each x-metric value
clean_vahydro(watershed.df)clean_vahydro(watershed.df)
watershed.df |
A dataframe of sites with ecological and hydrologic data |
A cleaned dataframe of sites with ecological and hydrologic data
# Retrieve dataset of interest watershed.df <- data.frame( MAF = c(100, 200, 300, 400, 526, 600, 700, 800, 400, 900, 1000, 100, 100), NT.TOTAL.UNIQUE = c(10, 20, 30, 40, 50, 40, 30 , 20, 50, 10, 10,99999,87), watershed.code = "test_testcode", hydrocode = c("t1","t2","t3","t4","t5","t6","t7","t8","t9","t10","t11","t12","t13"), DA_SQMI = c(110, 220000, 280, 360, 530, 604, 712, 698, 40000, 905, 1087, 98, 87), x.metric = c(100, 200, 300, 400, 526, 600, 700, 800, 400, 900, 1000, 100, 100) ) # Clean the dataset clean_vahydro(watershed.df)# Retrieve dataset of interest watershed.df <- data.frame( MAF = c(100, 200, 300, 400, 526, 600, 700, 800, 400, 900, 1000, 100, 100), NT.TOTAL.UNIQUE = c(10, 20, 30, 40, 50, 40, 30 , 20, 50, 10, 10,99999,87), watershed.code = "test_testcode", hydrocode = c("t1","t2","t3","t4","t5","t6","t7","t8","t9","t10","t11","t12","t13"), DA_SQMI = c(110, 220000, 280, 360, 530, 604, 712, 698, 40000, 905, 1087, 98, 87), x.metric = c(100, 200, 300, 400, 526, 600, 700, 800, 400, 900, 1000, 100, 100) ) # Clean the dataset clean_vahydro(watershed.df)
Calculates and plots percent richness change resulting from streamflow reductions
elfchange(stats, yaxis_thresh, xlabel = FALSE, ylabel = FALSE)elfchange(stats, yaxis_thresh, xlabel = FALSE, ylabel = FALSE)
stats |
A dataframe of ELF statistics |
yaxis_thresh |
Value used for specifying y-axis max limit |
xlabel |
Used to overwrite default x-axis label |
ylabel |
Used to overwrite default y-axis label |
Plot of percent decreases in richness from flow reductions
#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) breakpt <- 500 elf <- elfgen( "watershed.df" = watershed.df, "quantile" = 0.95, "breakpt" = breakpt, "xlabel" = "Mean Annual Flow (ft3/s)", "ylabel" = "Fish Species Richness" ) elfchange(elf$stats, "yaxis_thresh" = 25)#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) breakpt <- 500 elf <- elfgen( "watershed.df" = watershed.df, "quantile" = 0.95, "breakpt" = breakpt, "xlabel" = "Mean Annual Flow (ft3/s)", "ylabel" = "Fish Species Richness" ) elfchange(elf$stats, "yaxis_thresh" = 25)
Given a HUC code, provides a dataframe of all contained nhdplus segments and their individual NT Total and Mean Annual Flow MAF values
elfdata( watershed.code, ichthy.localpath, use_cache = TRUE, update_cache = FALSE )elfdata( watershed.code, ichthy.localpath, use_cache = TRUE, update_cache = FALSE )
watershed.code |
Hydrologic unit code, either HUC6, HUC8, HUC10, or HUC12 (e.g. HUC10 code '0208020101'). |
ichthy.localpath |
Local file path for storing downloaded ichthy data. Defaults to a temp directory. |
use_cache |
Should the function look for a file with the same name in the file directory? This allows users to use the same Icthy dataset each time rather than needing to download separately when running multiple analyses |
update_cache |
Should the file be written out to use for future caching? |
A dataframe of nhdplus segments containing species richness data (NT Total values) and mean annual flow (MAF) data.
# We don't run this example by R CMD check, because it takes >10s # Retrieve dataset of interest # You may enter either a 6, 8, 10, or 12-digit HUC code. # By default the ichthy dataset is downloaded to a temp directory, however this may be overridden by # supplying a local path of interest using the input parameter 'ichthy.localpath' watershed_df <- tryCatch({elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE)}, warning = function(w){print(w)}, error = function(e){"internet resource error"})# We don't run this example by R CMD check, because it takes >10s # Retrieve dataset of interest # You may enter either a 6, 8, 10, or 12-digit HUC code. # By default the ichthy dataset is downloaded to a temp directory, however this may be overridden by # supplying a local path of interest using the input parameter 'ichthy.localpath' watershed_df <- tryCatch({elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE)}, warning = function(w){print(w)}, error = function(e){"internet resource error"})
Given a set of VAHydro input parameters, outputs a dataframe of flow metric and richness metric data for hydrologic unit supplied
elfdata_vahydro( watershed.code, watershed.bundle, watershed.ftype, x.metric, y.metric, y.sampres, datasite, EDAS.localpath = tempdir() )elfdata_vahydro( watershed.code, watershed.bundle, watershed.ftype, x.metric, y.metric, y.sampres, datasite, EDAS.localpath = tempdir() )
watershed.code |
Hydrologic unit code, either HUC6, HUC8, HUC10, or HUC12 (e.g. HUC10 code '0208020101'). |
watershed.bundle |
dH bundle of hydrologic unit |
watershed.ftype |
dH ftype of hydrologic unit |
x.metric |
x-metric, i.e. streamflow or drainage area |
y.metric |
y-metric, most commonly species richness |
y.sampres |
Sample resolution of y.metric (e.g. 'species') |
datasite |
VAHydro database URL |
EDAS.localpath |
Local file path for storing downloaded EDAS data. Defaults to a temp directory. |
A dataframe of sites containing species richness data (NT Total values) and mean annual flow (MAF) data.
# Retrieve dataset of interest watershed.df <- elfdata_vahydro( 'nhd_huc8_02080201', 'watershed', 'nhd_huc8', 'nhdp_drainage_sqmi', 'aqbio_nt_total', 'species' ) elfdata_vahydro(watershed.df)# Retrieve dataset of interest watershed.df <- elfdata_vahydro( 'nhd_huc8_02080201', 'watershed', 'nhd_huc8', 'nhdp_drainage_sqmi', 'aqbio_nt_total', 'species' ) elfdata_vahydro(watershed.df)
Generate ELF models by supplying a dataframe of richness and stream size data (streamflow or drainage area), a quantile for evaluating the ecological limit, and a breakpoint threshold.
elfgen( watershed.df, quantile, breakpt, yaxis_thresh, xlabel = FALSE, ylabel = FALSE, plot_title = FALSE, break_var = "x_var" )elfgen( watershed.df, quantile, breakpt, yaxis_thresh, xlabel = FALSE, ylabel = FALSE, plot_title = FALSE, break_var = "x_var" )
watershed.df |
A dataframe of sites with ecological and hydrologic data |
quantile |
A specified value for the quantile of interest - 0.95 equals the 95th percentile |
breakpt |
A breakpoint - either user-supplied fixed value or derived using elfgen breakpoint functions bkpt_pwit() or bkpt_ymax |
yaxis_thresh |
Value used for specifying y-axis max limit |
xlabel |
Used to overwrite default x-axis label |
ylabel |
Used to overwrite default y-axis label |
plot_title |
A plot title used to title the ggplot. If left as the default (FALSE), the plot will be titled using the name of the HUC from nhdPlus |
break_var |
The name of the variable in watershed.df to be filtered for by the breakpt, defaults to the expected name "x_var" |
Object containing plot image and dataframe of ELF statistics
#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) breakpt <- 500 elfgen( "watershed.df" = watershed.df, "quantile" = 0.80, "breakpt" = breakpt, "xlabel" = "Mean Annual Flow (ft3/s)", "ylabel" = "Fish Species Richness" )#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) breakpt <- 500 elfgen( "watershed.df" = watershed.df, "quantile" = 0.80, "breakpt" = breakpt, "xlabel" = "Mean Annual Flow (ft3/s)", "ylabel" = "Fish Species Richness" )
Calculates absolute or percent richness change from streamflow reduction
richness_change(stats, pctchg, xval = FALSE)richness_change(stats, pctchg, xval = FALSE)
stats |
A dataframe of ELF statistics |
pctchg |
Decrease in flow as a percent (e.g. 10 equals 10 percent reduction in flow). |
xval |
x-axis value for assessing percent change in richness. When supplied, the function will calculate percent change in richness at a specific stream size (e.g. 50 equals a stream size with mean annual flow of 50 cfs). |
Richness change value is returned
#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) breakpt <- 500 elf <- elfgen( "watershed.df" = watershed.df, "quantile" = 0.95, "breakpt" = breakpt, "xlabel" = "Mean Annual Flow (ft3/s)", "ylabel" = "Fish Species Richness" ) # Calculate absolute richness change richness_change(elf$stats, "pctchg" = 10) # Calculate percent richness change at a specific stream size richness_change(elf$stats, "pctchg" = 10, "xval" = 50)#elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE) breakpt <- 500 elf <- elfgen( "watershed.df" = watershed.df, "quantile" = 0.95, "breakpt" = breakpt, "xlabel" = "Mean Annual Flow (ft3/s)", "ylabel" = "Fish Species Richness" ) # Calculate absolute richness change richness_change(elf$stats, "pctchg" = 10) # Calculate percent richness change at a specific stream size richness_change(elf$stats, "pctchg" = 10, "xval" = 50)
An example watershed data frame derived from elfdata() using the HUC
'0208020104'
watershed.dfwatershed.df
## 'watershed.df' A data frame with 81 rows and 15 columns:
Mean annual flow, as estimated from NHD estimation via nhdPlusTools
Monthly estimated mean flow derived from NHD estimation via nhdPlusTools
Total number of unique taxa
Watershed NHD Code
elfdata(watershed.code = '0208020104', ichthy.localpath = tempdir(), use_cache = FALSE)