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

Inleiding

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).

QC Protocol

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.

Samenstelling en beschrijving dataformat voor validatie

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:

  1. Veldbestand: databestand met veldobservaties betreffende locatie en toestand van de put;
  2. Putbestand: databestand met referentie putlocatie gegevens;
  3. Filterbestand: databestand met referentie putfilter gegevens;
  4. Parameterbestand: opzoekbestand voor parameter kenmerken;
  5. Metingenbestand: bestand met gemeten parameters uit monsteranalyses en veldmetingen.

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

Overzicht van de data

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:

data(veld)
data(put)
data(metingen)
data(filter)

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>

Installatie KRWQCprotocol R-pakket

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")

Werking KRWQCprotocol R-pakket

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.

Toepassing functies

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.

QC0 - Meetopstelling

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)

QC1 - Data-integriteit

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.

QC2 - Bemonstering

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.

QC3 - Plausibiliteit

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”.

QC4 - Consistentie

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:

  • Voor elke parameter worden de metingen log-getransformeerd weergegeven waar afijkende metingen uit de te valideren meetronde gekleurd zijn afgebeeld. Hiermee wordt in één opslag duidelijk hoeveel metingen per parameter afwijken en of er eventueel sprake is van eenheidsfouten of structurele afwijkingen in een meetronde.
  • Per twijfelachtige meting wordt de gehele reeks geplot tegelijkertijd met eventuele andere putfilters op die locatie. Zo kunnen mogelijke filterwisselingen geidentificeerd worden.

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)

QC5 - QC Status

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.

oordeel <- QC5(d_metingen = x, verbose = TRUE)
summary(oordeel)