Overview

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

Changes to prior code

Homework

  1. Run the code below to make a final graph with hardness, cations, anions.

  2. Look up ‘pivot_wider()’ in Help. Briefly summarize what it does.

This command increases the number of columns and decreases the number of rows.

  1. Look up ‘pivot_longer()’ in Help. Briefly summarize what it does.

This command decreases the number of columns and increases the number of rows.

  1. Go through the “Calculate the calcium noncarbonate hardness” example in the ‘Ch06_Ex06_part05_hardness_calcs’ code chunk. Then, a) calculate the magnesium noncarbonate hardness, b) calculate the alkalinity, c) calculate the TDS.

In-class examples

# This code chunk calculates ion concentrations in mg/L into meq/L and 
#   equivalents as mg/L as CaCO3
# Notes:
#   * Getting the data into R is sometimes the least fun of problem solving.
#   * I modified some code from last week to get this table.
#     -- the molecular_weight and charge are numeric in the table below
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# make a table of molecular weight, charge and concentration
tab_ions <- tibble::tribble(
~Type,   ~hardness, ~Ion, ~Molecular.Weight, ~Charge, ~Conc.mg.L,  
"cation", "hard_TH",   "Ca",        40.1,          2,       80,
"cation", "hard_TH",   "Mg",        24.3,          2,       30,
"cation",  NA,         "Na",        23.0,          1,       72,
"cation",  NA,          "K",        39.1,          1,        6,
"anion",   NA,         "Cl",        35.5,          1,      100,
"anion",   NA,        "SO4",        96.0,          2,      201,
"anion",  "hard_CH", "HCO3",        61.0,          1,      165
  )

# use the janitor package and dplyr::rename to clean names
tab_ions <- tab_ions %>%
  clean_names() %>%         # Cleans names of an object (usually a data.frame)
  rename(molec_wt_mmol = molecular_weight)

# calculate milliequivalents using the formula:
#   Equivalent weight (EW) = Atomic or molecular weight / charge

tab_ions <- tab_ions %>%
  mutate(equiv_wt_mg_meq = round(molec_wt_mmol / charge,
                         digits = 1)) %>%
  relocate(equiv_wt_mg_meq, .before = conc_mg_l)

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

# calculate the equivalents as CaCO3
# mg/L of X as CaCO3 = ( conc of X (mg/L) / EW of X (mg/meq) * 50.0 mg CaCO3/meq )
#    Note: the units of X are in "as mg/L CaCO3"                                    
tab_ions <- tab_ions %>%
  mutate(
    mg_l_as_CaCO3 = conc_mg_l/ equiv_wt_mg_meq * equiv_wt_CaCO3_var
    ) %>%
  mutate(mg_l_as_CaCO3 = round(mg_l_as_CaCO3,
                                     digits = 1
                                     ))
# This code chunk checks the cation and anion balance as as mg/L as CaCO3
#   In water, the sum of the anions = the sum of the cations
# Note: !is.na() means NOT = ! and is.na() checks for an NA value
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# add up all the anions and the cations
sum_ions <- tab_ions %>%
  group_by(type) %>%
  summarise(sum = sum(mg_l_as_CaCO3)) %>%
  ungroup()

# calculate total hardness and carbonate hardness
#   Total Hardness = Ca + Mg
#   Carbonate hardness = alkality or in this case the HCO3 conc as CaCO3

sum_hardness <- tab_ions %>%
  group_by(hardness) %>%
  summarise(sum = sum(mg_l_as_CaCO3)) %>%
  ungroup() %>%
  filter(!is.na(hardness)) %>%    # drops all the NA rows      
  rename(type = hardness)         # this is to add things together below

# add the cation sum to hardness long--
# get the cation and anion sums by themselves
sum_cations <- sum_ions %>%
  filter(type == "cation") 

sum_hardness <- bind_rows(sum_hardness, sum_cations) 

# we are going to calculate total hardness and carbonate hardness
 
# pivot the table
sum_hardness_wide <- sum_hardness %>%
  pivot_wider(names_from = type,
              values_from = sum) %>%
  relocate(hard_TH, .before = hard_CH) %>%
  rename(cation_sum = cation)

# calculate total hardness and carbonate hardness
# If the alkalinity exceeds the total hardness, then
#    CH = TH and NCH = 0
# If alkalinity is less than the total hardness
#    CH = alkalinity and NCH = TH — CH

