From 1283fa52ca842c934abfda0f1d35f4b49eec04e6 Mon Sep 17 00:00:00 2001 From: hillarymarler <152432687+hillarymarler@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:06:50 -0400 Subject: [PATCH 1/9] Update ATTAINSCrosswalks.R --- R/ATTAINSCrosswalks.R | 90 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/R/ATTAINSCrosswalks.R b/R/ATTAINSCrosswalks.R index eecf18489..c28c78ee5 100644 --- a/R/ATTAINSCrosswalks.R +++ b/R/ATTAINSCrosswalks.R @@ -5068,4 +5068,94 @@ TADA_ReviewATTAINSWaterTypes <- function( return(.data) } +} + +#' Assign Salt or Freshwater Indicator +#' +#' Assigns A Salt or Freshwater Indicator at the monitoring location or assessment +#' unit level by either ATTAINS.WaterType or TADA.MonitoringLocationTypeName. +#' +#' @param .data A data frame containing at least one location column +#' (TADA.MonitoringLocationIdentifier or ATTAINS.AssessmentUnitIdentifier) and +#' at least one water type column (TADA.MonitoringLocationTypeName or +#' ATTAINS.WaterType). Columns provided must match the columns selected for +#' indicator assignment in the other function params. +#' @param location_col Character string. Options are "AU" or "ML". When location_col +#' equals "AU", ATTAINS.AssessmentUnitIdentifier is used as the location column. +#' When location_col equals "ML", TADA.MonitoringLocationIdentifier is used as +#' the location_col. Default is location_col equals "AU". +#' @param type_col Character string. Options are "TADA" or "ATTAINS". When +#' type_col equals "TADA", TADA.MonitoringLocationTypeName is used to crosswalk +#' each location with a salt/freshwater indicator. When type_col equals "ATTAINS", +#' ATTAINS.WaterType is used to crosswalk each location with a salt/freshwater +#' indicator. Default is type_col equals "ATTAINS". +#' +#' @return The input data frame with an added TADA.SaltFreshIndicator column. +#' @export +#' +#' @examples +#' +#' \dontrun{ +#' +#' } +TADA_SaltFreshIndicator <- function(.data, + location_col = "AU", + type_col = "ATTAINS") { + + reqs <- data.frame( + col = character(), + reason = character(), + stringsAsFactors = FALSE + ) + + if (location_col == "AU") { + reqs <- rbind(reqs, data.frame( + col = "ATTAINS.AssessmentUnitIdentifier", + reason = "location_col equals 'AU'", + stringsAsFactors = FALSE + )) + } else { + reqs <- rbind(reqs, data.frame( + col = "TADA.MonitoringLocationIdentifier", + reason = "location_col equals 'ML'", + stringsAsFactors = FALSE + )) + } + + if (type_col == "ATTAINS") { + reqs <- rbind(reqs, data.frame( + col = "ATTAINS.WaterType", + reason = "type_col equals 'ATTAINS'", + stringsAsFactors = FALSE + )) + } else { + reqs <- rbind(reqs, data.frame( + col = "TADA.MonitoringLocationTypeName", + reason = "type_col equals 'TADA'", + stringsAsFactors = FALSE + )) + } + + missing <- unique(reqs$col[!reqs$col %in% names(.data)]) + + if (length(missing) > 0) { + missing_info <- reqs[reqs$col %in% missing, ] + missing_info <- missing_info[!duplicated(missing_info$col), ] + + msg <- paste0( + "TADA_SaltFreshIndicator: missing required column(s):\n", + paste0( + " - ", missing_info$col, + " (needed because ", missing_info$reason, ")", + collapse = "\n" + ) + ) + + stop(msg, call. = FALSE) + } + + + + + } From 3eacdc1934ab953d4f35f9becda1fba72459941c Mon Sep 17 00:00:00 2001 From: hillarymarler <152432687+hillarymarler@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:09:31 -0400 Subject: [PATCH 2/9] add salftfreshindicator function and crosswalk refs --- NAMESPACE | 1 + R/ATTAINSCrosswalks.R | 81 +++++++++++- inst/extdata/ATTAINSWaterTypeToSaltFresh.csv | 55 +++++++++ inst/extdata/WQPMonLocTypeToSaltFresh.csv | 122 +++++++++++++++++++ man/TADA_SaltFreshIndicator.Rd | 39 ++++++ tests/testthat/test-ATTAINSCrosswalks.R | 87 +++++++++++++ 6 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 inst/extdata/ATTAINSWaterTypeToSaltFresh.csv create mode 100644 inst/extdata/WQPMonLocTypeToSaltFresh.csv create mode 100644 man/TADA_SaltFreshIndicator.Rd diff --git a/NAMESPACE b/NAMESPACE index ab25fc572..fea50adb4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -95,6 +95,7 @@ export(TADA_RenametoLegacy) export(TADA_RetainRequired) export(TADA_ReviewATTAINSWaterTypes) export(TADA_RunKeyFlagFunctions) +export(TADA_SaltFreshIndicator) export(TADA_Scatterplot) export(TADA_SimpleCensoredMethods) export(TADA_Stats) diff --git a/R/ATTAINSCrosswalks.R b/R/ATTAINSCrosswalks.R index c28c78ee5..72960f1ce 100644 --- a/R/ATTAINSCrosswalks.R +++ b/R/ATTAINSCrosswalks.R @@ -5097,7 +5097,30 @@ TADA_ReviewATTAINSWaterTypes <- function( #' #' \dontrun{ #' +#' # Get test data with both freshwater and saltwater results +#' testdat <- TADA_DataRetrieval(statecode = "OR", +#' startDate = "2023-06-01", +#' endDate = "2023-06-15", +#' characteristicType = "Physical", +#' ask = FALSE) +#' +#' # Assign saltfresh indicator based on TADA.MonitoringLocationTypeName, +#' # using TADA.MonitoringLocationIdentifier as location grouping +#' TADA.example <- TADA_SaltFreshIndicator(testdat, +#' location_col = "ML", +#' type_col = "TADA") +#' +#' # Assign ATTAINS water types to test data +#' testdat.ATTAINSwattypes <- testdat |> +#' TADA_CrosswalkATTAINSWaterTypes() +#' +#' # Assign saltfresh indicator based on ATTAINS.WaterType, +#' # using ATTAINS.AssessmentUnitIdentifier as location grouping +#' ATTAINS.example <- TADA_SaltFreshIndicator(testdat.ATTAINSwattypes, +#' location_col = "AU", +#' type_col = "ATTAINS") #' } +#' TADA_SaltFreshIndicator <- function(.data, location_col = "AU", type_col = "ATTAINS") { @@ -5154,8 +5177,64 @@ TADA_SaltFreshIndicator <- function(.data, stop(msg, call. = FALSE) } + # Get unique combinations of location_col and type_col in .data + select.cols <- c(reqs$col[1], reqs$col[2]) + unique.pairs <- .data |> + dplyr::select(dplyr::all_of(select.cols)) |> + dplyr::distinct() + # Select which crosswalk is needed + if(reqs$col[1] == "ATTAINS.AssessmentUnitIdentifier") { + cw.name <- "ATTAINSWaterTypeToSaltFresh.csv" -} + cw.cols <- c("ATTAINS.WaterType", + "TADA.SaltFreshIndicator") + + } else { + + cw.name <- "WQPMonLocTypeToSaltFresh.csv" + + # will need to rename "Name" col + cw.cols <- c("TADA.MonitoringLocationTypeName", + "TADA.SaltFreshIndicator") + } + + # Load crosswalk + crosswalk <- utils::read.csv(system.file( + "extdata", + cw.name, + package = "EPATADA" + )) + + # Rename col if required + if ("Name" %in% names(crosswalk)) { + crosswalk <- dplyr::rename( + crosswalk, + TADA.MonitoringLocationTypeName = Name + ) + } + + # Retain required columns, keep only distinct rows, and join to unique pairs + crosswalk <- crosswalk |> + dplyr::select(dplyr::all_of(cw.cols)) |> + dplyr::mutate(dplyr::across(where(is.character), toupper)) |> + dplyr::distinct() |> + dplyr::right_join(unique.pairs, + by = dplyr::join_by(!!rlang::sym(reqs$col[2]))) |> + dplyr::distinct() + + # Join crosswalk to .data + .data <- .data |> + dplyr::left_join(crosswalk, + by = dplyr::join_by(!!rlang::sym(reqs$col[2]))) + + # Remove intermediate objects + rm(unique.pairs, cw.cols, cw.name, + location_col, missing, select.cols, + type_col, crosswalk, reqs) + + # Return data with salt fresh indicator + return(.data) + } diff --git a/inst/extdata/ATTAINSWaterTypeToSaltFresh.csv b/inst/extdata/ATTAINSWaterTypeToSaltFresh.csv new file mode 100644 index 000000000..141a15aa4 --- /dev/null +++ b/inst/extdata/ATTAINSWaterTypeToSaltFresh.csv @@ -0,0 +1,55 @@ +ATTAINS.WaterType,TADA.SaltFreshIndicator +CHANNEL,Freshwater +"STREAM, COASTAL",Freshwater +STREAM,Freshwater +STREAM/CREEK/RIVER,Freshwater +ESTUARY,Saltwater +"ESTUARY, FRESHWATER",Freshwater +GREAT LAKES BEACH,Freshwater +BEACH,Saltwater +GREAT LAKES SHORELINE,Freshwater +COASTAL,Saltwater +COASTAL & BAY SHORELINE,Saltwater +LAKE,Freshwater +"LAKE, FRESHWATER",Freshwater +"LAKE, NATURAL",Freshwater +LAKE/RESERVOIR/POND,Freshwater +"LAKE, SPRINGS",Freshwater +"LAKE, WILD RICE",Freshwater +"LAKE, PLAYA",Freshwater +"LAKE, SALINE",Saltwater +POND,Freshwater +RESERVOIR,Freshwater +INLAND LAKE SHORELINE,Freshwater +OCEAN,Saltwater +OCEAN/NEAR COASTAL,Saltwater +RIVER,Freshwater +"STREAM, TIDAL", +"RIVER, TIDAL", +DITCH OR CANAL,Freshwater +CONNECTING CHANNEL,Freshwater +CREEK,Freshwater +WETLAND,Freshwater +"WETLANDS, FRESHWATER",Freshwater +"WETLANDS, RIVERINE",Freshwater +"WETLANDS, SLOPE",Freshwater +"WETLANDS, TIDAL", +"WETLANDS, DEPRESSIONAL",Freshwater +MARSH,Freshwater +"ESTUARY, FRESHWATER",Freshwater +GREAT LAKES OPEN WATER,Freshwater +GREAT LAKES BAYS & HARBORS,Freshwater +GREAT LAKES CONNECTING CHANNEL,Freshwater +IMPOUNDMENT,Freshwater +"STREAM, INTERMITTENT",Freshwater +"STREAM, EPHEMERAL",Freshwater +"STREAM, PERRENIAL",Freshwater +"RIVER, WILD RICE",Freshwater +WASH,Freshwater +SPRING,Freshwater +RIVERINE BACKWATER,Freshwater +"CREEK, INTERMITTENT",Freshwater +"STREAM, PERENNIAL",Freshwater +"LAKE, SPRING",Freshwater +SPRINGSHED,Freshwater +"WETLAND, TIDAL", diff --git a/inst/extdata/WQPMonLocTypeToSaltFresh.csv b/inst/extdata/WQPMonLocTypeToSaltFresh.csv new file mode 100644 index 000000000..5fbdd9fb1 --- /dev/null +++ b/inst/extdata/WQPMonLocTypeToSaltFresh.csv @@ -0,0 +1,122 @@ +Domain,Unique Identifier,Name,Description,TADA.SaltFreshIndicator +Monitoring Location Type(MonitoringLocationTypeName),86,Atmosphere,Atmosphere monitoring stations provide weather data about conditions,NA +Monitoring Location Type(MonitoringLocationTypeName),58,BEACH Program Site-Channelized stream,"The process of straightening or redirecting natural streams in an artificially modified or constructed stream bed. Channelization has been carried out for numerous reasons, most often to drain wetlands , direct water flow for agricultural use, and control flooding . While this process makes a stream more useful for human activities, it tends to interfere with natural river habitats and to destabilize stream banks by destroying riparian vegetation.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),59,BEACH Program Site-Estuary,,SALTWATER +Monitoring Location Type(MonitoringLocationTypeName),60,BEACH Program Site-Great Lake,"The Great Lakes, also called the Laurentian Great Lakes and the Great Lakes of North America, are a series of interconnected freshwater lakes primarily in the upper mid-east region of North America, on the Canada–United States border, which connect to the Atlantic Ocean through the Saint Lawrence River.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),61,BEACH Program Site-Lake,"A lake is an area filled with water, localized in a basin, that is surrounded by land, apart from any river or other outlet that serves to feed or drain the lake",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),63,BEACH Program Site-Land,"Land, sometimes referred to as dry land, is the solid surface of Earth that is not permanently covered by water.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),62,BEACH Program Site-Land runoff,"Also known as overland flow is the flow of water that occurs when excess stormwater, meltwater, or other sources flows over the Earth's surface.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),64,BEACH Program Site-Ocean,An ocean is a body of water that composes much of a planet's hydrosphere.,SALTWATER +Monitoring Location Type(MonitoringLocationTypeName),65,BEACH Program Site-River/Stream,"A river is a natural flowing watercourse, usually freshwater, flowing towards an ocean, sea, lake or another river. In some cases a river flows into the ground and becomes dry at the end of its course without reaching another body of water. ",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),66,BEACH Program Site-Storm sewer,The storm sewer is a system designed to carry rainfall runoff and other drainage.,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),67,BEACH Program Site-Waste sewer,"The wastewater from residences and institutions, carrying bodily wastes (primarily feces and urine), washing water, food preparation wastes, laundry wastes, and other waste products of normal living, are classed as domestic or sanitary sewage.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),6,Borehole,"A borehole is a narrow shaft bored in the ground, either vertically or horizontally. A borehole may be constructed for many different purposes, including the extraction of water, other liquids (such as petroleum) or gases (such as natural gas), as part of a geotechnical investigation, environmental site assessment,",NA +Monitoring Location Type(MonitoringLocationTypeName),5,CERCLA Superfund Site,The Superfund site assessment process evaluates potential or confirmed releases of hazardous substances that may pose a threat to human health or the environment using the Hazard Ranking System (HRS) criteria guide,NA +Monitoring Location Type(MonitoringLocationTypeName),1,Canal Drainage,"As a channel drainage system it is designed to eliminate the need for further pipework systems to be installed in parallel to the drainage, reducing the environmental impact of production as well as improving water collection.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),2,Canal Irrigation,"Irrigation canals are the main waterways that bring irrigation water from a water source to the areas to be irrigated. They can be lined with concrete, brick, stone, or a flexible membrane to prevent seepage and erosion.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),3,Canal Transport,"Canals are human-made channels for water conveyance, or to service water transport vehicles. In most cases, the engineered works will have a series of dams and locks that create areas of low speed current flow. These areas are referred to as slack water levels, often just called levels.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),4,Cave,"A cave is a hollow place in the ground, specifically a natural underground space large enough for a human to enter. Caves form naturally by the weathering of rock and often extend deep underground. ",NA +Monitoring Location Type(MonitoringLocationTypeName),10,Channelized Stream,"The process of straightening or redirecting natural streams in an artificially modified or constructed stream bed. Channelization has been carried out for numerous reasons, most often to drain wetlands , direct water flow for agricultural use, and control flooding . While this process makes a stream more useful for human activities, it tends to interfere with natural river habitats and to destabilize stream banks by destroying riparian vegetation.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),11,Combined Sewer,"A combined sewer system (CSS) collects rainwater runoff, domestic sewage, and industrial wastewater into one pipe. Under normal conditions, it transports all of the wastewater it collects to a sewage treatment plant for treatment, then discharges to a water body. Combined sewer overflows (CSOs) contain untreated or partially treated human and industrial waste, toxic materials, and debris as well as stormwater.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),87,Constructed Diversion Dam,"A diversion dam is a dam that diverts all or a portion of the flow of a river from its natural course. Diversion dams do not generally impound water in a reservoir. Instead, the water is diverted into an artificial water course or canal, which may be used for irrigation or return to the river after passing through hydroelectric generators, flow into a different river or be itself dammed forming a reservoir.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),88,Constructed Tunnel,"an artificial underground passage, especially one built through a hill or under a building, road, or river.",NA +Monitoring Location Type(MonitoringLocationTypeName),89,Constructed Water Transport Structure,a system of structures and measures that support the intentional movement of water over large distances. simple aqueducts to transport water above ground level. short pipelines to transport water above or under another structure such as a water canal or an access road,NA +Monitoring Location Type(MonitoringLocationTypeName),12,Constructed Wetland,"A constructed wetland (CW) is an artificial wetland to treat municipal or industrial wastewater, greywater or stormwater runoff. It may also be designed for land reclamation after mining, or as a mitigation step for natural areas lost to land development.Constructed wetlands are engineered systems that use natural functions vegetation, soil, and organisms to treat wastewater",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),13,Estuary,"a partially enclosed coastal body of brackish water with one or more rivers or streams flowing into it, and with a free connection to the open sea +Estuaries form a transition zone between river environments and maritime environments. +The sea water entering the estuary is diluted by the fresh water flowing from rivers and streams. +",SALTWATER +Monitoring Location Type(MonitoringLocationTypeName),97,Estuary-Freshwater,"Freshwater estuaries are semi-enclosed areas of the Great Lakes in which lake and river water mix, forming a transition zone between river and lake environments that are chemically distinct",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),14,Facility Industrial,"a facility composed of one or more pieces of equipment connected to or part of a structure and designed to provide a service such as heat or electricity or water or sewage disposal. ""the price of the house included all utilities",NA +Monitoring Location Type(MonitoringLocationTypeName),15,Facility Municipal Sewage (POTW),"Treatment works treating domestic sewage means a POTW or any other sewage sludge or waste water treatment devices or systems, regardless of ownership (including federal facilities), used in the storage, treatment, recycling, and reclamation of municipal or domestic sewage, including land dedicated for the disposal of sewage sludge. This definition does not include septic tanks or similar devices.",NA +Monitoring Location Type(MonitoringLocationTypeName),17,Facility Other,"a facility composed of one or more pieces of equipment connected to or part of a structure and designed to provide a service such as Reclaimed water can supply needed water for some purposes Reclaimed wastewater frees up fresh water that can be used somewhere else, such as for drinking water",NA +Monitoring Location Type(MonitoringLocationTypeName),18,Facility Privately Owned Non-industrial,Privately owned treatment works means any device or system which is (a) used to treat wastes from any facility whose operator is not the operator of the treatment works,NA +Monitoring Location Type(MonitoringLocationTypeName),16,Facility Public Water Supply (PWS),"A Public Water System is a public water supply for the provision to the public of piped water for human consumption, A Public Water System includes any collection, treatment, storage, +and distribution facilities under control of such system, including the operator or administrator of such system, and is used primarily in +connection with such system and any collection or pretreatment storage facilities not under such control which are used primarily in +connection with such system.”",NA +Monitoring Location Type(MonitoringLocationTypeName),72,Floodwater Urban,"A flood is an overflow of water that submerges land that is usually dry In the sense of ""urban runoff water"". it may occur due to an accumulation of rainwater on saturated ground in an areal flood.",NA +Monitoring Location Type(MonitoringLocationTypeName),73,Floodwater non-Urban,"A flood is an overflow of water that submerges land that is usually dry Flooding may occur as an overflow of water from water bodies, such as a river, lake, or ocean, in which the water overtops or breaks levees, resulting in some of that water escaping its usual boundaries",NA +Monitoring Location Type(MonitoringLocationTypeName),19,Gallery,An infiltration gallery is a structure including perforated conduits in gravel to expedite transfer of water to or from a soil.,NA +Monitoring Location Type(MonitoringLocationTypeName),76,Gas-Condensate,"Natural-gas condensate, also called natural gas liquids, is a low-density mixture of hydrocarbon liquids that are present as gaseous components in the raw natural gas produced from many natural gas fields. ",NA +Monitoring Location Type(MonitoringLocationTypeName),77,Gas-Engine,"A gas engine is an internal combustion engine that runs on a gaseous fuel, such as coal gas, producer gas, biogas, landfill gas or natural gas.",NA +Monitoring Location Type(MonitoringLocationTypeName),78,Gas-Extraction,"Oil and Gas Extraction is the exploration and production of petroleum and natural gas from wells. The industry generates wastewater from the water extracted from the geological formations and from chemicals used during exploration, well drilling and production of oil and gas.",NA +Monitoring Location Type(MonitoringLocationTypeName),79,Gas-Flare,"A gas flare, alternatively known as a flare stack, is a gas combustion device used in industrial plants such as petroleum refineries, chemical plants, natural gas processing plants as well as at oil or gas production sites having oil wells, gas wells, offshore oil and gas rigs and landfills.",NA +Monitoring Location Type(MonitoringLocationTypeName),80,Gas-Monitoring Probe,"Gas monitoring probes are used to enhance environmental protection at landfills. Gas +concentrations are measured at permit or regulatory specified time intervals. This process +allows potential environmental concerns to be identified early, evaluated and corrected +(when necessary) in accordance with regulations and sound scientific approaches.",NA +Monitoring Location Type(MonitoringLocationTypeName),81,Gas-Passive Vent,Dispersion of gas safely from soil.,NA +Monitoring Location Type(MonitoringLocationTypeName),92,Gas-Subslab,Sub-slab Soil Gas: Sub-slab samples are collected to characterize the nature and extent of vapor contamination in the soil immediately beneath a building with a slab or beneath the basement floor.,NA +Monitoring Location Type(MonitoringLocationTypeName),82,Gas-Temporary,a gas capable of liquefaction,NA +Monitoring Location Type(MonitoringLocationTypeName),20,Great Lake,"The Great Lakes, also called the Laurentian Great Lakes and the Great Lakes of North America, are a series of interconnected freshwater lakes primarily in the upper mid-east region of North America, on the Canada–United States border, which connect to the Atlantic Ocean through the Saint Lawrence River.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),98,Intertidal,denoting the area of a seashore which is covered at high tide and uncovered at low tide,SALTWATER +Monitoring Location Type(MonitoringLocationTypeName),21,Lake,"A lake is an area filled with water, localized in a basin, that is surrounded by land, apart from any river or other outlet that serves to feed or drain the lake",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),50,Land,"Land, sometimes referred to as dry land, is the solid surface of Earth that is not permanently covered by water.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),22,Land Flood Plain,"An area of land adjacent to a stream or river which stretches from the banks of its channel to the base of the enclosing valley walls, and which experiences flooding during periods of high discharge.",NA +Monitoring Location Type(MonitoringLocationTypeName),23,Land Runoff,"Also known as overland flow is the flow of water that occurs when excess stormwater, meltwater, or other sources flows over the Earth's surface.",NA +Monitoring Location Type(MonitoringLocationTypeName),24,Landfill,A site for the disposal of waste materials by burial.,NA +Monitoring Location Type(MonitoringLocationTypeName),83,Leachate-Extraction,The pump systems which extract the leachate from the wastes,NA +Monitoring Location Type(MonitoringLocationTypeName),84,Leachate-Head Well,The wells and boreholes within the landfill into which the leachate collection system conveys the leachate. The well head where samples of water are taken determining water quality in source Leachate,NA +Monitoring Location Type(MonitoringLocationTypeName),71,Leachate-Lysimeter,Is a measuring device which can be used to measure the amount of actual evapotranspiration which is released by plants (usually crops or trees),NA +Monitoring Location Type(MonitoringLocationTypeName),85,Leachate-SamplePoint,"The point where samples of water are taken determining water quality in source the pipes/pipelines which convey the leachate to the collection tank, or treatment plant location. Leachate is the liquid that drains or 'leaches' from a landfill. It varies widely in composition regarding the age of the landfill and the type of waste that it contains. It usually contains both dissolved and suspended material.",NA +Monitoring Location Type(MonitoringLocationTypeName),91,Local Air Monitoring Station,"Ambient air monitoring is the systematic, long-term assessment of pollutant levels by measuring the quantity and types of certain pollutants in the surrounding, outdoor air.",NA +Monitoring Location Type(MonitoringLocationTypeName),95,Mine Pit,"Open-pit mining, also known as opencast mining, is a surface mining technique that extracts minerals from an open pit in the ground. Open-pits are sometimes called ‘quarries’ when they produce building materials and dimension stone.",NA +Monitoring Location Type(MonitoringLocationTypeName),25,Mine/Mine Discharge,"Formed when pyrite (an iron sulfide) is exposed and reacts with air and water to form sulfuric acid and dissolved iron. Some or all of this iron can precipitate to form the red, orange, or yellow sediments in the bottom of streams containing mine drainage. The acid runoff further dissolves heavy metals such as copper, lead, and mercury into groundwater or surface water. ",NA +Monitoring Location Type(MonitoringLocationTypeName),26,Mine/Mine Discharge Adit (Mine Entrance),"An adit (from Latin aditus, entrance) is an entrance to an underground mine which is horizontal or nearly horizontal, by which the mine can be entered, drained of water, ventilated, and minerals extracted at the lowest convenient level.",NA +Monitoring Location Type(MonitoringLocationTypeName),27,Mine/Mine Discharge Tailings Pile,Materials left over after the process of separating the valuable fraction from the uneconomic fraction (gangue) of an ore. ,NA +Monitoring Location Type(MonitoringLocationTypeName),28,Mine/Mine Discharge Waste Rock Pile,"Mine drainage is metal-rich water formed from chemical reaction between water and rocks containing. sulfur-bearing minerals. • The runoff formed is usually acidic and frequently comes from areas where ore or coal mining activities. have exposed rocks containing pyrite, a sulfur bearing mineral",NA +Monitoring Location Type(MonitoringLocationTypeName),29,National Air Monitoring Station,"Ambient air monitoring is the systematic, long-term assessment of pollutant levels by measuring the quantity and types of certain pollutants in the surrounding, outdoor air.",NA +Monitoring Location Type(MonitoringLocationTypeName),30,Ocean,An ocean is a body of water that composes much of a planet's hydrosphere.,SALTWATER +Monitoring Location Type(MonitoringLocationTypeName),90,Oil and Gas Well,An oil well is a boring in the Earth that is designed to bring petroleum oil hydrocarbons to the surface. Usually some natural gas is released along with the oil. A well that is designed to produce only gas may be termed a gas well.,NA +Monitoring Location Type(MonitoringLocationTypeName),52,Other-Ground Water,The water present beneath Earth's surface in soil pore spaces and in the fractures of rock formations.,NA +Monitoring Location Type(MonitoringLocationTypeName),51,Other-Surface Water,"water on the surface of continents such as in a river, lake, or wetland.",NA +Monitoring Location Type(MonitoringLocationTypeName),57,"Pipe, Unspecified Source","Methods used to remove already formed contaminants from a stream of air, water, waste, product or similar. ",NA +Monitoring Location Type(MonitoringLocationTypeName),54,Playa,"Known as an alkali flat or sabkha, a desert basin with no outlet which periodically fills with water to form a temporary lake.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),201,Pond,"Naturally occurring. A pond is an area filled with water, that is smaller than a lake. It may arise naturally in floodplains as part of a river system, or be a somewhat isolated depression (such as a kettle, vernal pool, or prairie pothole).",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),70,Pond-Anchialine,A landlocked body of water with a subterranean connection to the ocean. ,SALTWATER +Monitoring Location Type(MonitoringLocationTypeName),93,Pond-Sediment,"A naturally occurring material that is broken down by processes of weathering and erosion, and is subsequently transported by the action of wind, water, or ice or by the force of gravity acting on the particles.",NA +Monitoring Location Type(MonitoringLocationTypeName),94,Pond-Stock,Ponds for a specific purpose for watering livestock.,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),68,Pond-Stormwater,"Stormwater, also spelled storm water, is water that originates during precipitation events and snow/ice melt.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),75,Pond-Wastewater,"Any water that has been affected by human use. Wastewater is ""used water from any combination of domestic, industrial, commercial or agricultural activities, surface runoff or stormwater, and any sewer inflow or sewer infiltration"".",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),31,Reservoir,"An enlarged natural or artificial lake, pond or impoundment created using a dam or lock to store water.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),32,River/Stream,A body of water with surface water flowing within the bed and banks of a channel.,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),69,River/Stream Ephemeral,A stream that flows only briefly during and following a period of rainfall in the immediate locality,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),55,River/Stream Intermittent,Mormally cease flowing for weeks or months each year. ,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),56,River/Stream Perennial,A stream or river (channel) that has continuous flow in parts of its stream bed all year round during years of normal rainfall.,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),74,River/stream Effluent-Dominated,A stream or river that gets a significant portion of its flow from effulent discharge.,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),33,Riverine Impoundment,"Impoundments (also known as reservoirs) are artificially created standing water bodies, produced by dams on streams or rivers.",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),53,Seep,"A moist or wet place where water, usually groundwater, reaches the earth's surface from an underground aquifer.",NA +Monitoring Location Type(MonitoringLocationTypeName),101,Soil sediment,The unconsolidated mineral or organic material on the immediate surface of the Earth that serves as a natural medium for the growth of land plants,NA +Monitoring Location Type(MonitoringLocationTypeName),100,Source-ManMade,"Industrial, agricultural, stormwater, sewer/septic, discharge/pipe, lagoon, or other source",NA +Monitoring Location Type(MonitoringLocationTypeName),7,Spigot / Faucet,"A spigot is a single knob faucet that only has one pipe it controls, like the outdoor spigot that you connect a garden hose to. A tap is used when there isn't a pipe",NA +Monitoring Location Type(MonitoringLocationTypeName),34,Spring,the result of an aquifer being filled to the point that the water overflows onto the land surface.,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),35,State/Local Air Monitoring Station,A Facility to measure systematically concentrations of pollutants in ambient air. Synonym: Air quality measurement station.,NA +"Added manually, from USGS results",,Stream,,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),36,Storm Sewer,A system designed to carry rainfall runoff and other drainage.,NA +Monitoring Location Type(MonitoringLocationTypeName),99,Subtidal,Refers to the area where the seabed is below the lowest tide,SALTWATER +Monitoring Location Type(MonitoringLocationTypeName),181,Sump,A sump is a shallow borehole (no well construction) that intersects the water table,NA +Monitoring Location Type(MonitoringLocationTypeName),8,Survey Monument,"Boundary monuments are placed at every corner of the property, including any angle or change of direction of the boundary line.",NA +Monitoring Location Type(MonitoringLocationTypeName),9,Test Pit,"A trial pit (or test pit) is an excavation of ground in order to study or sample the composition and structure of the subsurface, usually dug during a site investigation, a soil survey or a geological survey. Trial pits are dug before the construction. They are dug to determine the geology and the water table of that site.",NA +Monitoring Location Type(MonitoringLocationTypeName),37,Waste Pit,"A mud pit in which a supply of drilling fluid has been stored. Also, a waste pit, usually an excavated, earthen-walled pit. It may be lined with plastic to prevent soil contamination.",NA +Monitoring Location Type(MonitoringLocationTypeName),38,Waste Sewer,a waste pipe that carries away sewage or surface water,NA +Monitoring Location Type(MonitoringLocationTypeName),39,Well,"An excavation or structure created in the ground by digging, driving, or drilling to access liquid resources, usually water.",NA +Monitoring Location Type(MonitoringLocationTypeName),161,Wetland Estuarine-Ditch,"Open water estuary, bay, sound Vegetated and non-vegetated brackish and saltwater ditch", +Monitoring Location Type(MonitoringLocationTypeName),40,Wetland Estuarine-Emergent,"Open water estuary, bay, sound Herbaceous marsh, fen, swale and wet meadow", +Monitoring Location Type(MonitoringLocationTypeName),41,Wetland Estuarine-Forested,"Open water estuary, bay, sound Vegetated brackish and saltwater forest", +Monitoring Location Type(MonitoringLocationTypeName),163,Wetland Estuarine-Marsh,"Open water estuary, bay, sound Vegetated brackish and saltwater marsh", +Monitoring Location Type(MonitoringLocationTypeName),165,Wetland Estuarine-Pool,"Open water estuary, bay, sound Vegetated brackish and saltwater pool: lagoons", +Monitoring Location Type(MonitoringLocationTypeName),42,Wetland Estuarine-Scrub-Shrub,"Open water estuary, bay, sound Vegetated brackish and saltwater scrub-shrub", +Monitoring Location Type(MonitoringLocationTypeName),162,Wetland Estuarine-Tidal Creek,"Open water estuary, bay, sound Vegetated brackish and saltwater tidal creek", +Monitoring Location Type(MonitoringLocationTypeName),157,Wetland Lacustrine-Aquatic Bed,Includes nontidal wetlands fringing lakes and dominated by floating leaved and submergent plants, +Monitoring Location Type(MonitoringLocationTypeName),43,Wetland Lacustrine-Emergent,"bounded by upland or by wetland dominated by trees, shrubs, persistent emergents, emergent mosses, or lichens", +Monitoring Location Type(MonitoringLocationTypeName),158,Wetland Lacustrine-Unconsolidated Bottom,Includes nontidal wetlands ringing lakes in which substrate is at least 25% particles smaller than stones and vegetative cover less than 30%, +Monitoring Location Type(MonitoringLocationTypeName),96,Wetland Palustrine Pond,includes all nontidal wetlands dominated by pond and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),44,Wetland Palustrine-Emergent,"includes all nontidal wetlands characterized by erect, rooted, herbaceous hydrophytes, excluding mosses and lichens and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),45,Wetland Palustrine-Forested,"includes all nontidal wetlands dominated by trees, forest, and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),46,Wetland Palustrine-Moss-Lichen,"includes all nontidal wetlands dominated by mosses or lichens, and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),47,Wetland Palustrine-Shrub-Scrub,"includes all nontidal wetlands dominated by, shrubs, scrub and all such wetlands that occur in tidal areas where salinity due to ocean-derived salts is below 0.5 ‰",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),160,Wetland Riverine-Aquatic Bed,Includes wetlands connected by or within low gradient rivers dominated by floating leaved and submergent plants ,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),48,Wetland Riverine-Emergent,"wetlands connected by rivers. ... They are found along the edges of rivers, streams and creeks and include rivers, floodplains, marshes, lakes and billabongs. characterized by erect, rooted, herbaceous hydrophytes, excluding mosses and lichens",FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),159,Wetland Riverine-Unconsolidated Bottom,Includes nontidal wetlands connected by rivers in which substrate is at least 25% particles smaller than stones and vegetative cover less than 30% ,FRESHWATER +Monitoring Location Type(MonitoringLocationTypeName),49,Wetland Undifferentiated,"a land area that is saturated with water, either permanently or seasonally, It primarily is characteristized by vegetation of aquatic plants, adapted to the unique hydric soil.",FRESHWATER diff --git a/man/TADA_SaltFreshIndicator.Rd b/man/TADA_SaltFreshIndicator.Rd new file mode 100644 index 000000000..7e858cc2e --- /dev/null +++ b/man/TADA_SaltFreshIndicator.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ATTAINSCrosswalks.R +\name{TADA_SaltFreshIndicator} +\alias{TADA_SaltFreshIndicator} +\title{Assign Salt or Freshwater Indicator} +\usage{ +TADA_SaltFreshIndicator(.data, location_col = "AU", type_col = "ATTAINS") +} +\arguments{ +\item{.data}{A data frame containing at least one location column +(TADA.MonitoringLocationIdentifier or ATTAINS.AssessmentUnitIdentifier) and +at least one water type column (TADA.MonitoringLocationTypeName or +ATTAINS.WaterType). Columns provided must match the columns selected for +indicator assignment in the other function params.} + +\item{location_col}{Character string. Options are "AU" or "ML". When location_col +equals "AU", ATTAINS.AssessmentUnitIdentifier is used as the location column. +When location_col equals "ML", TADA.MonitoringLocationIdentifier is used as +the location_col. Default is location_col equals "AU".} + +\item{type_col}{Character string. Options are "TADA" or "ATTAINS". When +type_col equals "TADA", TADA.MonitoringLocationTypeName is used to crosswalk +each location with a salt/freshwater indicator. When type_col equals "ATTAINS", +ATTAINS.WaterType is used to crosswalk each location with a salt/freshwater +indicator. Default is type_col equals "ATTAINS".} +} +\value{ +The input data frame with an added TADA.SaltFreshIndicator column. +} +\description{ +Assigns A Salt or Freshwater Indicator at the monitoring location or assessment +unit level by either ATTAINS.WaterType or TADA.MonitoringLocationTypeName. +} +\examples{ + +\dontrun{ + +} +} diff --git a/tests/testthat/test-ATTAINSCrosswalks.R b/tests/testthat/test-ATTAINSCrosswalks.R index 3f8d42d9d..3908513dc 100644 --- a/tests/testthat/test-ATTAINSCrosswalks.R +++ b/tests/testthat/test-ATTAINSCrosswalks.R @@ -790,3 +790,90 @@ test_that("TADA_CreatePointAUs does not modify existing non-missing, non-blank A c("EXISTING_AU_001", "WQX_LOC2") ) }) + +# tests for TADA_SaltFreshIndicator +testthat::test_that("TADA_SaltFresh Indicator errors when required columns are missing for AU/ATTAINS", { + df <- data.frame( + ATTAINS.WaterType = "Fresh", + stringsAsFactors = FALSE + ) + + testthat::expect_error( + TADA_SaltFreshIndicator(df, location_col = "AU", type_col = "ATTAINS"), + "missing required column\\(s\\)" + ) + testthat::expect_error( + TADA_SaltFreshIndicator(df, location_col = "AU", type_col = "ATTAINS"), + "ATTAINS\\.AssessmentUnitIdentifier" + ) +}) + +testthat::test_that("TADA_SaltFreshIndicator errors when required columns are missing for ML/TADA", { + df <- data.frame( + TADA.MonitoringLocationTypeName = "Stream", + stringsAsFactors = FALSE + ) + + testthat::expect_error( + TADA_SaltFreshIndicator(df, location_col = "ML", type_col = "TADA"), + "missing required column\\(s\\)" + ) + testthat::expect_error( + TADA_SaltFreshIndicator(df, location_col = "ML", type_col = "TADA"), + "TADA\\.MonitoringLocationIdentifier" + ) +}) + +testthat::test_that("TADA_SaltFreshIndicator returns data with TADA.SaltFreshIndicator for AU/ATTAINS", { + df <- data.frame( + ATTAINS.AssessmentUnitIdentifier = c("AU1", "AU2"), + ATTAINS.WaterType = c("STREAM/CREEK/RIVER", "BEACH"), + stringsAsFactors = FALSE + ) + + out <- TADA_SaltFreshIndicator(df, location_col = "AU", type_col = "ATTAINS") + + testthat::expect_true("TADA.SaltFreshIndicator" %in% names(out)) + testthat::expect_equal(nrow(out), nrow(df)) +}) + +testthat::test_that("TADA_SaltFreshIndicator returns data with TADA.SaltFreshIndicator for ML/TADA", { + df <- data.frame( + TADA.MonitoringLocationIdentifier = c("ML1", "ML2"), + TADA.MonitoringLocationTypeName = c("RIVER/STREAM EPHEMERAL", "BEACH PROGRAM SITE-OCEAN"), + stringsAsFactors = FALSE + ) + + out <- TADA_SaltFreshIndicator(df, location_col = "ML", type_col = "TADA") + + testthat::expect_true("TADA.SaltFreshIndicator" %in% names(out)) + testthat::expect_equal(nrow(out), nrow(df)) +}) + +testthat::test_that("does not duplicate output rows when input has duplicate pairs", { + df <- data.frame( + ATTAINS.AssessmentUnitIdentifier = c("AU1", "AU1", "AU2"), + ATTAINS.WaterType = c("STREAM/CREEK/RIVER", "STREAM/CREEK/RIVER", "BEACH"), + stringsAsFactors = FALSE + ) + + out <- TADA_SaltFreshIndicator(df, location_col = "AU", type_col = "ATTAINS") + + testthat::expect_equal(nrow(out), nrow(df)) + testthat::expect_true("TADA.SaltFreshIndicator" %in% names(out)) +}) + +testthat::test_that("produces a useful error message listing each missing column once", { + df <- data.frame( + x = 1:3 + ) + + err <- expect_error( + TADA_SaltFreshIndicator(df, location_col = "ML", type_col = "TADA"), + class = "error" + ) + + testthat::expect_match(err$message, "TADA_SaltFreshIndicator: missing required column\\(s\\):") + testthat::expect_match(err$message, "TADA\\.MonitoringLocationIdentifier") + testthat::expect_match(err$message, "TADA\\.MonitoringLocationTypeName") +}) From cb87442fba854b5d6c0a2703ec7007dbb02890ce Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:15:43 +0000 Subject: [PATCH 3/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- R/ATTAINSCrosswalks.R | 112 ++++++++++++++---------- tests/testthat/test-ATTAINSCrosswalks.R | 19 ++-- 2 files changed, 76 insertions(+), 55 deletions(-) diff --git a/R/ATTAINSCrosswalks.R b/R/ATTAINSCrosswalks.R index 72960f1ce..3f097d166 100644 --- a/R/ATTAINSCrosswalks.R +++ b/R/ATTAINSCrosswalks.R @@ -5121,10 +5121,11 @@ TADA_ReviewATTAINSWaterTypes <- function( #' type_col = "ATTAINS") #' } #' -TADA_SaltFreshIndicator <- function(.data, - location_col = "AU", - type_col = "ATTAINS") { - +TADA_SaltFreshIndicator <- function( + .data, + location_col = "AU", + type_col = "ATTAINS" +) { reqs <- data.frame( col = character(), reason = character(), @@ -5132,31 +5133,43 @@ TADA_SaltFreshIndicator <- function(.data, ) if (location_col == "AU") { - reqs <- rbind(reqs, data.frame( - col = "ATTAINS.AssessmentUnitIdentifier", - reason = "location_col equals 'AU'", - stringsAsFactors = FALSE - )) + reqs <- rbind( + reqs, + data.frame( + col = "ATTAINS.AssessmentUnitIdentifier", + reason = "location_col equals 'AU'", + stringsAsFactors = FALSE + ) + ) } else { - reqs <- rbind(reqs, data.frame( - col = "TADA.MonitoringLocationIdentifier", - reason = "location_col equals 'ML'", - stringsAsFactors = FALSE - )) + reqs <- rbind( + reqs, + data.frame( + col = "TADA.MonitoringLocationIdentifier", + reason = "location_col equals 'ML'", + stringsAsFactors = FALSE + ) + ) } if (type_col == "ATTAINS") { - reqs <- rbind(reqs, data.frame( - col = "ATTAINS.WaterType", - reason = "type_col equals 'ATTAINS'", - stringsAsFactors = FALSE - )) + reqs <- rbind( + reqs, + data.frame( + col = "ATTAINS.WaterType", + reason = "type_col equals 'ATTAINS'", + stringsAsFactors = FALSE + ) + ) } else { - reqs <- rbind(reqs, data.frame( - col = "TADA.MonitoringLocationTypeName", - reason = "type_col equals 'TADA'", - stringsAsFactors = FALSE - )) + reqs <- rbind( + reqs, + data.frame( + col = "TADA.MonitoringLocationTypeName", + reason = "type_col equals 'TADA'", + stringsAsFactors = FALSE + ) + ) } missing <- unique(reqs$col[!reqs$col %in% names(.data)]) @@ -5168,8 +5181,11 @@ TADA_SaltFreshIndicator <- function(.data, msg <- paste0( "TADA_SaltFreshIndicator: missing required column(s):\n", paste0( - " - ", missing_info$col, - " (needed because ", missing_info$reason, ")", + " - ", + missing_info$col, + " (needed because ", + missing_info$reason, + ")", collapse = "\n" ) ) @@ -5185,21 +5201,16 @@ TADA_SaltFreshIndicator <- function(.data, dplyr::distinct() # Select which crosswalk is needed - if(reqs$col[1] == "ATTAINS.AssessmentUnitIdentifier") { - + if (reqs$col[1] == "ATTAINS.AssessmentUnitIdentifier") { cw.name <- "ATTAINSWaterTypeToSaltFresh.csv" - cw.cols <- c("ATTAINS.WaterType", - "TADA.SaltFreshIndicator") - - } else { - - cw.name <- "WQPMonLocTypeToSaltFresh.csv" + cw.cols <- c("ATTAINS.WaterType", "TADA.SaltFreshIndicator") + } else { + cw.name <- "WQPMonLocTypeToSaltFresh.csv" - # will need to rename "Name" col - cw.cols <- c("TADA.MonitoringLocationTypeName", - "TADA.SaltFreshIndicator") - } + # will need to rename "Name" col + cw.cols <- c("TADA.MonitoringLocationTypeName", "TADA.SaltFreshIndicator") + } # Load crosswalk crosswalk <- utils::read.csv(system.file( @@ -5221,20 +5232,29 @@ TADA_SaltFreshIndicator <- function(.data, dplyr::select(dplyr::all_of(cw.cols)) |> dplyr::mutate(dplyr::across(where(is.character), toupper)) |> dplyr::distinct() |> - dplyr::right_join(unique.pairs, - by = dplyr::join_by(!!rlang::sym(reqs$col[2]))) |> + dplyr::right_join( + unique.pairs, + by = dplyr::join_by(!!rlang::sym(reqs$col[2])) + ) |> dplyr::distinct() # Join crosswalk to .data .data <- .data |> - dplyr::left_join(crosswalk, - by = dplyr::join_by(!!rlang::sym(reqs$col[2]))) + dplyr::left_join(crosswalk, by = dplyr::join_by(!!rlang::sym(reqs$col[2]))) # Remove intermediate objects - rm(unique.pairs, cw.cols, cw.name, - location_col, missing, select.cols, - type_col, crosswalk, reqs) + rm( + unique.pairs, + cw.cols, + cw.name, + location_col, + missing, + select.cols, + type_col, + crosswalk, + reqs + ) # Return data with salt fresh indicator return(.data) - } +} diff --git a/tests/testthat/test-ATTAINSCrosswalks.R b/tests/testthat/test-ATTAINSCrosswalks.R index 3908513dc..ef079ccfc 100644 --- a/tests/testthat/test-ATTAINSCrosswalks.R +++ b/tests/testthat/test-ATTAINSCrosswalks.R @@ -793,10 +793,7 @@ test_that("TADA_CreatePointAUs does not modify existing non-missing, non-blank A # tests for TADA_SaltFreshIndicator testthat::test_that("TADA_SaltFresh Indicator errors when required columns are missing for AU/ATTAINS", { - df <- data.frame( - ATTAINS.WaterType = "Fresh", - stringsAsFactors = FALSE - ) + df <- data.frame(ATTAINS.WaterType = "Fresh", stringsAsFactors = FALSE) testthat::expect_error( TADA_SaltFreshIndicator(df, location_col = "AU", type_col = "ATTAINS"), @@ -840,7 +837,10 @@ testthat::test_that("TADA_SaltFreshIndicator returns data with TADA.SaltFreshInd testthat::test_that("TADA_SaltFreshIndicator returns data with TADA.SaltFreshIndicator for ML/TADA", { df <- data.frame( TADA.MonitoringLocationIdentifier = c("ML1", "ML2"), - TADA.MonitoringLocationTypeName = c("RIVER/STREAM EPHEMERAL", "BEACH PROGRAM SITE-OCEAN"), + TADA.MonitoringLocationTypeName = c( + "RIVER/STREAM EPHEMERAL", + "BEACH PROGRAM SITE-OCEAN" + ), stringsAsFactors = FALSE ) @@ -864,16 +864,17 @@ testthat::test_that("does not duplicate output rows when input has duplicate pai }) testthat::test_that("produces a useful error message listing each missing column once", { - df <- data.frame( - x = 1:3 - ) + df <- data.frame(x = 1:3) err <- expect_error( TADA_SaltFreshIndicator(df, location_col = "ML", type_col = "TADA"), class = "error" ) - testthat::expect_match(err$message, "TADA_SaltFreshIndicator: missing required column\\(s\\):") + testthat::expect_match( + err$message, + "TADA_SaltFreshIndicator: missing required column\\(s\\):" + ) testthat::expect_match(err$message, "TADA\\.MonitoringLocationIdentifier") testthat::expect_match(err$message, "TADA\\.MonitoringLocationTypeName") }) From 2adcc1f330228e7a87a1057f718d17baa8094f21 Mon Sep 17 00:00:00 2001 From: hillarymarler <152432687+hillarymarler@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:16:20 -0400 Subject: [PATCH 4/9] Update TADA_SaltFreshIndicator.Rd --- man/TADA_SaltFreshIndicator.Rd | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/man/TADA_SaltFreshIndicator.Rd b/man/TADA_SaltFreshIndicator.Rd index 7e858cc2e..fe5d141be 100644 --- a/man/TADA_SaltFreshIndicator.Rd +++ b/man/TADA_SaltFreshIndicator.Rd @@ -35,5 +35,28 @@ unit level by either ATTAINS.WaterType or TADA.MonitoringLocationTypeName. \dontrun{ +# Get test data with both freshwater and saltwater results +testdat <- TADA_DataRetrieval(statecode = "OR", + startDate = "2023-06-01", + endDate = "2023-06-15", + characteristicType = "Physical", + ask = FALSE) + +# Assign saltfresh indicator based on TADA.MonitoringLocationTypeName, +# using TADA.MonitoringLocationIdentifier as location grouping + TADA.example <- TADA_SaltFreshIndicator(testdat, + location_col = "ML", + type_col = "TADA") + +# Assign ATTAINS water types to test data +testdat.ATTAINSwattypes <- testdat |> + TADA_CrosswalkATTAINSWaterTypes() + +# Assign saltfresh indicator based on ATTAINS.WaterType, +# using ATTAINS.AssessmentUnitIdentifier as location grouping +ATTAINS.example <- TADA_SaltFreshIndicator(testdat.ATTAINSwattypes, + location_col = "AU", + type_col = "ATTAINS") } + } From 60f32a4107ab0963a3b198406492152ed8ea4e3b Mon Sep 17 00:00:00 2001 From: hillarymarler <152432687+hillarymarler@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:16:40 -0400 Subject: [PATCH 5/9] Update WORDLIST --- inst/WORDLIST | 1 + 1 file changed, 1 insertion(+) diff --git a/inst/WORDLIST b/inst/WORDLIST index 28df55dfd..a2540445e 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -314,6 +314,7 @@ SSN STORET STV SaltFresh +SaltFreshIndicator SampleCollectionEquipmentName SampleCollectionMethod SampleFraction From 590b218d187a4a4b639ba29bbb4f8d76c0e342b4 Mon Sep 17 00:00:00 2001 From: hillarymarler <152432687+hillarymarler@users.noreply.github.com> Date: Tue, 25 Aug 2026 18:28:04 -0400 Subject: [PATCH 6/9] updates from dev --- tests/testthat/test-TADARefTables.R | 3 ++- vignettes/TADAModule3a.Rmd | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/testthat/test-TADARefTables.R b/tests/testthat/test-TADARefTables.R index 38b8884cb..c665e9da4 100644 --- a/tests/testthat/test-TADARefTables.R +++ b/tests/testthat/test-TADARefTables.R @@ -179,7 +179,8 @@ test_that("Is the saved TADACharAliasRef.csv up to date?", { skip_if_offline() ATTAINS.raw <- suppressWarnings(suppressMessages(rExpertQuery::EQ_DomainValues( - "param_name" + "param_name", + api_key = EPATADA:::.setEQKey() ))) ref <- unique(ATTAINS.raw[, "name"]) old <- utils::read.csv( diff --git a/vignettes/TADAModule3a.Rmd b/vignettes/TADAModule3a.Rmd index 3f2f69c7f..c9769117f 100644 --- a/vignettes/TADAModule3a.Rmd +++ b/vignettes/TADAModule3a.Rmd @@ -101,11 +101,11 @@ can also access function help pages from RStudio by entering # Introduction to TADA Module 3 -This [RMarkdown](https://yihui.org/rmarkdown/) document walks -users through how to create WQP and ATTAINS crosswalks that are needed -prior to defining and capturing organization specific water quality -analysis criteria and methodologies. It is the first of several -vignettes that are being developed as part of TADA Module 3. +This [RMarkdown](https://yihui.org/rmarkdown/) document walks users +through how to create WQP and ATTAINS crosswalks that are needed prior +to defining and capturing organization specific water quality analysis +criteria and methodologies. It is the first of several vignettes that +are being developed as part of TADA Module 3. Specifically, this vignette provides an overview of two functions that can assist users with: @@ -190,7 +190,7 @@ the complete list: ```{r ATTAINS-params} # return ATTAINS parameter domain values -TADA_TableExport(rExpertQuery::EQ_DomainValues("param_name")) +TADA_TableExport(rExpertQuery::EQ_DomainValues("param_name", api_key = .setEQKey())) ``` In the next section, we will review which parameters have been listed in @@ -201,7 +201,7 @@ ATTAINS organization id's to use for the function input. ```{r ATTAINS-orgs} # return ATTAINS organization domain values -TADA_TableExport(rExpertQuery::EQ_DomainValues("org_id")) +TADA_TableExport(rExpertQuery::EQ_DomainValues("org_id", api_key = .setEQKey())) ``` # TADA_ParametersForAnalysis() Basics From f8bd069e03b40a3409d8d331c9607e3bd652a536 Mon Sep 17 00:00:00 2001 From: hillarymarler <152432687+hillarymarler@users.noreply.github.com> Date: Wed, 26 Aug 2026 09:43:41 -0400 Subject: [PATCH 7/9] fix many to many relationship bug --- R/ATTAINSCrosswalks.R | 5 ----- inst/extdata/WQPMonLocTypeToSaltFresh.csv | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/R/ATTAINSCrosswalks.R b/R/ATTAINSCrosswalks.R index 3f097d166..d24db944d 100644 --- a/R/ATTAINSCrosswalks.R +++ b/R/ATTAINSCrosswalks.R @@ -5231,11 +5231,6 @@ TADA_SaltFreshIndicator <- function( crosswalk <- crosswalk |> dplyr::select(dplyr::all_of(cw.cols)) |> dplyr::mutate(dplyr::across(where(is.character), toupper)) |> - dplyr::distinct() |> - dplyr::right_join( - unique.pairs, - by = dplyr::join_by(!!rlang::sym(reqs$col[2])) - ) |> dplyr::distinct() # Join crosswalk to .data diff --git a/inst/extdata/WQPMonLocTypeToSaltFresh.csv b/inst/extdata/WQPMonLocTypeToSaltFresh.csv index 5fbdd9fb1..f49b8091e 100644 --- a/inst/extdata/WQPMonLocTypeToSaltFresh.csv +++ b/inst/extdata/WQPMonLocTypeToSaltFresh.csv @@ -34,7 +34,7 @@ Monitoring Location Type(MonitoringLocationTypeName),18,Facility Privately Owned Monitoring Location Type(MonitoringLocationTypeName),16,Facility Public Water Supply (PWS),"A Public Water System is a public water supply for the provision to the public of piped water for human consumption, A Public Water System includes any collection, treatment, storage, and distribution facilities under control of such system, including the operator or administrator of such system, and is used primarily in connection with such system and any collection or pretreatment storage facilities not under such control which are used primarily in -connection with such system.”",NA +connection with such system.”",FRESHWATER Monitoring Location Type(MonitoringLocationTypeName),72,Floodwater Urban,"A flood is an overflow of water that submerges land that is usually dry In the sense of ""urban runoff water"". it may occur due to an accumulation of rainwater on saturated ground in an areal flood.",NA Monitoring Location Type(MonitoringLocationTypeName),73,Floodwater non-Urban,"A flood is an overflow of water that submerges land that is usually dry Flooding may occur as an overflow of water from water bodies, such as a river, lake, or ocean, in which the water overtops or breaks levees, resulting in some of that water escaping its usual boundaries",NA Monitoring Location Type(MonitoringLocationTypeName),19,Gallery,An infiltration gallery is a structure including perforated conduits in gravel to expedite transfer of water to or from a soil.,NA From 0fe2f9799d189ec5879c696774ebbfda98fb4a3f Mon Sep 17 00:00:00 2001 From: hillarymarler <152432687+hillarymarler@users.noreply.github.com> Date: Wed, 26 Aug 2026 11:29:01 -0400 Subject: [PATCH 8/9] add stop if param values are incorrect --- DESCRIPTION | 2 +- R/ATTAINSCrosswalks.R | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 86f1af7f0..925db10a6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -119,4 +119,4 @@ LazyData: true LazyDataCompression: xz Config/Needs/website: rmarkdown BugReports: https://github.com/USEPA/EPATADA/issues -Config/roxygen2/version: 8.0.0 +Config/roxygen2/version: 8.1.0 diff --git a/R/ATTAINSCrosswalks.R b/R/ATTAINSCrosswalks.R index d24db944d..fc4bb314e 100644 --- a/R/ATTAINSCrosswalks.R +++ b/R/ATTAINSCrosswalks.R @@ -5126,6 +5126,15 @@ TADA_SaltFreshIndicator <- function( location_col = "AU", type_col = "ATTAINS" ) { + + if(location_col != "AU" & location_col != "ML") { + stop("TADA_SaltFreshIndicator: location_col must equal 'AU' or 'ML'.") + } + + if(type_col != "ATTAINS" & type_col != "TADA") { + stop("TADA_SaltFreshIndicator: type_col must equal 'ATTAINS' or 'TADA'.") + } + reqs <- data.frame( col = character(), reason = character(), From 197e9d35a4777eb941916689808a906c52d0b38e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2026 15:35:14 +0000 Subject: [PATCH 9/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- R/ATTAINSCrosswalks.R | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/R/ATTAINSCrosswalks.R b/R/ATTAINSCrosswalks.R index fc4bb314e..0bbfec9fa 100644 --- a/R/ATTAINSCrosswalks.R +++ b/R/ATTAINSCrosswalks.R @@ -5126,12 +5126,11 @@ TADA_SaltFreshIndicator <- function( location_col = "AU", type_col = "ATTAINS" ) { - - if(location_col != "AU" & location_col != "ML") { + if (location_col != "AU" & location_col != "ML") { stop("TADA_SaltFreshIndicator: location_col must equal 'AU' or 'ML'.") } - if(type_col != "ATTAINS" & type_col != "TADA") { + if (type_col != "ATTAINS" & type_col != "TADA") { stop("TADA_SaltFreshIndicator: type_col must equal 'ATTAINS' or 'TADA'.") }