krwqcprotocol.Rmd
library(KRWQCprotocol)
#> Loading required package: dplyr
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
#> Loading required package: tidyr
#> Loading required package: lubridate
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
#> Loading required package: ggplot2
#> Loading required package: gridExtra
#>
#> Attaching package: 'gridExtra'
#> The following object is masked from 'package:dplyr':
#>
#> combine
#> Loading required package: stringr
Deze handleiding beschrijft de validatie werkwijze volgens het QC protocol (REF RIVM/PMB) voor zowel de grondwaterdata uit het Landelijk Meetnet Grondwaterkwaliteit (LMG) als uit de Provinciale/KRW Monitoringprogramma’s (PMG/KMG). Met dit protocol wordt de dataverwerking en validatie geharmoniseerd en vastgesteld waardoor de datakwaliteit verbeterd. In dit kader is een R-pakket opgesteld om zoveel mogelijk te automatiseren. De hieruit voortkomende betrouwbare dataset is uiteindelijk van belang voor de vastlegging in de Basis Registratie Ondergrond (BRO).
Het protocol voor datakwaliteitscontrole (QC) beschrijft de werkwijze om grondwaterkwaliteitsgegevens te controleren en beoordelen. Dit protocol wordt door provincies en het RIVM gebruikt als bronhouders van de landelijke en provinciale grondwaterkwaliteitsdata. De bestaande werkwijze voor controle en beoordeling staat beschreven in het Handboek Monitoring Grondwaterkwaliteit KRW (2013)
.
Deze werkwijze is ontwikkeld door het RIVM en vanaf de inrichting van het LMG gebruikt voor de kwaliteitscontrole. De kwaliteitscontrole (QC)-onderdelen in deze bestaande werkwijze zijn uitgebreid en in een aantal gevallen verder gespecifieerd. De verschillende QC-onderdelen in deze vernieuwde versie van het protocol zijn opgesteld volgens de structuur van het Protocol voor datakwaliteitscontrole:
kwaliteitsborging grondwaterstands- en stijghoogtegegevens
. Bij het opstellen van de nieuwe QC-onderdelen is samengewerkt tussen het RIVM en de provincies.
In het QC protocol worden controles uitgevoerd m.b.t. parameters, meettechnieken, observaties en meetwaardes uit zowel het veld als uit het lab. Door de veelvoud aan controles is het complex om de vele gegevens in één bestand te vatten. Om deze reden is gekozen om de datastromen in 5 datasets op te knippen zodat het automatiseren van de controles eenvoudiger wordt. Alle records en kolomnamen zijn in lowercase. De datasets zijn als volgt:
Tabel 1 veldbestand (d_veld
) bestaat uit:
kolomnaam | inhoud | type |
---|---|---|
qcid | rijnummer | numeriek |
putcode | identificatie putlocatie volgens RGD/BRO? | karakter |
filter | filternummer | numeriek |
jaar | jaar van veldbezoek | numeriek |
maand | maand van veldbezoek | numeriek |
dag | dag van veldbezoek | numeriek |
xcoord | x-coördinaat gemeten in het veld, in meters volgens RD | numeriek |
ycoord | y-coördinaat gemeten in het veld, in meters volgens RD | numeriek |
landgebruik | veldobservatie van dominant landgebruik putomgeving, volgens BRO | karakter |
okf | diepte onderkant filter t.o.v. maaiveld, in meters | numeriek |
gws_voor | gemeten grondwaterstand voor bepomping filter t.o.v. maaiveld, in meters | numeriek |
gws_na | gemeten grondwaterstand na bepomping filter t.o.v. maaiveld, in meters | numeriek |
bem_app | gebruikt bemonsteringsapparaat | karakter |
Tabel 2 putbestand (d_put
) bestaat uit:
kolomnaam | inhoud | type |
---|---|---|
qcid | rijnummer | numeriek |
putcode | identificatie putlocatie volgens BRO | karakter |
rgdputnummer | identificatie putlocatie volgens RGD | karakter |
xcoord | x-coördinaat zoals opgegeven in BRO, in meters volgens RD | numeriek |
ycoord | y-coördinaat zoals opgegeven in BRO, in meters volgens RD | numeriek |
landgebruik | (historisch) bepaald dominant landgebruik putomgeving | karakter |
maaiveld | maaiveldhoogte bij de put, in meters NAP | numeriek |
provincie | provincie aanduiding of code van beheerder | karakter |
Tabel 3 filterbestand (d_filter
) bestaat uit:
kolomnaam | inhoud | type |
---|---|---|
qcid | rijnummer | numeriek |
putcode | identificatie putlocatie volgens BRO | karakter |
filter | filternummer | numeriek |
bro_id | identificatie putfilter zoals opgenomen in BRO | karakter |
diepte_onder | diepte onderkant filter t.o.v. maaiveld in meters | numeriek |
diepte_boven | diepte bovenkant filter t.o.v. maaiveld in meters | numeriek |
watertype | geeft aan of het grondwater zoet (<300 mg/l Cl) of brak/zout is (>= 300 mg/l Cl) | |
redoxklasse | geeft aan welke redoxcondities in het putfilter gelden | karakter |
Tabel 4 parameterbestand (d_parameter
) bestaat uit:
kolomnaam | inhoud | type |
---|---|---|
qcid | rijnummer | numeriek |
parameter | stofnaam | karakter |
aquocode | aquocode van de betreffende stof | karakter |
cas | CAS-nummer van de betreffende stof | karakter |
eenheid | eenheid van de betroffende stof | karakter |
hoedanigheid | hoedanigheid waarin een stof is uitgedrukt | karakter |
omschrijving | volledig uitgeschreven stofnaam. Kan overeenkomen met kolom naam | karakter |
bem_apparaat | bemonsteringsapparaat waarmee een stof volgens de BRO dient te worden bemonsterd | karakter |
bem_procedure | bemonsteringsprocedure procedure gehanteerd bij uitvoering grondwaterbemonstering | karakter |
waarde_techniek | waardebepalingstechniek laboratoriumtechniek gebruikt bij bepaling chemische parameter | karakter |
waarde_procedure | waardebepalingsprocedure voorschriften uitvoering laboratoriumonderzoek | karakter |
Tabel 5 metingenbestand (d_metingen
) bestaat uit:
kolomnaam | inhoud | type |
---|---|---|
qcid | rijnummer | numeriek |
monsterID | unieke identificatiecode voor het genomen grondwatermonster | numeriek |
jaar | jaar van laboratorium of veldanalyse | numeriek |
maand | maand van laboratorium of veldanalyse | numeriek |
dag | dag van laboratorium of veldanalyse | numeriek |
putcode | identificatie putlocatie volgens BRO | karakter |
filter | filternummer | numeriek |
parameter | naam van de gemeten parameter | karakter |
detectieteken | geeft aan of een waarde onder de rapportagegrens ligt (<) of erboven | karakter |
rapportagegrens | geeft de waarde van de rapportagegrens voor de betreffende paramter en monster | numeriek |
waarde | de gemeten waarde, waarbij alle waardes positief dienen te zijn | numeriek |
Dit pakket maakt gebruik van test data van het LMG die op bepaalde punten is aangepast om het gedrag van verschillende functies te controleren. Voorbeeld bestanden inladen:
Overzicht tabel 1 met veldgegevens
str(veld)
#> tibble [2,025 × 14] (S3: tbl_df/tbl/data.frame)
#> $ qcid : int [1:2025] 1 2 3 4 5 6 7 8 9 10 ...
#> $ putcode : num [1:2025] 1 1 1 1 1 1 1 2 2 2 ...
#> $ filter : num [1:2025] 1 1 1 1 1 3 3 1 1 1 ...
#> $ jaar : num [1:2025] 2014 2015 2017 2018 2019 ...
#> $ maand : num [1:2025] 3 5 5 4 4 3 5 4 6 8 ...
#> $ dag : num [1:2025] 31 4 2 10 15 31 2 9 3 30 ...
#> $ xcoord : num [1:2025] 211635 211635 211635 211635 211635 ...
#> $ ycoord : num [1:2025] 467710 467710 467710 467710 467710 ...
#> $ landgebruik: chr [1:2025] "bos, natuur en water" "bos, natuur en water" "bos, natuur en water" "bos, natuur en water" ...
#> $ okf : num [1:2025] 10.6 10.6 10.6 10.6 10.6 25 25 10 10 10 ...
#> $ gws_voor : num [1:2025] 1.73 1.3 0.84 1.81 0.8 1.47 1.5 1.68 0.86 1.05 ...
#> $ gws_na : num [1:2025] 2 0.9 1.97 0.8 1.8 1.9 1.06 1.26 0.82 1.31 ...
#> $ bem_proc : chr [1:2025] "NEN9644" "SIKBProtocol2002vanafV4" "NEN1176" "NEN1176" ...
#> $ bem_app : chr [1:2025] "peristaltischePomp" "" "slurf" "onderwaterpomp" ...
#> - attr(*, "problems")= tibble [595 × 5] (S3: tbl_df/tbl/data.frame)
#> ..$ row : int [1:595] 1289 1290 1292 1397 1398 1408 1409 1427 1427 1427 ...
#> ..$ col : chr [1:595] "DETECTIETEKEN_CA" "DETECTIETEKEN_CA" "DETECTIETEKEN_CA" "DETECTIETEKEN_BA" ...
#> ..$ expected: chr [1:595] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
#> ..$ actual : chr [1:595] "<" "<" "<" "<" ...
#> ..$ file : chr [1:595] "'./brondata//LMG_2014ev.csv'" "'./brondata//LMG_2014ev.csv'" "'./brondata//LMG_2014ev.csv'" "'./brondata//LMG_2014ev.csv'" ...
head(veld)
#> # A tibble: 6 × 14
#> qcid putcode filter jaar maand dag xcoord ycoord landgebruik okf
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
#> 1 1 1 1 2014 3 31 211635 467710 bos, natuur en wat… 10.6
#> 2 2 1 1 2015 5 4 211635 467710 bos, natuur en wat… 10.6
#> 3 3 1 1 2017 5 2 211635 467710 bos, natuur en wat… 10.6
#> 4 4 1 1 2018 4 10 211635 467710 bos, natuur en wat… 10.6
#> 5 5 1 1 2019 4 15 211635 467710 bos, natuur en wat… 10.6
#> 6 6 1 3 2014 3 31 211635 467710 bos, natuur en wat… 25
#> # … with 4 more variables: gws_voor <dbl>, gws_na <dbl>, bem_proc <chr>,
#> # bem_app <chr>
Overzicht tabel 2 met put informatie
str(put)
#> tibble [340 × 8] (S3: tbl_df/tbl/data.frame)
#> $ qcid : int [1:340] 1 2 3 4 5 6 7 8 9 10 ...
#> $ putcode : num [1:340] 1 2 3 4 5 6 7 8 9 10 ...
#> $ rgdputnummer: num [1:340] 108 109 91 196 258 69 70 71 200 74 ...
#> $ xcoord : num [1:340] 211635 216255 223125 211975 218750 ...
#> $ ycoord : num [1:340] 467710 470435 470025 461935 449190 ...
#> $ landgebruik : chr [1:340] "bos, natuur en water" "grasland" "bos, natuur en water" "grasland" ...
#> $ maaiveld : num [1:340] 8 9 12 8 15 7 13 17 20 18 ...
#> $ provincie : chr [1:340] "GLD" "GLD" "GLD" "GLD" ...
#> - attr(*, "problems")= tibble [595 × 5] (S3: tbl_df/tbl/data.frame)
#> ..$ row : int [1:595] 1289 1290 1292 1397 1398 1408 1409 1427 1427 1427 ...
#> ..$ col : chr [1:595] "DETECTIETEKEN_CA" "DETECTIETEKEN_CA" "DETECTIETEKEN_CA" "DETECTIETEKEN_BA" ...
#> ..$ expected: chr [1:595] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
#> ..$ actual : chr [1:595] "<" "<" "<" "<" ...
#> ..$ file : chr [1:595] "'./brondata//LMG_2014ev.csv'" "'./brondata//LMG_2014ev.csv'" "'./brondata//LMG_2014ev.csv'" "'./brondata//LMG_2014ev.csv'" ...
head(put)
#> # A tibble: 6 × 8
#> qcid putcode rgdputnummer xcoord ycoord landgebruik maaiveld provincie
#> <int> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <chr>
#> 1 1 1 108 211635 467710 bos, natuur en wa… 8 GLD
#> 2 2 2 109 216255 470435 grasland 9 GLD
#> 3 3 3 91 223125 470025 bos, natuur en wa… 12 GLD
#> 4 4 4 196 211975 461935 grasland 8 GLD
#> 5 5 5 258 218750 449190 akkerbouw 15 GLD
#> 6 6 6 69 222795 450795 bos, natuur en wa… 7 GLD
Overzicht tabel 3 met putfilter informatie
str(filter)
#> tibble [345 × 8] (S3: tbl_df/tbl/data.frame)
#> $ qcid : int [1:345] 1 2 3 4 5 6 7 8 9 10 ...
#> $ putcode : num [1:345] 1 2 3 4 5 6 7 8 9 10 ...
#> $ filter : num [1:345] 1 1 1 1 1 1 1 1 1 1 ...
#> $ bro_id : chr [1:345] "108-1" "109-1" "91-1" "196-1" ...
#> $ diepte_onder: num [1:345] 10.6 10 9.85 9.55 9.9 ...
#> $ diepte_boven: num [1:345] 8.6 8 7.85 7.55 7.9 7.95 8 9.9 8.45 7.95 ...
#> $ watertype : chr [1:345] "zoet" "zoet" "zoet" "zoet" ...
#> $ redoxklasse : chr [1:345] "ferm" "fean" "fean" "ferm" ...
#> - attr(*, "problems")= tibble [595 × 5] (S3: tbl_df/tbl/data.frame)
#> ..$ row : int [1:595] 1289 1290 1292 1397 1398 1408 1409 1427 1427 1427 ...
#> ..$ col : chr [1:595] "DETECTIETEKEN_CA" "DETECTIETEKEN_CA" "DETECTIETEKEN_CA" "DETECTIETEKEN_BA" ...
#> ..$ expected: chr [1:595] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
#> ..$ actual : chr [1:595] "<" "<" "<" "<" ...
#> ..$ file : chr [1:595] "'./brondata//LMG_2014ev.csv'" "'./brondata//LMG_2014ev.csv'" "'./brondata//LMG_2014ev.csv'" "'./brondata//LMG_2014ev.csv'" ...
head(filter)
#> # A tibble: 6 × 8
#> qcid putcode filter bro_id diepte_onder diepte_boven watertype redoxklasse
#> <int> <dbl> <dbl> <chr> <dbl> <dbl> <chr> <chr>
#> 1 1 1 1 108-1 10.6 8.6 zoet ferm
#> 2 2 2 1 109-1 10 8 zoet fean
#> 3 3 3 1 91-1 9.85 7.85 zoet fean
#> 4 4 4 1 196-1 9.55 7.55 zoet ferm
#> 5 5 5 1 258-1 9.9 7.9 zoet so4r
#> 6 6 6 1 69-1 9.95 7.95 zoet ferm
Overzicht tabel 4 met parameter informatie
str(parameter)
#> tibble [61 × 10] (S3: tbl_df/tbl/data.frame)
#> $ qcid : int [1:61] 1 2 3 4 5 6 7 8 9 10 ...
#> $ parameter : chr [1:61] "Al" "As" "Ba" "Ca" ...
#> $ omschrijving : chr [1:61] "aluminium" "arseen" "barium" "calcium" ...
#> $ aquocode : chr [1:61] "Al" "As" "Ba" "Ca" ...
#> $ cas : chr [1:61] "7429-90-5" "7440-38-2" "7440-39-3" "7440-70-2" ...
#> $ eenheid : chr [1:61] "ug/l" "ug/l" "ug/l" "mg/l" ...
#> $ bem_apparaat : chr [1:61] "Harolina" "visisonor" "Baliset" "Holophonor" ...
#> $ bem_procedure : chr [1:61] "NEN 4976" "NEN 1534" "NEN 5330" "NEN 4029" ...
#> $ waarde_techniek : chr [1:61] "" "GC-ECD" "MICCOUL" "GC-MS-PT" ...
#> $ waarde_procedure: chr [1:61] "N6964+C1.06" "P6266.91" "I12846.12" "D38407-30.07" ...
head(parameter)
#> # A tibble: 6 × 10
#> qcid parameter omschrijving aquocode cas eenheid bem_apparaat bem_procedure
#> <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 1 Al aluminium Al 7429… ug/l Harolina NEN 4976
#> 2 2 As arseen As 7440… ug/l visisonor NEN 1534
#> 3 3 Ba barium Ba 7440… ug/l Baliset NEN 5330
#> 4 4 Ca calcium Ca 7440… mg/l Holophonor NEN 4029
#> 5 5 Cd cadmium Cd 7440… ug/l Harolina NEN 1419
#> 6 6 Cl chloride Cl 1688… mg/l Holophonor NEN 1605
#> # … with 2 more variables: waarde_techniek <chr>, waarde_procedure <chr>
Overzicht tabel 5 met meetwaardes
str(metingen)
#> tibble [126,880 × 11] (S3: tbl_df/tbl/data.frame)
#> $ qcid : int [1:126880] 1 2 3 4 5 6 7 8 9 10 ...
#> $ monsterid : int [1:126880] 1 1 1 1 1 1 1 1 1 1 ...
#> $ jaar : num [1:126880] 2014 2014 2014 2014 2014 ...
#> $ maand : num [1:126880] 3 3 3 3 3 3 3 3 3 3 ...
#> $ dag : num [1:126880] 31 31 31 31 31 31 31 31 31 31 ...
#> $ filter : num [1:126880] 1 1 1 1 1 1 1 1 1 1 ...
#> $ putcode : num [1:126880] 1 1 1 1 1 1 1 1 1 1 ...
#> $ detectieteken : chr [1:126880] "" "" "" "" ...
#> $ rapportagegrens: num [1:126880] NA NA NA NA 0.05 NA NA NA 0.5 NA ...
#> $ waarde : num [1:126880] 10 0.6 39 97.65 0.05 ...
#> $ parameter : chr [1:126880] "Al" "As" "Ba" "Ca" ...
head(metingen)
#> # A tibble: 6 × 11
#> qcid monsterid jaar maand dag filter putcode detectieteken rapportagegrens
#> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
#> 1 1 1 2014 3 31 1 1 "" NA
#> 2 2 1 2014 3 31 1 1 "" NA
#> 3 3 1 2014 3 31 1 1 "" NA
#> 4 4 1 2014 3 31 1 1 "" NA
#> 5 5 1 2014 3 31 1 1 "<" 0.05
#> 6 6 1 2014 3 31 1 1 "" NA
#> # … with 2 more variables: waarde <dbl>, parameter <chr>
Het KRWQCprotocol wordt beschikbaar gesteld als R pakket. Gebruikers kunnen de functies uit dit pakket gebruiken in hun eigen scripts. Om het pakket te installeren moet vanuit R het volgende commando uitgevoerd worden:
remotes::install_github("jspijker/KRWQCprotocol")
De verschillende QC stappen uit het Protocol kunnen eenvoudig uitgevoerd worden door het aanroepen van de relevante functie (QC0a-QC5). Als invoer van de functie worden de relevante datatabellen meegegeven benodigd voor de testen. In de functie kan met het verbose argument opgegeven worden of de print van tussentijdse output gewenst is door deze op TRUE
te zetten. In een aantal gevallen dienen extra invoervariabelen opgegeven te worden. Zie hiervoor de documentatie bij de functies, bijvoorbeeld ?KRWQCprotocol::QC0a
.
In de verschillende QC functies worden de testen uitgevoerd beschreven in het QC Protocol. Als bij deze stappen een afwijking geconstateerd wordt dan krijgt het monster, de parameter of de waarde een concept oordeel toegekend. Deze afwijkingen worden aan het eind van de functie als attribuut meegegeven aan het metingen bestand (d_metingen
) en kunnen dus na het runnen van elke test bekeken worden.
BELANGRIJK: alle resultaten en concept oordelen worden per QC-test als attribuut aan het metingenbestand gehangen. Het is daarom noodzakelijk om voor elke test hetzelfde bestand als invoer te gebruiken, zodat alle test resultaten uiteindelijk als attribuut beschikbaar zijn onder eenzelfde bestand.
Hieronder zullen de QC stappen 0-5 kort doorlopen worden om te laten zien hoe de functies toegepast worden en of aanvullende acties benodigd zijn.
Bij een viertal QC stappen moet de validatie door de grondwaterbeheerder zelf worden uitgevoerd. Het gaat om de stappen QC0c, QC0d, QC2b en QC2c. Om deze stappen in het R-pakket op te kunnen nemen moet voor deze functies eerst een invoerbestand gegenereerd worden met QC0c_create_file
, idem voor de overige 3 functies. Na het invullen van deze bestanden dient het bestand onder dezelfde naam opgeslagen te worden zodat deze meegenomen kan worden in de functies QC0c, QC0d, QC2b en QC2c uit dit pakket. De resultaten worden net als bij de andere functies vervolgens als attribute toegekend aan het metingen bestand.
De stappen en functies onder QC0 worden op reguliere wijze uitgevoerd door het aanroepen van de betreffende functie en benodigde datasets, met uitzondering van QC0c en QC0d zie bovenstaande.
Voorbeeld voor uitvoeren van QC0a:
x <- metingen
x <- QC0a(d_veld = veld, d_put = put, d_metingen = x, verbose = TRUE)
#> "Er zijn in totaal 10 bemonsterde putlocaties met XY-coordinaten afwijkend van de BRO geregistreerde putcoordinaten."
#> putcode X_val Y_val X_BRO Y_BRO
#> 1 21 226390 567500 226350 567500
#> 2 28 212490 546675 212450 546675
#> 3 78 68760 417805 68720 417805
#> 4 93 85200 446927 85200 446970
#> 5 94 133875 407482 133875 407525
#> 6 183 164930 585020 164890 585020
#> 7 183 164890 584977 164890 585020
#> 8 206 233340 500225 233300 500225
#> 9 272 193288 435470 193288 435513
#> 10 283 125350 521257 125350 521300
In het voorbeeld veld data van het LMG zit als test het landgebruik heide. Dit zorgt voor een error in QC0b:
try(
x <- QC0b(d_veld = veld, d_put = put, d_metingen = x, verbose = TRUE)
)
#> Error in QC0b(d_veld = veld, d_put = put, d_metingen = x, verbose = TRUE) :
#> Landgebruiksklasse worden niet herkend, zie valideLandgebruiken()
Heide is niet opgenomen in de valide landgebruiken en kan daardoor niet worden meegenomen in test QC0b. Voorbeeld voor uitvoeren van QC0b:
veld <- veld %>% dplyr::filter(landgebruik != "heide")
x <- QC0b(d_veld = veld, d_put = put, d_metingen = x, verbose = TRUE)
#> [1] "Voor elke putfilter is het landgebruik identiek aan de BRO geregistreerde informatie"
Voorbeeld voor uitvoeren van QC0c:
QC0c_create_file("created_files") # -> handmatig invullen en met dezelfde naam opslaan
x <- QC0c(dir = "created_files", d_metingen = x, verbose = TRUE)
In QC1a wordt de informatie uit de parameter tabel (d_parameter) vergeleken met informatie uit de BRO. Binnen het pakket is de meest recente versie van deze BRO parameterlijst opgenomen en deze wordt binnen de functie aangeroepen. In QC1b worden de bemonsteringsapparatuur en -procedure en de analysetechniek en -procedure getoetst aan de gegevens uit de BRO. Indien het vermoeden bestaat dat de BRO gegevens in dit pakket achterhaald zijn wordt verzocht een issue aan te maken op de Github pagina van dit QC pakket zodat de meest actuele gegevens beschikbaar kunnen worden gesteld.
QC1d (controle conformiteit BRO format) uit het Protocol wordt niet in dit R-pakket als afzonderlijke functie getoetst. In iedere functie wordt namelijk al getest of de benodigde datakolommen aanwezig zijn.
De andere testen uit QC1 worden op reguliere wijze uitgevoerd, zie voorbeeld van QC0a.
De stappen en functies onder QC2 worden op reguliere wijze uitgevoerd door het aanroepen van de betreffende functie en benodigde datasets, met uitzondering van QC2b en QC2c, zie eerder.
In QC3b wordt getoetst of de putten in de BRO puttenlijst voorkomen. De bedoeling is om d.m.v. een API de puttenlijst uit de BRO automatisch in te laden. Door technische problemen is dit momenteel nog niet mogelijk. Hierdoor is voor QC3b nu een tijdelijke functie opgenomen. Bij deze functie is het op het moment noodzakelijk om handmatig de putten uit het metingen bestand te selecteren welke niet in de BRO voorkomen en de subselectie uit het metingen bestand in te voeren in de functie.
In QC3c wordt de ionenbalans opgesteld. Het is hierdoor belangrijk om de benodigde parameters de juiste naam te geven. In alle QC’s wordt er van uitgegaan dat lab parameters genoteerd zijn als aquoqode (zoals in het parameter bestand beschreven). Daarnaast wordt van het volgende uitgegaan:
In het geval dat de hco3 in het lab is bepaald (zoals in de provinciale set), wordt de lab waarde gebruikt. Dit betekent dat ook pH uit het lab gebruikt moet worden. De standaard waardes voor ph_naam en hco3_naam worden dan gebruikt.
In het geval de hco3 in het veld is bepaald (zoals in de LMG set), worden veld waardes gebruikt. In dit geval moet de ph_naam en hco3_naam wel worden gespecificeerd.
Met het voorbeeld metingen bestand uit het LMG wordt QC3c op de volgende manier uitgevoerd:
x <- QC3c(d_metingen = x, ph_naam = "h_5__veld", hco3_naam = "hco3_veld", verbose = TRUE)
In QC3d worden de ec lab en ec veld vergeleken. Benodigde parameternamen zijn “GELDHD” en geleidendheid_veld_naam
. In alle QC’s wordt er van uitgegaan dat lab parameters genoteerd zijn als aquoqode (zoals in parameter bestand) dus in dit geval “GELDHD”.
x <- QC3d(d_metingen = x, d_parameter = parameter, geleidendheid_veld_naam = "ec_5__veld", verbose = TRUE)
In QC3e wordt de ec berekend aan de hand van de gemeten concentraties. De berekende EC wordt vergeleken met de gemeten EC. Met functie argument add_phosphate
kan aangegeven worden of het gewenst is dat PO4 uit ptot wordt berekend indien po4 niet bekend is. Binnen deze functie wordt de ionenbalans opnieuw opgesteld zodat HCO3 geschat kan worden als deze ontbreekt met add_bicarbonate
. Vervolgens wordt aan de hand van bepaalde condities bepaald welke methode gebruikt wordt om de EC te berekenen om deze uiteindelijk toe te passen. Net zoals bij QC3c hoeven de variabelen ph_naam, hco3_naam en ec_naam alleen te worden gespecificeerd als niet de standaard lab waardes (in aquocodes) worden gebruikt.
In QC3f wordt de pH lab met pH veld vergeleken. Benodigde parameternamen zijn “pH” en ph_veld_naam
. In alle QC’s wordt er van uitgegaan dat lab parameters genoteerd zijn als aquoqode (zoals in parameter bestand) dus in dit geval “pH”.
In QC3g wordt de pH met hco3 vergeleken. Aangezien in de meeste gevallen hco3 niet in het veld is bepaald voor de provinciale gegevens, worden nu de lab metingen van beiden vergeleken. Benodigde parameternamen zijn “pH” en “HCO3”.
In QC3h wordt no3 met nh4 vergeleken. Benodigde parameternamen zijn “NO3” en “NH4”.
In QC4a worden de metingen uit de te valideren meetronde gecontroleerd of deze consistent zijn met de historische meetreeks. Metingen welke >3.5 sd afwijken worden als afwijkend en twijfelachtig bestempeld. Wanneer een reeks minder dan 3 metingen heeft is de test niet uitvoerbaar. Vervolgens worden op 2 manieren figuren gegenereerd en weggeschreven als attribute aan het metingen bestand om de validatie te kunnen uitvoeren:
Voorbeeld voor het maken van een pdf met de afbeeldingen van de parameters:
x <- QC4a(d_metingen = x, d_parameter = parameter)
x_attr <- attr(x, "qcout")
ggsave(
filename = paste0(getwd(), "/parameters_", Sys.Date(),".pdf"),
plot = gridExtra::marrangeGrob(x_attr$QC4a$resultaat$plot_param, nrow = 1, ncol = 1),
width = 15, height = 9
)
QC4b wordt regulier uitgevoerd met het aanroepen van QC4b() met metingen data uit het LMG als voorbeeld. Bij deze stap word getest of de pH van het veld en de pH van het lab niet buiten het meetbereik liggen. De benodigde naam voor pH lab is “pH”. De benodigde naam voor pH veld staat standaard op “pH_veld”, maar kan worden aangepast door een character string in te vullen voor ph_veld_naam. In het geval van het voorbeeld metingen data uit het LMG wordt QC4b op de volgende manier uitgevoerd:
x <- QC4b(d_metingen = x, ph_veld_naam = "h_5__veld", verbose = TRUE)
In de functie voor QC5 worden de attributes met resultaten van de verschillende tests uit het metingen bestand gehaald en bij elkaar gevoegd als één dataframe met collect_result()
. Het is hierbij belangrijk dat alle minimaal benodigde QC-stappen (QC0a, QC0c t/m QC0e, QC1f, QC2a t/m QC2c, QC3c t/m QC3h“,”QC4a" en “QC4b”) zijn doorlopen en dat voor iedere functie hetzelfde metingen bestand als invoer is gebruikt. In dit geval zijn de resultaten uit de verschillende QC tests als attribute aan één bestand gekoppeld. Met het verkregen dataframe uit collect_result()
wordt vervolgens per meting het eindoordeel bepaald volgens de regels uit het QC Protocol.
De overige qc test zijn benodigd voor het volledig doorlopen van het KRWQC protocol, maar het ontbreken ervan is geen technische belemmering voor het uitvoeren van QC5.