The waters are saved as Excel and csv files.

We will use the readxl package, which is loaded as part of the Tidyverse to

convert Excel files to an R-readable format.

Homework

This file contains a homework template and in-class examples. When you have completed the homework, click Knit to HTML.

Question for Final

  1. When insufficient water supplies caused by insufficient water flows, what are the four most prioritized uses that are considered by the OST?

Answer: Domestic and muncipals uses, stock watering uses, agricultural uses, and In-stream needs for fish, wild-life conservation, and recreational uses.

  1. What are the five vulnerabilities that were identified by the Drought Vulnerability Assessment?

Answer: 1. The general infrastructure is old and outdated. 2. Private well are in high arsenic. 3. Volunteer fire department are far and far between. 4. Tree regeneration is signficantly reduced. 5. There is an increase in invasive plant species.

In-class examples

. The 1. We are going to remake Table 6.3 from the text as a tidy tibble 2. We are going to subset the table join it to our sample data. 3. We are going to use the joined table to calculate hardness and alkalinity in units of meq/L and mg/L as CaCO3. 4. We are going to summarise the joined table to find the hardness.

Example 1. Expressing hardness

A sample of groundwater has 100 mg/L of calcium and 10 mg/L of magnesium.

Use Table 6.3 from the text (it’s recreated in the lecture notes as Table 1) to express the groundwater hardness in units of meq/L and mg/L as \(CaCO_3\). (See Example 4 in the text).

Use Table 6.4 from the text (recreated as Table 2 in the lecture notes) to describe the water as soft to very hard.

# install janitor package----
#install.packages("janitor")  # Simple Tools for Examining and Cleaning Dirty Data

# load packages----
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(janitor)
## 
## Attaching package: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
# remake Table 6.3 from the text as a tidy tibble----
# -- note the original names of the columns
# -- also note that I like to line things up in my code (but it's not necessary)

tab_ions <- tibble::tribble(
   ~Type,     ~Name,              ~Formula, ~Molecular.Weight, ~Charge,
  "multi-cation",  "Aluminum",                "Al",        "27.0",        "3",
  "multi-cation",  "Calcium",                 "Ca",        "40.1",        "2",
    "alk-cation",  "Hydrogen",                 "H",         "1.0",        "1",
  "multi-cation",  "Magnesium",               "Mg",        "24.3",        "2",
        "cation",  "Potassium",                "K",        "39.1",        "1",
        "cation",  "Sodium",                  "Na",        "23.0",        "1",
     "alk-anion",   "Bicarbonate",          "HCO3",        "61.0",        "1",
     "alk-anion",   "Carbonate",             "CO3",        "60.0",        "2",
         "anion",   "Chloride",               "Cl",        "35.5",        "1",
     "alk-anion",   "Hydroxide",               "OH",        "17.0",        "1",
         "anion",   "Nitrite",                "NO2",        "46.0",        "1",
         "anion",   "Nitrate",                "NO3",        "62.0",        "1",
         "anion",   "Orthophosphate",         "PO4",        "95.0",        "3",
         "anion",   "Sulfate",                "SO4",        "96.0",        "2",
       "neutral", "Calcium carbonate",      "CaCO3",       "100.0",        "2",
       "neutral", "Carbon dioxide",           "CO2",        "44.0",        "2",
       "neutral", "Magnesium hydroxide",     "MgOH",        "58.3",        "2"
  )

# use the janitor package and dplyr::rename to clean names
tab_ions <- tab_ions %>%
  clean_names() %>%
  rename(molec_wt_mmol = molecular_weight)

# use mutate to change molecular_weight and charge to numeric----
#   take a look at how molecular_weight and charge are stored:
#     the data are stored as a string -- "chr" stands for character
#     we need to change them to numeric to use them in calculations.

tab_ions <- tab_ions %>%
  mutate(molec_wt_mmol = as.numeric(molec_wt_mmol)) %>%
  mutate(charge = as.numeric(charge)) 

# calculate milliequivalents using the formula in your notes
tab_ions <- tab_ions %>%
  mutate(equiv_wt_mg_meq = round(molec_wt_mmol / charge,
                         digits = 1)
         )

# calculate equivalent weight as CaCO3----
# make a variable to use below
equiv_wt_CaCO3_var <- 50       # mg/meq; note this is a 1x1 vector

