Skip to content

Commit

Permalink
fixes to NP summation
Browse files Browse the repository at this point in the history
I realized that if the equation accepts any combination of subsets of subspecies, other equations later in the hierarchy might be completely skipped even though a more complete set of subspecies exist. To fix this, I had to basically give the function every possible combination of nutrient subspecies, in a larger hierarchy. This is now saved as a .csv in the package.
  • Loading branch information
ehinman committed Aug 19, 2023
1 parent bfef123 commit 3f5405c
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 35 deletions.
2 changes: 1 addition & 1 deletion R/GenerateRefTables.R
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,6 @@ TADA_UpdateMeasureQualifierCodeRef <- function() {
#' @export

TADA_GetNutrientSummationRef <- function() {
ref <- utils::read.csv(system.file("extdata", "Nsummation_key.csv", package = "TADA"))
ref <- utils::read.csv(system.file("extdata", "NPsummation_key.csv", package = "TADA"))
return(ref)
}
67 changes: 36 additions & 31 deletions R/Transformations.R
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ TADA_HarmonizeSynonyms <- function(.data, ref, np_speciation = TRUE) {

#' Calculate Total Nitrogen and Phosphorus
#'
#' This function uses the [Nutrient Aggregation logic](https://echo.epa.gov/trends/loading-tool/resources/nutrient-aggregation#nitrogen)
#' This function applies the [Nutrient Aggregation logic](https://echo.epa.gov/trends/loading-tool/resources/nutrient-aggregation#nitrogen)
#' from ECHO's Water Pollutant Loading Tool to add nitrogen subspecies together
#' to approximate a total nitrogen value on a single day at a single site.
#' Before summing subspecies, this function runs TADA_AggregateMeasurements to
Expand All @@ -334,9 +334,29 @@ TADA_HarmonizeSynonyms <- function(.data, ref, np_speciation = TRUE) {
#' nitrogen subspecies expressed as nitrate, nitrite, ammonia, ammonium, etc. to
#' as nitrogen based on the atomic weights of the different elements in the
#' compound. The reference table is contained within the package but may be
#' edited/customized by users. Future development may include total P summations
#' as well.
#'
#' edited/customized by users. Nutrient equations are as follows:
#'
#' NITROGEN:
#' 1. TOTAL N (UNFILTERED)
#' 2. TOTAL N (FILTERED) + TOTAL N (PARTICULE)
#' 3. TOTAL KJELDAHL NITROGEN + NITRATE + NITRITE
#' 4. ORGANIC N + AMMONIA + NITRATE + NITRITE
#' 5. OTHER NITROGEN FORMS
#'
#' PHOSPHORUS:
#' 1. TOTAL PHOSPHORUS
#' 2. PHOSPHATE
#' 3. OTHER PHOSPHORUS FORMS
#'
#' Equations are applied in the order above. The function looks for groups of
#' nutrients that exactly match each equation before looking for every
#' combination within each equation (for example, a group of nitrogen subspecies
#' including AMMONIA and NITRATE will be passed over in an intial sweep of
#' groups of subspecies containing ORG N, AMMONIA, NITRATE, and NITRITE, but
#' will be caught as the function moves down the hierarchy of equations to fewer
#' and fewer subspecies). Eventually, even groups with only one subspecies will
#' be used to represent a TOTAL N value for that site/day/depth.
#'
#' @param .data TADA dataframe, ideally harmonized using TADA_HarmonizeSynonyms.
#' If user wants to consider grouping N or P subspecies across multiple
#' organizations, user should have run TADA_FindNearbySites and grouped all
Expand Down Expand Up @@ -420,43 +440,28 @@ TADA_CalculateTotalNP <- function(.data, sum_ref, daily_agg = c("max", "min", "m
dplyr::group_by(dplyr::across(dplyr::all_of(thecols))) %>%
dplyr::mutate(TADA.NutrientSummationGroup = dplyr::cur_group_id())

# Create list of summation equations in order of preference, can also accommodate phosphorus
eqns <- list(
"N" = list(
N0 = "TOTAL N (UNFILTERED)",
N1 = c("TOTAL N (FILTERED)", "TOTAL N (PARTICLE)"),
N2 = c("TKN", "NITRATE", "NITRITE"),
N2_a = c("TKN", "NITRATE + NITRITE"),
N3 = c("ORG N", "AMMON", "NITRATE", "NITRITE"),
N3_a = c("ORG N", "AMMON", "NITRATE + NITRITE"),
N4 = c("AMMON", "NITRATE", "NITRITE"),
N4_a = c("AMMON", "NITRATE + NITRITE"),
N5 = "OTHER N"
),
"P" = list(
P1 = c("PHOSP"),
P2 = c("PO4"),
P3 = "OTHER P"
)
)
# bring in equations
eqns = utils::read.csv(system.file("extdata","NP_equations.csv", package = "TADA"))


# dataframe to hold results
summeddata <- data.frame()
grps <- vector()

for (i in 1:length(eqns)) {
eq <- eqns[[i]]
for (j in 1:length(eq)) {
eq1 <- eq[[j]]
eqname <- names(eq[j])
nutrient <- ifelse(grepl("N", names(eq[j])), "Total Nitrogen as N", "Total Phosphorus as P")
for (i in 1:length(unique(eqns$Nutrient))) {
nut = unique(eqns$Nutrient)[i]
nutqns = subset(eqns, eqns$Nutrient==nut)
for (j in 1:length(unique(nutqns$EQN))) {
eqnum = unique(nutqns$EQN)[j]
eqn = subset(nutqns, nutqns$EQN==eqnum)$SummationName
nutrient <- ifelse(nut=="N", "Total Nitrogen as N", "Total Phosphorus as P")
# for each equation, see if any groups contain all required subspecies, and for each pick the variant with the lowest rank.
# combine group with other groups and remove group ID from consideration for the next equation
out <- sum_dat %>%
dplyr::filter(!TADA.NutrientSummationGroup %in% grps) %>%
dplyr::group_by(TADA.NutrientSummationGroup) %>%
# dplyr::filter(all(eq1 %in% SummationName)) %>% # this line ensures that ALL subspecies are present within an equation group, not just one or more
dplyr::filter(SummationName %in% eq1) %>%
dplyr::filter(all(eqn %in% SummationName)) %>% # this line ensures that ALL subspecies are present within an equation group, not just one or more
dplyr::filter(SummationName %in% eqn) %>%
dplyr::mutate(TADA.NutrientSummationEquation = paste0(unique(SummationName), collapse = " + "))

out <- out %>%
Expand Down
47 changes: 47 additions & 0 deletions inst/extdata/NP_equations.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Nutrient,EQN,SummationName
N,0,TOTAL N (UNFILTERED)
N,1,TOTAL N (FILTERED)
N,1,TOTAL N (PARTICLE)
N,2,TKN
N,2,NITRATE
N,2,NITRITE
N,3,TKN
N,3,NITRATE + NITRITE
N,4,ORG N
N,4,AMMON
N,4,NITRATE
N,4,NITRITE
N,5,ORG N
N,5,AMMON
N,5,NITRATE + NITRITE
N,6,AMMON
N,6,NITRATE
N,6,NITRITE
N,7,AMMON
N,7,NITRATE + NITRITE
N,8,TKN
N,8,NITRATE
N,9,TKN
N,9,NITRITE
N,10,ORG N
N,10,AMMON
N,11,ORG N
N,11,NITRATE
N,12,ORG N
N,12,NITRITE
N,13,ORG N
N,13,NITRATE + NITRITE
N,14,AMMON
N,14,NITRATE
N,15,AMMON
N,15,NITRITE
N,16,TKN
N,17,NITRATE
N,18,NITRITE
N,19,NITRATE + NITRITE
N,20,AMMON
N,21,ORG N
N,22,OTHER N
P,1,PHOSP
P,2,PO4
P,3,OTHER P
File renamed without changes.
31 changes: 28 additions & 3 deletions man/TADA_CalculateTotalNP.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3f5405c

Please sign in to comment.