sum_hardness_wide <- sum_hardness_wide %>%
  mutate(hard_NCH = hard_TH - hard_CH) %>%
  relocate(hard_TH, .before  = hard_CH) %>%
  relocate(hard_NCH, .after  = hard_CH)

# calculate the cations not contributing to hardness -- and check calculations
sum_hardness_wide <- sum_hardness_wide %>%
  mutate(other = cation_sum - hard_TH) %>%
  relocate(other, .after  = hard_NCH) %>%
  mutate(cation_check = hard_CH + hard_NCH + other)

# clean up global environment
rm(sum_cations,
   equiv_wt_CaCO3_var)
# This code chunk will make a stacked bar chart for hardness
#   https://r-graph-gallery.com/48-grouped-barplot-with-ggplot2
#   https://www.datanovia.com/en/blog/how-to-create-a-ggplot-horizontal-bar-chart/
# the coord flip() turns the barchart sideways
#  Note this is not the final graph -- just a check on our process

sum_hardness <- sum_hardness_wide %>%
  pivot_longer(cols = c(hard_CH, hard_NCH, other),
    names_to = "ion",
               values_to = "mg_l_as_CaCO3") %>%
  mutate(type = "hardness") %>%    # need to do this to make an x-axis to "stack"
  select(-c(hard_TH, cation_sum, cation_check))

sum_hardness %>%
ggplot(aes(x = type, y = mg_l_as_CaCO3))+
  geom_col(aes(fill = ion), width = 0.7) +
  coord_flip()

Code added after class

# This code chunk will make a stacked bar chart for hardness, cations, anions
#  Note this is not the final graph -- just a check on our process
#  Next step is to change the plotting order of the items

# make a tibble of ions to add to the summary hardness 
tab_ions_hard <- tab_ions %>%
  select(type, ion, mg_l_as_CaCO3)

tab_ions_hard <- bind_rows(sum_hardness, tab_ions_hard)

# clean up global environment
rm(list = ls(pattern = "wide"))

# check results
tab_ions_hard %>%
ggplot(aes(x = type, y = mg_l_as_CaCO3))+
  geom_col(aes(fill = ion), width = 0.7) +
  coord_flip()

# this code chunk plots a graph in the order shown in Fig. 9 on page 308.

# use fct_relevel to order the ions for graphing -- 
#   Note the fct_relevel feels like it is in the opposite order.
tab_ions_hard <- tab_ions_hard %>%
mutate(ion = fct_relevel(ion,
                         "Cl",
                         "SO4",
                         "HCO3",
                         "K",
                         "Na",
                         "Mg",
                         "Ca",
                         "other",
                         "hard_NCH",
                         "hard_CH"
                         ))

# check progress -- plot the ordered table of ions
tab_ions_hard %>%
ggplot(aes(x = type, y = mg_l_as_CaCO3))+
  geom_col(aes(fill = ion), width = 0.7) +
  coord_flip()

# make a final plot
tab_ions_hard %>%
ggplot(aes(x = type, y = mg_l_as_CaCO3))+
  geom_col(aes(fill = ion), width = 0.7) +
  coord_flip() +
  ggtitle("Ionic constituents of an example water") +
  labs(x = "",           # drops the 'type' from the graph - originally x-axis
       y = "mg/L as CaCO3") +      
  theme_classic() +
   guides(fill = guide_legend(reverse = TRUE))

# Prepare for hardness calculations
hard_calcs <- tab_ions_hard %>%
  filter(type == "hardness" |
         type == "cation"   
           ) %>%
  select(-type) %>%     # want to get the data on the same row after pivoting
  filter(ion == "hard_CH"  |
         ion == "hard_NCH" |
           ion == "Ca"     |
           ion == "Mg"
           ) %>%
  pivot_wider(names_from = ion,
              values_from = mg_l_as_CaCO3)

# Calculate the calcium noncarbonate hardness

hard_calcs <- hard_calcs %>%
  mutate(Ca_CH = hard_CH) %>%
  mutate(Ca_NCH = Ca - Ca_CH) %>%


# Calculate the magnesium noncarbonate hardness
# note you should subtract off the Ca-NCH to get the leftover NCH
  mutate(Mg_NCH = (Ca + Mg) - hard_CH - Ca_NCH) %>%
  

# Calculate the alkalinity
  mutate(HCO3 = Ca_CH)

# Calculate the TDS
# note -- might want to use tab_ions

sum(tab_ions$conc_mg_l)
## [1] 654