# add the equiv_wt_CaCO3_var to the table of ions
tab_ions <- tab_ions %>%
  mutate(equiv_wt_CaCO3_mg_L = equiv_wt_CaCO3_var)

# clean up the environment
rm(equiv_wt_CaCO3_var)
# make a tibble of our sample data----
sample_data <- tribble(
  ~formula, ~conc_mg_L,
    "Ca",     100,
    "Mg",      10
  )

# subset the table of equivalent weights----
tab_ions_sub <- tab_ions %>%
  filter(formula == "Ca" |
         formula == "Mg")

# join the sample data and the subsetted table----
sample_data <- left_join(sample_data, tab_ions_sub,
                         by = "formula")

# move some columns around to make it easier to read----
sample_data <- sample_data %>%
  relocate(type, .before = formula) %>%
  relocate(name, .before = formula)

# calculate the equivalent weight of our samples in units of meq/L
#    use equation 6.29 in the text
sample_data <- sample_data %>%
  mutate(conc_meq_L = round(conc_mg_L / equiv_wt_mg_meq,
                            digits = 2))

# calculate the equivalent weight of our samples in units of meq/L
#    use equation 6.29 in the text
sample_data <- sample_data %>%
  mutate(conc_as_mg_L_CaCO3 = round(
    conc_mg_L * equiv_wt_CaCO3_mg_L / equiv_wt_mg_meq,
    digits = 0))

# clean up the environment
rm(equiv_wt_CaCO3_var)
## Warning in rm(equiv_wt_CaCO3_var): object 'equiv_wt_CaCO3_var' not found
# calculate hardness--
# we can use group_by and summarise to summarise the columns by type
hardness <- sample_data %>%
  group_by(type) %>%
  summarise(hardness_meq_L = sum(conc_meq_L),
            hardness_as_mg_L_CaCO3 = sum(conc_as_mg_L_CaCO3)) %>%
  ungroup()

# print the tibble to screen
hardness
## # A tibble: 1 × 3
##   type         hardness_meq_L hardness_as_mg_L_CaCO3
##   <chr>                 <dbl>                  <dbl>
## 1 multi-cation           5.82                    291

Example 2. Expressing alkalinity

A sample of groundwater has 32.0 mg/L of carbonate and 69.5 mg/L of bicarbonate. The water is pH 10, with a hydroxide concentration of 1.7 mg/L. Find the alkalinity.

Updates

Changed the concentration of carbonate and bicarbonate Updated “alk_anion” to “alk-anion” for one observation

# make a tibble of our sample data----
sample_data <- tribble(
  ~formula, ~conc_mg_L,
    "CO3",      32.0,
    "HCO3",     69.5,
     "OH",       1.7
  )

# subset the table of equivalent weights----
tab_ions_sub <- tab_ions %>%
  filter(formula == "CO3"  |
         formula == "HCO3" |
         formula == "OH"
         )

# join the sample data and the subsetted table----
sample_data <- left_join(sample_data, tab_ions_sub,
                         by = "formula")

# move some columns around to make it easier to read----
sample_data <- sample_data %>%
  relocate(type, .before = formula) %>%
  relocate(name, .before = formula)

# calculate the equivalent weight of our samples in units of meq/L
#    use equation 6.29 in the text
sample_data <- sample_data %>%
  mutate(conc_meq_L = round(conc_mg_L / equiv_wt_mg_meq,
                            digits = 2))

# calculate the equivalent weight of our samples in units of meq/L
#    use equation 6.30 in the text
sample_data <- sample_data %>%
  mutate(conc_as_mg_L_CaCO3 = round(
    conc_mg_L * equiv_wt_CaCO3_mg_L / equiv_wt_mg_meq,
    digits = 0))
# calculate alkalinity--
# we can use group_by and summarise to summarise the columns by type
alkalinity <- sample_data %>%
  group_by(type) %>%
  summarise(alkalinity_meq_L = sum(conc_meq_L),
            alkalinity_as_mg_L_CaCO3 = sum(conc_as_mg_L_CaCO3))

# print the tibble to screen
alkalinity
## # A tibble: 1 × 3
##   type      alkalinity_meq_L alkalinity_as_mg_L_CaCO3
##   <chr>                <dbl>                    <dbl>
## 1 alk-anion             2.31                      115