library(tidyverse)
library(here)
library(ggthemes)
library(dplyr)
library(lubridate)
Trinkwasserdaten
Einleitung
Trinkwasserdaten im Kanton Zürich, Export aus dem LIMS einer anonymisierten Wasserversorgung mit zwei Probenahmestellen aus den Jahren 2019-2024
Ziele sind:
Daten aufbereiten
Überschreitungen von 25 mg/l und 40 mg/l Nitrat, E.coli und Enterokokken graphisch darstellen und visuell kenntlich machen (z.B. Plots mit roten Punkten als Überschreitung).
Schnittstelle Datenbanken abklären.
In ein Shiny App implementieren, um einzelne Gemeinden anzuwählen und darzustellen.
Daten (statisch)
## Daten einlesen als semicolon getrennte Daten. Die ersten 5 Zeilen überspringen
<- read_delim(here::here("daten/raw/2019-2024_TEST.csv"), skip = 5) |>
daten_in # clean_names hier nutzen, damit auf "saubere" Variablen in Aufbereitung zugegriffen werden kann
::clean_names()
janitor
## Metadaten extrahieren. Die ersten 2 Zeilen überspringen. Keine Spaltennamen geben.
<- read_delim(here::here("daten/raw/2019-2024_TEST.csv"), skip = 2, col_names = FALSE) |>
dictionary_in # clean_names hier nutzen, damit auf "saubere" Variablen in Aufbereitung zugegriffen werden kann
::clean_names() janitor
Daten Aufbereitung
Notizen
- tags sind nicht vereinheitlichet (probiere: test_wv |> count(tags))
- Unterhalb von detektierbaren Messschwellen wird der Wert “<0.01” zurückgegeben, dadurch wird Spalte zu einer character Spalte. Dieser Werte müssten mit einem numerischen Wert ersetzt werden (e.g. 0) damit Werte grösser 0.01 mg/l korrekt als numerische Werte erkannt werden.
#tags sind nicht relevant für die Auswertung
# Daten säubern
<- daten_in |>
test_wv # Spalte ist hat keine Werte. Am Ende wird auf eine Legende hingewiesen
select(-koordinaten_lv95) |>
slice(-3) |> # Zeile hat keine Werte
mutate(erhebungsdatum= dmy(erhebungsdatum)) |>
# Alle Reihen mit NA für erhebungsdatum sind leer.
filter(!is.na(erhebungsdatum)) |>
# Fügt eine ID Spalte hinzu um Proben zu identifizieren
mutate(id = seq(1:n())) |>
# Bringt die Spalte id an den Anfang des Datensatzes
relocate(id)
# Das Daten Wörterbuch aus den Metadaten in der Datei erstellen
<- dictionary_in |>
dictionary slice(1:4) |> # Nur die ersten 4 Zeilen sind relevant
# Spalte x1 wurd aus Daten entfernt (i.e. koordinaten_lv95)
# Spalte id wurde zu Daten hinzugefügt
# Hier wird Kooridnaten_lv95 zu id umbenannt damit es im Wörterbuch auftaucht
mutate(x1 = case_when(
== "Koordinaten LV95" ~ "Eindeutige ID für jede Probe.",
x1 .default = NA)
|>
) t() |> # Transponieren, macht aus 4 Reihen 4 Spalten. Rückgabe als Matrix/Array.
as_tibble() |> # Aus Matrix / Arrax ein tibble machen (Dataframe)
# Spaltennamen aus test_wv als Variable hinzufügen
# names(test_wv) gibt Spaltennamen zurück.
mutate(variable = names(test_wv)) |> #
select(variable, # Mit select Reihenfolge bestimmen und Spalten benennen
einheit = V2,
methode = V3,
typ = V1,
beschreibung = V4) |>
# Füllt NA Werte in Spalte typ mit dem Wert darüber (überprüfen!)
fill(typ, .direction = "down")
{r}
#test_wv |>
#glimpse()
#test_wv |>
#head()
#test_wv |>
#tail()
Daten Visualisierung und Ergebnisse
Table 1 zeigt eine Übersicht zu den Werten von Nitrat, E.coli und Enterokokken.
|>
test_wv select(nitrat, escherichia_coli, enterokokken) |>
summary(test_wv) |>
::kable() knitr
nitrat | escherichia_coli | enterokokken | |
---|---|---|---|
Min. :12.50 | Min. :0 | Min. :0 | |
1st Qu.:21.75 | 1st Qu.:0 | 1st Qu.:0 | |
Median :24.70 | Median :0 | Median :0 | |
Mean :23.48 | Mean :0 | Mean :0 | |
3rd Qu.:26.05 | 3rd Qu.:0 | 3rd Qu.:0 | |
Max. :40.70 | Max. :0 | Max. :0 | |
NA’s :23 | NA’s :7 | NA’s :7 |
In Figure 1 und Figure 2 sind mögliche Höchstwertüberschreitungen von Fäkalkeimen dargestellt. Zusätzlich sieht man in Figure 3, ob der Nitrat Höchstwert von 40 mg/l überschritten wurde.
ggplot(data = test_wv,
mapping = aes(x = erhebungsdatum,
y = escherichia_coli)) +
geom_point() +
scale_color_manual(values = "blue") +
geom_vline(xintercept = 1, color = "red", linetype = "dashed", linewidth = 1) +
facet_wrap(~probenahmestelle) +
labs(title = "Auswertung Wasserversorgung Test",
subtitle = "E.coli",
caption = "KL",
y = NULL,
x = NULL) +
theme_minimal() +
theme(legend.position = "bottom", panel.grid.major.y = element_blank())
ggplot(data = test_wv,
mapping = aes(x = erhebungsdatum,
y = enterokokken)) +
geom_point() +
scale_color_manual(values = "blue") +
geom_vline(xintercept = 1, color = "red", linetype = "dashed", linewidth = 1) +
facet_wrap(~probenahmestelle) +
labs(title = "Auswertung Wasserversorgung Test",
subtitle = "Enterokokken",
caption = "KL",
y = NULL,
x = NULL) +
theme_minimal() +
theme(legend.position = "bottom", panel.grid.major.y = element_blank())
ggplot(data = test_wv,
mapping = aes(x = erhebungsdatum,
y = nitrat)) +
geom_point() +
scale_color_manual(values = "green") +
geom_vline(xintercept = 40, color = "red", linetype = "dashed", linewidth = 1) +
facet_wrap(~probenahmestelle) +
labs(title = "Auswertung Wasserversorgung Test",
subtitle = "Nitrat",
caption = "KL",
y = NULL,
x = NULL) +
theme_minimal() +
theme(legend.position = "bottom", panel.grid.major.y = element_blank())
Die Diagramme und Tabelle zeigen, dass es zu keiner Höchstwertüberschreitung an Fäkalkeimen zwischen 2019 und 2024 gekommen ist. Der Höchstwert von 40 mgl/l Nitrat wurde an Teststr. im Jahr 2021 überschritten.
Schlussfolgerungen
Es ist möglich mit diesem Vorgehen eine Übersicht über die relevanten Höchstwertüberschreitungen einer Wasserversorgung über einen bestimmten Zeitraum zu gewinnen.
Eine gute Datenaufbereitung ist das schwierigste.
Ausblick
Schnittstelle Datenbanken abklären, um ein Abruf der Daten aus der Datenbank zu ermöglichen.
Datenaufbereitung
In ein Shiny App implementieren, um einzelne Gemeinden anzuwählen und darzustellen.