forked from NINAnor/ecosystemCondition
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctional_plant_indicators_wetland.Rmd
1768 lines (1439 loc) · 97.5 KB
/
functional_plant_indicators_wetland.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Functional Plant Indicators - Wetlands {#Functional-plant-indicators-wetland}
<br />
Norwegian name: **Vegetasjon og fuktighet/lys/pH/nitrogen**
_Author and date:_
Joachim Töpper
May 2023
<br />
<!-- Load all you dependencies here -->
```{r setup, include=FALSE, warning=F, message=F}
library(sf)
library(plyr)
library(tidyverse)
library(RColorBrewer)
library(gridExtra)
library(ggridges)
library(tmap)
library(tmaptools)
library(raster)
library(stars)
library(knitr)
library(kableExtra)
library(betareg)
library(glmmTMB)
knitr::opts_chunk$set(echo = TRUE)
```
<!-- Limit code block height and force scrolling -->
```{css, echo=FALSE}
pre {
max-height: 300px;
overflow-y: auto;
}
pre[class] {
max-height: 200px;
}
```
```{r, echo=FALSE}
Ecosystem <- "våtmark"
Egenskap <- c("Primærproduksjon","Abiotiske forhold")
ECT <- "Functional state characteristic"
Contact <- "Joachim Töpper"
```
```{r, echo=FALSE}
metaData <- data.frame(Ecosystem,
"Økologisk egenskap" = Egenskap,
"ECT class" = ECT)
knitr::kable(metaData)
```
<br />
Indicators described in this chapter:
- Moisture
- Light
- pH
- Nitrogen
<!-- Don't remove these three html lines -->
<br />
<br />
<hr />
## Introduction {#intro-fpiw}
Functional plant indicators can be used to describe the functional signature of plant communities by calculating community-weighted means of functional trait values for plant communities (Diekmann 2003). The functional signature of plant communities may be indicative of ecosystem identity, depending on which functional plant indicator we look at (cf. Töpper et al. 2018). For instance, using an indicator for moisture one would find a functional signature with higher moisture values for plant communities in mires compared to e.g. grasslands or forests. Deviations in the functional signature of such an indicator beyond a certain range of indicator values (as there of course is natural variation of functional signatures within an ecosystem type) may be related to a reduction in ecological condition.
Here, we combine functional indicator data with field sampled plant community data from the Norwegian nature monitoring program ANO (Tingstad et al. 2019) for wetland ecosystems. We calculate the functional signature of plant communities in the monitored sites with respect to light, moisture, pH and nitrogen. These functional signatures are then compared to reference distributions of functional signature, separately for each wetland ecosystem type, calculated from 'generalized species lists' underlying the Norwegian categorization system for eco-diversity (Halvorsen et al. 2020). These plant functional type indicators are developed following the principles and technical protocol of the IBECA framework (Jakobsson et al. 2021, Töpper & Jakobsson 2021).
Parallel indicator sets are explored and developed for [semi-natural ecosystems](#functional-plant-indicators-seminat) and naturally [open ecosystems](#functional-plant-indicators-open).
## About the underlying data {#underlying-data-fpiw}
We use three sets of data for building indicators for ecological condition:
- as test data we use plant community data from the ANO monitoring scheme (cf. Tingstad et al. 2019)
- as reference data we use generalized species lists from the Norwegian categorization system for eco-diversity (NiN) (cf. Halvorsen et al. 2020)
- Swedish plant indicator data for light, moisture, pH, and nitrogen from Tyler et al. (2021)
(1) **ANO monitoring data**:
ANO stands for _areal-representativ naturovervåking_, i.e. _area representative nature monitoring_. 1000 sites are randomly distributed across mainland Norway and visitied within a 5-year cycle. Each ANO site spans a 500 x 500 m grid cell, and the data collection at each ANO site includes up to 12 evenly distributed vegetation analyses in 1 x 1 m plots (up to 12, because some of these evenly distributed points may be in water or otherwise inaccessible). For the vegetation analyses, the cover of each vascular plant species in the plot is recorded. Every vegetation analysis is accompanied by an assessment of the ecosystem the plot lies in, including ecosystem type and some additional variables related to ecosystem-specific drivers of state. In the wetland-analysis in this document, we only use the plots which were classified as one of the wetland ecosystem types in the Norwegian categorization system for eco-diversity (NiN).
In the analysis in this document, we use the data available on Miljødirektoratets kartkatalog (https://kartkatalog.miljodirektoratet.no/Dataset/Details/2054), which comprises data from the first three ANO-years, 2019-2021, and a total of 8887 plots in 498 sites.
(2) **NiN reference data**:
The generalized species lists underlying the ecosystem categorization in [NiN](https://artsdatabanken.no/NiN) represent expert-compiled species lists based on empirical evidence from the literature and expert knowledge of the systems and their species. In these lists, every species is assigned an abundance value on a 6-step scale, with each step representing a range for the 'expected combination of frequency and cover' of occurrence
- 1 = \< 1/32
- 2 = 1/32 - 1/8
- 3 = 1/8 - 3/8
- 4 = 3/8 - 4/5
- 5 = 3/8 - 4/5 + dominance
- 6 = \> 4/5
For the purpose of this project, these steps are simplified to maximum _expected combination of frequency and cover_, whereby steps 4 & 5 are assigned 0.6 and 0.8, respectively, in order to distinguish between them.
(3) **The Swedish plant indicator set** published by Tyler et al. (2021) contains a large collection of plant indicators based on the Swedish flora, which is well representative of the Norwegian flora as well. From this set, we decided to include indicator data for light, moisture, pH, and nitrogen for wetlands as these are thought to be subject to potential change due to shrub/tree encroachment, drainage, and pollution.
### Representativity in time and space {#representativity-fpiw}
For wetlands, the ANO data contain 1351 plots in 330 sites, in principle distributed randomly across the country. As wetlands occur more often in certain regions of Norway than in others, the amount of plots and sites is not equal among Norway's five regions. The 1351
<!-- I cannot recreate this number. Use in-line R code, here and elsewhere in similar situations -->
plots are distributed across regions in the following way:
- Northern Norway: 416
- Central Norway: 361
- Eastern Norway: 294
- Western Norway: 150
- Southern Norway: 126
### Temporal coverage {#representativity-temporal-fpiw}
The evaluation data cover the first three years, 2019-2021, of the first 5-year-cycle in the ANO monitoring scheme. Thus there is no actual time series to these data, and the indicator evaluation does therefore not include any temporal analyses.
## Collinearities with other indicators
Collinearity could occur with other indicators that are responding to the same drivers/pressures, but no really problematic issues have been discussed.
## Reference state and values {#ref-state-fpiw}
### Reference state {#ref-state2-fpiw}
The reference state is defined via the functional signature of the generalized species lists in NiN (see also Töpper et al. 2018). By bootstrapping the species lists (see details further below) and calculating community-weighted means of functional plant indicators for every re-sampled community, we describe the reference state as a distribution of indicator values for each respective plant functional indicator. These distributions are calculated for minor ecosystem types ( _grunntyper_ or _kartleggingsenheter_ at a 1:5000 mapping scale) within the major ecosystem types (hovedtyper) in NiN. A more extensive discussion on the use of reference communities can be found in Jakobsson et al. (2020).
### Reference values, thresholds for defining _good ecological condition_, minimum and/or maximum values {#ref-values-fpiw}
In this analysis, we derive scaling values from statistical (here, non-parametric) distributions (see Jakobsson et al. 2010). For each ecosystem sub-type and plant functional indicator, the reference value is defined as the median value of the indicator value distribution. As in most cases the distributions naturally are two-sided (but see the Heat-requirement indicator in the mountain assessment for an example of a one-sided plant functional indicator, Fremstad et al. 2022), and deviation from the optimal state thus may occur in both direction (e.g. indicating too low or too high pH), we need to define two threshold values for good ecological condition as well as both a minimum and maximum value. In line with previous assessments of ecological condition for Norwegian forests and mountains, we define a lower and an upper threshold value via the 95% confidence interval of the reference distribution, i.e. its 0.025 and 0.975 quantiles. The minimum and maximum values are given by the minimum and maximum of the possible indicator values for each respective plant functional indicator. For details on the scaling principles in IBECA, please see Töpper & Jakobsson (2021).
## Uncertainties {#uncertainties-fpiw}
We can calculate a mean indicator value (after scaling) for every region (or any other delimited area of interest) as well as its corresponding standard error as a measure of spatial uncertainty for a geographical area.
## References {#references-fpiw}
Diekmann, M. 2003. Species indicator values as an important tool in applied plant ecology - a review. Basic and Applied Ecology 4: 493-506, doi:10.1078/1439-1791-00185
Framstad, E., Kolstad, A. L., Nybø, S., Töpper, J. & Vandvik, V. 2022. The condition of forest and mountain ecosystems in Norway. Assessment by the IBECA method. NINA Report 2100. Norwegian Institute for Nature Research.
Halvorsen, R., Skarpaas, O., Bryn, A., Bratli, H., Erikstad, L., Simensen, T., & Lieungh, E. (2020). Towards a systematics of ecodiversity: The EcoSyst framework. Global Ecology and Biogeography, 29(11), 1887-1906. doi:10.1111/geb.13164
Jakobsson, S., Töpper, J.P., Evju, M., Framstad, E., Lyngstad, A., Pedersen, B., Sickel, H., Sverdrup-Thygeson, A., Vandvik. V., Velle, L.G., Aarrestad, P.A. & Nybø, S. 2020. Setting reference levels and limits for good ecological condition in terrestrial ecosystems. Insights from a case study based on the IBECA approach. Ecological Indicators 116: 106492.
Jakobsson, S., Evju, M., Framstad, E., Imbert, A., Lyngstad, A., Sickel, H., Sverdrup-Thygeson, A., Töpper, J., Vandvik, V., Velle, L.G., Aarrestad, P.A. & Nybø, S. 2021. An index-based assessment of ecological condition and its links to international frameworks. Ecological Indicators 124: 107252.
Tingstad, L., Evju, M., Sickel, H., & Töpper, J. 2019. Utvikling av nasjonal arealrepresentativ naturovervåking (ANO). Forslag til gjennomføring, protokoller og kostnadsvurderinger med utgangspunkt i erfaringer fra uttesting i Trøndelag. NINA Rapport 1642.
Töpper, J. & Jakobsson, S. 2021. The Index-Based Ecological Condition Assessment (IBECA) - Technical protocol, version 1.0. NINA Report 1967. Norwegian Institute for Nature Research.
Töpper, J., Velle, L.G. & Vandvik, V. 2018. Developing a method for assessment of ecological state based on indicator values after Ellenberg and Grime (revised edition). NINA Report 1529b. Norwegian Institute for Nature Research.
Tyler, T., Herbertsson, L., Olofsson, J., & Olsson, P. A. 2021. Ecological indicator and traits values for Swedish vascular plants. Ecological In-dicators, 120. doi:10.1016/j.ecolind.2020.106923
## Analyses {#analyses-fpiw}
### Data sets
<!-- Please print the entire workflow with echo=T. Also, simply reading cached data creates loose ends - I cant find out where this data comes from. You may also chose to read tin this data (or a cached version of it) way at the top of the file, so that you can add some in-line R code for the summary stats in the introduction part (see previous comments)-->
Import ANO data:
```{r}
# Add data from cache
ANO.sp<-readRDS(paste0(here::here(),"/data/cache/ANO.sp.RDS"))
ANO.geo<-readRDS(paste0(here::here(),"/data/cache/ANO.geo.RDS"))
# st_layers(dsn = "/data/P-Prosjekter2/41201785_okologisk_tilstand_2022_2023/data/Naturovervaking_eksport.gdb")
# ANO.sp <- st_read("/data/P-Prosjekter2/41201785_okologisk_tilstand_2022_2023/data/Naturovervaking_eksport.gdb",
# layer="ANO_Art")
# ANO.geo <- st_read("/data/P-Prosjekter2/41201785_okologisk_tilstand_2022_2023/data/Naturovervaking_eksport.gdb",
# layer="ANO_SurveyPoint")
# head(ANO.sp)
# head(ANO.geo)
```
Import Plant indicators from Tyler et al. (2021):
```{r}
## Tyler indicator data
## data from cache
ind.dat <-readRDS(paste0(here::here(),"/data/cache/ind.dat.RDS"))
# ind.dat <- read.table("/data/P-Prosjekter2/41201785_okologisk_tilstand_2022_2023/data/functional plant indicators/Tyler et al_Swedish plant indicators.txt",
# sep = '\t', header=T, quote = '')
# head(ind.dat)
```
Import Generalized species lists NiN
```{r}
# data from cache
Eco_State<-readRDS(paste0(here::here(),"/data/cache/Eco_State.RDS"))
# load("/data/P-Prosjekter2/41201785_okologisk_tilstand_2022_2023/functional plant indicators/reference from NiN/Eco_State.RData")
# str(Eco_State)
```
#### Data handling
- Checking for errors
- Checking species nomenclature in the different species lists to make species and indicator data possible to merge
- Merging indicator data with monitoring data and indicator data with reference data
(not shown here, but documented in the code)
<!-- Please include everything like this, but you can chose to have it take up less space by adding the attr.output option, like this: -->
```{r, include = T, results='hide', warning=F, message=F}
### Plant indicator data
names(ind.dat)
names(ind.dat)[1] <- 'species'
ind.dat$species <- as.factor(ind.dat$species)
summary(ind.dat$species)
ind.dat <- ind.dat[!is.na(ind.dat$species),] # removing species-NAs
ind.dat[,'species.orig'] <- ind.dat[,'species'] # make a backup of the original species variable
ind.dat[,'species'] <- word(ind.dat[,'species'], 1,2) # trimming away sub-species & co, and descriptor info
# the trimming above leaves some duplicates that need to be taken care of
ind.dat[duplicated(ind.dat[,'species']),"species"]
ind.dat.dup <- ind.dat[duplicated(ind.dat[,'species']),"species"]
ind.dat[ind.dat$species %in% ind.dat.dup,c("Light","Moisture","Soil_reaction_pH","Nitrogen","species.orig","species")]
ind.dat <- ind.dat %>% filter( !(species.orig %in% list("Ammophila arenaria x Calamagrostis epigejos",
"Anemone nemorosa x ranunculoides",
"Armeria maritima ssp. elongata",
"Asplenium trichomanes ssp. quadrivalens",
"Calystegia sepium ssp. spectabilis",
"Campanula glomerata 'Superba'",
"Dactylorhiza maculata ssp. fuchsii",
"Erigeron acris ssp. droebachensis",
"Erigeron acris ssp. politus",
"Erysimum cheiranthoides L. ssp. alatum",
"Euphrasia nemorosa x stricta var. brevipila",
"Galium mollugo x verum",
"Geum rivale x urbanum",
"Hylotelephium telephium (ssp. maximum)",
"Juncus alpinoarticulatus ssp. rariflorus",
"Lamiastrum galeobdolon ssp. argentatum",
"Lathyrus latifolius ssp. heterophyllus",
"Medicago sativa ssp. falcata",
"Medicago sativa ssp. x varia",
"Monotropa hypopitys ssp. hypophegea",
"Ononis spinosa ssp. hircina",
"Ononis spinosa ssp. procurrens",
"Pilosella aurantiaca ssp. decolorans",
"Pilosella aurantiaca ssp. dimorpha",
"Pilosella cymosa ssp. gotlandica",
"Pilosella cymosa ssp. praealta",
"Pilosella officinarum ssp. peleteranum",
"Poa x jemtlandica (Almq.) K. Richt.",
"Poa x herjedalica Harry Sm.",
"Ranunculus peltatus ssp. baudotii",
"Sagittaria natans x sagittifolia",
"Salix repens ssp. rosmarinifolia",
"Stellaria nemorum L. ssp. montana",
"Trichophorum cespitosum ssp. germanicum")
) )
# checking duplicates again
ind.dat[duplicated(ind.dat[,'species']),"species"]
ind.dat.dup <- ind.dat[duplicated(ind.dat[,'species']),"species"]
ind.dat[ind.dat$species %in% ind.dat.dup,c("Light","Moisture","Soil_reaction_pH","Nitrogen","species.orig","species")]
# getting rid of sect. for Hieracium
ind.dat <- ind.dat %>% mutate(species=gsub("sect. ","",species.orig))
ind.dat[,'species'] <- word(ind.dat[,'species'], 1,2)
ind.dat[duplicated(ind.dat[,'species']),"species"]
ind.dat.dup <- ind.dat[duplicated(ind.dat[,'species']),"species"]
ind.dat[ind.dat$species %in% ind.dat.dup,c("Light","Moisture","Soil_reaction_pH","Nitrogen","species.orig","species")]
# only hybrids left -> get rid of these
ind.dat <- ind.dat[!duplicated(ind.dat[,'species']),]
ind.dat[duplicated(ind.dat[,'species']),"species"]
ind.dat$species <- as.factor(ind.dat$species)
summary(ind.dat$species)
# no duplicates left
head(ind.dat)
### ANO monitoring data
head(ANO.sp)
head(ANO.geo)
## fix NiN information
ANO.geo$hovedtype_rute <- substr(ANO.geo$kartleggingsenhet_1m2,1,3) # take the 3 first characters
ANO.geo$hovedtype_rute <- gsub("-", "", ANO.geo$hovedtype_rute) # remove hyphen
unique(as.factor(ANO.geo$hovedtype_rute))
## fix NiN-variables
colnames(ANO.geo)
colnames(ANO.geo)[42:47] <- c("groeftingsintensitet",
"bruksintensitet",
"beitetrykk",
"slatteintensitet",
"tungekjoretoy",
"slitasje")
head(ANO.geo)
# remove variable code in the data
ANO.geo$groeftingsintensitet <- gsub("7GR-GI_", "", ANO.geo$groeftingsintensitet)
unique(ANO.geo$groeftingsintensitet)
ANO.geo$groeftingsintensitet <- gsub("X", "NA", ANO.geo$groeftingsintensitet)
unique(ANO.geo$groeftingsintensitet)
ANO.geo$groeftingsintensitet <- as.numeric(ANO.geo$groeftingsintensitet)
unique(ANO.geo$groeftingsintensitet)
ANO.geo$bruksintensitet <- gsub("7JB-BA_", "", ANO.geo$bruksintensitet)
unique(ANO.geo$bruksintensitet)
ANO.geo$bruksintensitet <- gsub("X", "NA", ANO.geo$bruksintensitet)
unique(ANO.geo$bruksintensitet)
ANO.geo$bruksintensitet <- as.numeric(ANO.geo$bruksintensitet)
unique(ANO.geo$bruksintensitet)
ANO.geo$beitetrykk <- gsub("7JB-BT_", "", ANO.geo$beitetrykk)
unique(ANO.geo$beitetrykk)
ANO.geo$beitetrykk <- gsub("X", "NA", ANO.geo$beitetrykk)
unique(ANO.geo$beitetrykk)
ANO.geo$beitetrykk <- as.numeric(ANO.geo$beitetrykk)
unique(ANO.geo$beitetrykk)
ANO.geo$slatteintensitet <- gsub("7JB-SI_", "", ANO.geo$slatteintensitet)
unique(ANO.geo$slatteintensitet)
ANO.geo$slatteintensitet <- gsub("X", "NA", ANO.geo$slatteintensitet)
unique(ANO.geo$slatteintensitet)
ANO.geo$slatteintensitet <- as.numeric(ANO.geo$slatteintensitet)
unique(ANO.geo$slatteintensitet)
ANO.geo$tungekjoretoy <- gsub("7TK_", "", ANO.geo$tungekjoretoy)
unique(ANO.geo$tungekjoretoy)
ANO.geo$tungekjoretoy <- gsub("X", "NA", ANO.geo$tungekjoretoy)
unique(ANO.geo$tungekjoretoy)
ANO.geo$tungekjoretoy <- as.numeric(ANO.geo$tungekjoretoy)
unique(ANO.geo$tungekjoretoy)
ANO.geo$slitasje <- gsub("7SE_", "", ANO.geo$slitasje)
unique(ANO.geo$slitasje)
ANO.geo$slitasje <- gsub("X", "NA", ANO.geo$slitasje)
unique(ANO.geo$slitasje)
ANO.geo$slitasje <- as.numeric(ANO.geo$slitasje)
unique(ANO.geo$slitasje)
## check that every point is present only once
length(levels(as.factor(ANO.geo$ano_flate_id)))
length(levels(as.factor(ANO.geo$ano_punkt_id)))
summary(as.factor(ANO.geo$ano_punkt_id))
# there's many double presences, probably some wrong registrations of point numbers,
# but also double registrations (e.g. ANO0159_55)
# CHECK THIS when preparing ecosystem-datasets for scaling
# fix species names
ANO.sp$Species <- ANO.sp$art_navn
unique(as.factor(ANO.sp$Species))
ANO.sp[,'Species'] <- word(ANO.sp[,'Species'], 1,2) # lose subspecies
ANO.sp$Species <- str_to_title(ANO.sp$Species) # make first letter capital
ANO.sp$Species <- gsub("( .*)","\\L\\1",ANO.sp$Species,perl=TRUE) # make capital letters after hyphen to lowercase
ANO.sp$Species <- gsub("( .*)","\\L\\1",ANO.sp$Species,perl=TRUE) # make capital letters after space to lowercase
## merge species data with indicators
ANO.sp.ind <- merge(x=ANO.sp[,c("Species", "art_dekning", "ParentGlobalID")],
y= ind.dat[,c("species", "Light", "Moisture", "Soil_reaction_pH", "Nitrogen")],
by.x="Species", by.y="species", all.x=T)
summary(ANO.sp.ind)
## checking which species didn't find a match
unique(ANO.sp.ind[is.na(ANO.sp.ind$Moisture),'Species'])
# fix species name issues
ind.dat <- ind.dat %>%
mutate(species=str_replace(species,"Aconitum lycoctonum", "Aconitum septentrionale")) %>%
mutate(species=str_replace(species,"Carex simpliciuscula", "Kobresia simpliciuscula")) %>%
mutate(species=str_replace(species,"Carex myosuroides", "Kobresia myosuroides")) %>%
mutate(species=str_replace(species,"Clinopodium acinos", "Acinos arvensis")) %>%
mutate(species=str_replace(species,"Artemisia rupestris", "Artemisia norvegica")) %>%
mutate(species=str_replace(species,"Cherleria biflora", "Minuartia biflora"))
ANO.sp <- ANO.sp %>%
mutate(Species=str_replace(Species,"Arctous alpinus", "Arctous alpina")) %>%
mutate(Species=str_replace(Species,"Betula tortuosa", "Betula pubescens")) %>%
mutate(Species=str_replace(Species,"Blysmopsis rufa", "Blysmus rufus")) %>%
mutate(Species=str_replace(Species,"Cardamine nymanii", "Cardamine pratensis")) %>%
mutate(Species=str_replace(Species,"Carex adelostoma", "Carex buxbaumii")) %>%
mutate(Species=str_replace(Species,"Carex leersii", "Carex echinata")) %>%
mutate(Species=str_replace(Species,"Carex paupercula", "Carex magellanica")) %>%
mutate(Species=str_replace(Species,"Carex simpliciuscula", "Kobresia simpliciuscula")) %>%
mutate(Species=str_replace(Species,"Carex viridula", "Carex flava")) %>%
mutate(Species=str_replace(Species,"Chamaepericlymenum suecicum", "Cornus suecia")) %>%
mutate(Species=str_replace(Species,"Cicerbita alpina", "Lactuca alpina")) %>%
mutate(Species=str_replace(Species,"Empetrum hermaphroditum", "Empetrum nigrum")) %>%
mutate(Species=str_replace(Species,"Festuca prolifera", "Festuca rubra")) %>%
mutate(Species=str_replace(Species,"Galium album", "Galium mollugo")) %>%
mutate(Species=str_replace(Species,"Galium elongatum", "Galium palustre")) %>%
mutate(Species=str_replace(Species,"Helictotrichon pratense", "Avenula pratensis")) %>%
mutate(Species=str_replace(Species,"Helictotrichon pubescens", "Avenula pubescens")) %>%
mutate(Species=str_replace(Species,"Hieracium alpina", "Hieracium Alpina")) %>%
mutate(Species=str_replace(Species,"Hieracium alpinum", "Hieracium Alpina")) %>%
mutate(Species=str_replace(Species,"Hieracium hieracium", "Hieracium Hieracium")) %>%
mutate(Species=str_replace(Species,"Hieracium hieracioides", "Hieracium umbellatum")) %>%
mutate(Species=str_replace(Species,"Hieracium murorum", "Hieracium Vulgata")) %>%
mutate(Species=str_replace(Species,"Hieracium oreadea", "Hieracium Oreadea")) %>%
mutate(Species=str_replace(Species,"Hieracium prenanthoidea", "Hieracium Prenanthoidea")) %>%
mutate(Species=str_replace(Species,"Hieracium vulgata", "Hieracium Vulgata")) %>%
mutate(Species=str_replace(Species,"Hieracium pilosella", "Pilosella officinarum")) %>%
mutate(Species=str_replace(Species,"Hieracium vulgatum", "Hieracium umbellatum")) %>%
mutate(Species=str_replace(Species,"Hierochloã« alpina", "Hierochloë alpina")) %>%
mutate(Species=str_replace(Species,"Hierochloã« hirta", "Hierochloë hirta")) %>%
mutate(Species=str_replace(Species,"Hierochloã« odorata", "Hierochloë odorata")) %>%
mutate(Species=str_replace(Species,"Listera cordata", "Neottia cordata")) %>%
mutate(Species=str_replace(Species,"Leontodon autumnalis", "Scorzoneroides autumnalis")) %>%
mutate(Species=str_replace(Species,"Loiseleuria procumbens", "Kalmia procumbens")) %>%
mutate(Species=str_replace(Species,"Mycelis muralis", "Lactuca muralis")) %>%
mutate(Species=str_replace(Species,"Omalotheca supina", "Gnaphalium supinum")) %>%
mutate(Species=str_replace(Species,"Omalotheca norvegica", "Gnaphalium norvegicum")) %>%
mutate(Species=str_replace(Species,"Omalotheca sylvatica", "Gnaphalium sylvaticum")) %>%
mutate(Species=str_replace(Species,"Oreopteris limbosperma", "Thelypteris limbosperma")) %>%
mutate(Species=str_replace(Species,"Oxycoccus microcarpus", "Vaccinium microcarpum")) %>%
mutate(Species=str_replace(Species,"Oxycoccus palustris", "Vaccinium oxycoccos")) %>%
mutate(Species=str_replace(Species,"Phalaris minor", "Phalaris arundinacea")) %>%
mutate(Species=str_replace(Species,"Pinus unicinata", "Pinus mugo")) %>%
mutate(Species=str_replace(Species,"Poa alpigena", "Poa pratensis")) %>%
mutate(Species=str_replace(Species,"Poa angustifolia", "Poa pratensis")) %>%
mutate(Species=str_replace(Species,"Pyrola grandiflora", "Pyrola rotundifolia")) %>%
mutate(Species=str_replace(Species,"Rumex alpestris", "Rumex acetosa")) %>%
mutate(Species=str_replace(Species,"Syringa emodi", "Syringa vulgaris")) %>%
mutate(Species=str_replace(Species,"Taraxacum crocea", "Taraxacum officinale")) %>%
mutate(Species=str_replace(Species,"Taraxacum croceum", "Taraxacum officinale")) %>%
mutate(Species=str_replace(Species,"Trientalis europaea", "Lysimachia europaea")) %>%
mutate(Species=str_replace(Species,"Trifolium pallidum", "Trifolium pratense"))
## merge species data with indicators
ANO.sp.ind <- merge(x=ANO.sp[,c("Species", "art_dekning", "ParentGlobalID")],
y= ind.dat[,c("species", "Light", "Moisture", "Soil_reaction_pH", "Nitrogen")],
by.x="Species", by.y="species", all.x=T)
summary(ANO.sp.ind)
# checking which species didn't find a match
unique(ANO.sp.ind[is.na(ANO.sp.ind$Moisture),'Species'])
# don't find synonyms for these in the ind lists
## trimming away the points without information on NiN, species or cover
ANO.sp.ind <- ANO.sp.ind[!is.na(ANO.sp.ind$Species),]
ANO.sp.ind <- ANO.sp.ind[!is.na(ANO.sp.ind$art_dekning),]
summary(ANO.sp.ind)
head(ANO.sp.ind)
rm(ANO.sp)
### NiN reference data - data handling
## generalized species lists from NiN
str(Eco_State)
# species
Eco_State$Concept_Data$Species$Species_List$species
# environments
t(Eco_State$Concept_Data$Env$Env_Data)
# abundances
t(Eco_State$Concept_Data$Species$Species_Data)
## transposing abundance data
NiN.sp <- t(Eco_State$Concept_Data$Species$Species_Data)
NiN.sp <- as.data.frame(NiN.sp)
NiN.sp$sp <- as.factor(as.vector(Eco_State$Concept_Data$Species$Species_List$species))
# only genus and species name
NiN.sp$sp <- word(NiN.sp$sp, 1,2)
NiN.sp$spgr <- as.factor(as.vector(Eco_State$Concept_Data$Species$Species_List$art.code))
# if relevant, trimming to desired species groups (for forests e.g. removing trees)
#NiN.sp <- NiN.sp[NiN.sp$spgr!="a1a",]
## environment data
NiN.env <- Eco_State$Concept_Data$Env$Env_Data
## merging with indicator values
NiN.sp.ind <- merge(NiN.sp,ind.dat, by.x="sp", by.y="species", all.x=T)
summary(NiN.sp.ind)
NiN.sp.ind[NiN.sp.ind==999] <- NA
## checking which species didn't find a match
unique(NiN.sp.ind[is.na(NiN.sp.ind$Moisture) & NiN.sp.ind$spgr %in% list("a1a","a1b","a1c"),'sp'])
## fix species name issues
ind.dat <- ind.dat %>%
mutate(species=str_replace(species,"Aconitum lycoctonum", "Aconitum septentrionale")) %>%
mutate(species=str_replace(species,"Carex simpliciuscula", "Kobresia simpliciuscula")) %>%
mutate(species=str_replace(species,"Carex myosuroides", "Kobresia myosuroides")) %>%
mutate(species=str_replace(species,"Clinopodium acinos", "Acinos arvensis")) %>%
mutate(species=str_replace(species,"Artemisia rupestris", "Artemisia norvegica")) %>%
mutate(species=str_replace(species,"Cherleria biflora", "Minuartia biflora"))
NiN.sp <- NiN.sp %>%
mutate(sp=str_replace(sp,"Aconitum lycoctonum", "Aconitum septentrionale")) %>%
mutate(sp=str_replace(sp,"Anagallis minima", "Lysimachia minima")) %>%
mutate(sp=str_replace(sp,"Arctous alpinus", "Arctous alpina")) %>%
mutate(sp=str_replace(sp,"Betula tortuosa", "Betula pubescens")) %>%
mutate(sp=str_replace(sp,"Blysmopsis rufa", "Blysmus rufus")) %>%
mutate(sp=str_replace(sp,"Cardamine nymanii", "Cardamine pratensis")) %>%
mutate(sp=str_replace(sp,"Carex adelostoma", "Carex buxbaumii")) %>%
mutate(sp=str_replace(sp,"Carex leersii", "Carex echinata")) %>%
mutate(sp=str_replace(sp,"Carex paupercula", "Carex magellanica")) %>%
mutate(sp=str_replace(sp,"Carex simpliciuscula", "Kobresia simpliciuscula")) %>%
mutate(sp=str_replace(sp,"Carex _vacillans", "Carex vacillans")) %>%
mutate(sp=str_replace(sp,"Carex viridula", "Carex flava")) %>%
mutate(sp=str_replace(sp,"Chamaepericlymenum suecicum", "Cornus suecia")) %>%
mutate(sp=str_replace(sp,"Cornus suecia", "Cornus suecica")) %>%
mutate(sp=str_replace(sp,"Cicerbita alpina", "Lactuca alpina")) %>%
mutate(sp=str_replace(sp,"Dactylorhiza sphagnicola", "Dactylorhiza majalis")) %>%
mutate(sp=str_replace(sp,"Diphasiastrum complanatum", "Lycopodium complanatum")) %>%
mutate(sp=str_replace(sp,"Elymus alaskanus", "Elymus kronokensis")) %>%
mutate(sp=str_replace(sp,"Empetrum hermaphroditum", "Empetrum nigrum")) %>%
mutate(sp=str_replace(sp,"Erigeron eriocephalus", "Erigeron uniflorus")) %>%
mutate(sp=str_replace(sp,"Festuca prolifera", "Festuca rubra")) %>%
mutate(sp=str_replace(sp,"Galium album", "Galium mollugo")) %>%
mutate(sp=str_replace(sp,"Galium elongatum", "Galium palustre")) %>%
mutate(sp=str_replace(sp,"Glaux maritima", "Lysimachia maritima")) %>%
mutate(sp=str_replace(sp,"Helictotrichon pratense", "Avenula pratensis")) %>%
mutate(sp=str_replace(sp,"Helictotrichon pubescens", "Avenula pubescens")) %>%
mutate(sp=str_replace(sp,"Hieracium alpina", "Hieracium Alpina")) %>%
mutate(sp=str_replace(sp,"Hieracium alpinum", "Hieracium Alpina")) %>%
mutate(sp=str_replace(sp,"Hieracium aurantiacum", "Pilosella aurantiaca")) %>%
mutate(sp=str_replace(sp,"Hieracium hieracium", "Hieracium Hieracium")) %>%
mutate(sp=str_replace(sp,"Hieracium hieracioides", "Hieracium umbellatum")) %>%
mutate(sp=str_replace(sp,"Hieracium lactucella", "Pilosella lactucella")) %>%
mutate(sp=str_replace(sp,"Hieracium murorum", "Hieracium Vulgata")) %>%
mutate(sp=str_replace(sp,"Hieracium oreadea", "Hieracium Oreadea")) %>%
mutate(sp=str_replace(sp,"Hieracium prenanthoidea", "Hieracium Prenanthoidea")) %>%
mutate(sp=str_replace(sp,"Hieracium vulgata", "Hieracium Vulgata")) %>%
mutate(sp=str_replace(sp,"Hieracium pilosella", "Pilosella officinarum")) %>%
mutate(sp=str_replace(sp,"Hieracium vulgatum", "Hieracium umbellatum")) %>%
mutate(sp=str_replace(sp,"Hierochloã« alpina", "Hierochloë alpina")) %>%
mutate(sp=str_replace(sp,"Hierochloã« hirta", "Hierochloë hirta")) %>%
mutate(sp=str_replace(sp,"Hierochloã« odorata", "Hierochloë odorata")) %>%
mutate(sp=str_replace(sp,"Huperzia appressa", "Huperzia selago")) %>%
mutate(sp=str_replace(sp,"Hylotelephium maximum", "Hylotelephium telephium")) %>%
mutate(sp=str_replace(sp,"Lappula myosotis", "Lappula squarrosa")) %>%
mutate(sp=str_replace(sp,"Lepidotheca suaveolens", "Matricaria discoidea")) %>%
mutate(sp=str_replace(sp,"Listera cordata", "Neottia cordata")) %>%
mutate(sp=str_replace(sp,"Leontodon autumnalis", "Scorzoneroides autumnalis")) %>%
mutate(sp=str_replace(sp,"Loiseleuria procumbens", "Kalmia procumbens")) %>%
mutate(sp=str_replace(sp,"Logfia arvensis", "Filago arvensis")) %>%
mutate(sp=str_replace(sp,"Mentha _verticillata", "Mentha verticillata")) %>%
mutate(sp=str_replace(sp,"Minuartia rubella", "Sabulina rubella")) %>%
mutate(sp=str_replace(sp,"Minuartia stricta", "Sabulina stricta")) %>%
mutate(sp=str_replace(sp,"Mycelis muralis", "Lactuca muralis")) %>%
mutate(sp=str_replace(sp,"Omalotheca supina", "Gnaphalium supinum")) %>%
mutate(sp=str_replace(sp,"Omalotheca norvegica", "Gnaphalium norvegicum")) %>%
mutate(sp=str_replace(sp,"Omalotheca sylvatica", "Gnaphalium sylvaticum")) %>%
mutate(sp=str_replace(sp,"Ononis arvensis", "Ononis spinosa")) %>%
mutate(sp=str_replace(sp,"Oreopteris limbosperma", "Thelypteris limbosperma")) %>%
mutate(sp=str_replace(sp,"Oxycoccus microcarpus", "Vaccinium microcarpum")) %>%
mutate(sp=str_replace(sp,"Oxycoccus palustris", "Vaccinium oxycoccos")) %>%
mutate(sp=str_replace(sp,"Phalaris minor", "Phalaris arundinacea")) %>%
mutate(sp=str_replace(sp,"Phalaroides arundinacea", "Phalaris arundinacea")) %>%
mutate(sp=str_replace(sp,"Pinus unicinata", "Pinus mugo")) %>%
mutate(sp=str_replace(sp,"Platanthera montana", "Platanthera chlorantha")) %>%
mutate(sp=str_replace(sp,"Poa alpigena", "Poa pratensis")) %>%
mutate(sp=str_replace(sp,"Poa angustifolia", "Poa pratensis")) %>%
mutate(sp=str_replace(sp,"Poa laxa", "Poa flexuosa")) %>%
mutate(sp=str_replace(sp,"Poa _herjedalica", "Poa herjedalica")) %>%
mutate(sp=str_replace(sp,"Poa _jemtlandica", "Poa jemtlandica")) %>%
mutate(sp=str_replace(sp,"Poa lindebergii", "Poa arctica")) %>%
mutate(sp=str_replace(sp,"Pyrola grandiflora", "Pyrola rotundifolia")) %>%
mutate(sp=str_replace(sp,"Rhamnus catharticus", "Rhamnus cathartica")) %>%
mutate(sp=str_replace(sp,"Rumex alpestris", "Rumex acetosa")) %>%
mutate(sp=str_replace(sp,"Salix _fragilis", "Salix fragilis")) %>%
mutate(sp=str_replace(sp,"Saxifraga _opdalensis", "Saxifraga opdalensis")) %>%
mutate(sp=str_replace(sp,"Spergularia salina", "Spergularia marina")) %>%
mutate(sp=str_replace(sp,"Syringa emodi", "Syringa vulgaris")) %>%
mutate(sp=str_replace(sp,"Taraxacum crocea", "Taraxacum officinale")) %>%
mutate(sp=str_replace(sp,"Taraxacum croceum", "Taraxacum officinale")) %>%
mutate(sp=str_replace(sp,"Taraxacum erythrospermum", "Taraxacum officinale")) %>%
mutate(sp=str_replace(sp,"Taraxacum hamatum", "Taraxacum officinale")) %>%
mutate(sp=str_replace(sp,"Trientalis europaea", "Lysimachia europaea")) %>%
mutate(sp=str_replace(sp,"Trifolium pallidum", "Trifolium pratense")) %>%
mutate(sp=str_replace(sp,"Vicia orobus", "Vicia cassubica"))
## merge species data with indicators
NiN.sp.ind <- merge(NiN.sp,ind.dat, by.x="sp", by.y="species", all.x=T)
summary(NiN.sp.ind)
NiN.sp.ind[NiN.sp.ind==999] <- NA
# checking which species didn't find a match
unique(NiN.sp.ind[is.na(NiN.sp.ind$Moisture) & NiN.sp.ind$spgr %in% list("a1a","a1b","a1c"),'sp'])
# ok now
## matching with NiN ecosystem types - for wetlands
# NB! beware of rogue spaces in the 'Nature_type' & 'Sub_Type' variables, e.g. "Spring_Forest "
NiN.wetland <- NiN.sp.ind[,c("sp",paste(NiN.env[NiN.env$Nature_Type=="Mire","ID"]),colnames(ind.dat)[15:18])] # Light, Moisture, Soil_reaction_pH, Nitrogen
NiN.wetland[1,]
names(NiN.wetland)
cbind(colnames(NiN.wetland),
c("",
'V3-C1a','V3-C1b','V3-C1c','V3-C1d','V3-C1e',
'V1-C1a','V1-C1b','V1-C1c','V1-C1d','V1-C1e',
'V1-C2a','V1-C2b','V1-C2c','V1-C2d',
'V1-C3a','V1-C3b','V1-C3c','V1-C3d',
'V1-C4a','V1-C4b','V1-C4c','V1-C4d',
'V1-C4e','V1-C4f','V1-C4g','V1-C4h',
'V3-C2','V1-C5',
'V1-C6a','V1-C6b',
'V1-C7a','V1-C7b',
'V1-C8a','V1-C8b',
'V2-C1a','V2-C1b',
'V2-C2a','V2-C2b',
'V2-C3a','V2-C3b',
"V4-C2","V4-C3",
"","",
'V8-C1','V8-C2','V8-C3',
rep("",10),
rep("",4)
)
)
NiN.wetland <- NiN.wetland[,c(1:43,46:48,59:62)]
colnames(NiN.wetland)[2:46] <- c('V3-C1a','V3-C1b','V3-C1c','V3-C1d','V3-C1e',
'V1-C1a','V1-C1b','V1-C1c','V1-C1d','V1-C1e',
'V1-C2a','V1-C2b','V1-C2c','V1-C2d',
'V1-C3a','V1-C3b','V1-C3c','V1-C3d',
'V1-C4a','V1-C4b','V1-C4c','V1-C4d',
'V1-C4e','V1-C4f','V1-C4g','V1-C4h',
'V3-C2','V1-C5',
'V1-C6a','V1-C6b',
'V1-C7a','V1-C7b',
'V1-C8a','V1-C8b',
'V2-C1a','V2-C1b',
'V2-C2a','V2-C2b',
'V2-C3a','V2-C3b',
'V4-C2','V4-C3',
'V8-C1','V8-C2','V8-C3'
)
head(NiN.wetland)
# translating the abundance classes into %-cover
coverscale <- data.frame(orig=0:6,
cov=c(0,1/32,1/8,3/8,0.6,4/5,1)
)
NiN.wetland.cov <- NiN.wetland
colnames(NiN.wetland.cov)
for (i in 2:46) {
NiN.wetland.cov[,i] <- coverscale[,2][ match(NiN.wetland[,i], 0:6 ) ]
}
NiN.wetland.cov$sp <- as.factor(NiN.wetland.cov$sp)
```
This leaves us with the monitoring data including plant indicators (ANO.sp.ind) and the reference data including plant indicators (NiN.wetland.cov):
<!-- Print head of data set with horizontal scrolling -->
```{r ano-sp-tab, echo=F}
head(ANO.sp.ind) %>%
kable("html",caption = "ANO species occurence data set with attached plant trait data.") %>%
kable_styling("striped") %>% scroll_box(width = "100%")
```
```{r wetland-ref-data-tab, echo=FALSE}
head(NiN.wetland.cov) %>%
kable("html", caption = "Reference data set") %>%
kable_styling("striped") %>% scroll_box(width = "100%")
```
<br />
For each ecosystem type with a NiN species list, we can calculate a community weighted mean (CWM) for the relevant functional plant indicators.
For wetland ecosystem we are testing "Light", "Moisture", "Soil_reaction_pH", and "Nitrogen". In order to get distributions of CWMs rather than one single value (for comparison with the empirical testing data) the NiN lists can be bootstrapped.
<br />
##### Bootstrap function for frequency abundance
- function to calculate community weighted means of selected indicator values (ind)
- for species lists (sp) with given abundances in percent (or on a scale from 0 to 1) in one or more 'sites' (abun)
- with a given number of iterations (iter),
- with species given a certain minimum abundance occurring in all bootstraps (obl), and
- with a given re-sampling ratio of the original species list (rat)
- in every bootstrap iteration the abundance of the sampled species can be randomly changed by a limited amount if wished by introducing a re-sampling of abundance values from adjacent abundance steps with a certain probability (var.abun)
```{r, echo = T}
indBoot.freq <- function(sp,abun,ind,iter,obl,rat=2/3,var.abun=F) {
ind.b <- matrix(nrow=iter,ncol=length(colnames(abun)))
colnames(ind.b) <- colnames(abun)
ind.b <- as.data.frame(ind.b)
ind <- as.data.frame(ind)
ind.list <- as.list(1:length(colnames(ind)))
names(ind.list) <- colnames(ind)
for (k in 1:length(colnames(ind)) ) {
ind.list[[k]] <- ind.b }
for (j in 1:length(colnames(abun)) ) {
dat <- cbind(sp,abun[,j],ind)
dat <- dat[dat[,2]>0,] # only species that are present in the ecosystem
dat <- dat[!is.na(dat[,3]),] # only species that have indicator values
for (i in 1:iter) {
speciesSample <- sample(dat$sp[dat[,2] < obl], size=round( (length(dat$sp)-length(dat$sp[dat[,2]>=obl])) *rat,0), replace=F)
dat.b <- rbind(dat[dat[,2] >= obl,],
dat[match(speciesSample,dat$sp),]
)
if (var.abun==T) {
for (m in 1:nrow(coverscale[-1,]) ) {
xxx <- dat.b[dat.b[,2]==coverscale[-1,][m,2],2]
if ( m==1 ) { dat.b[dat.b[,2]==coverscale[-1,][m,2],2] <- sample( c(0.01,coverscale[2:7,2]), prob = c(0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0) ,size=length(xxx),replace=T) }
if ( m==2 ) { dat.b[dat.b[,2]==coverscale[-1,][m,2],2] <- sample( c(0.01,coverscale[2:7,2]), prob = c(0.2, 0.3, 0.5, 0.0, 0.0, 0.0, 0.0) ,size=length(xxx),replace=T) }
if ( m==3 ) { dat.b[dat.b[,2]==coverscale[-1,][m,2],2] <- sample( c(0.01,coverscale[2:7,2]), prob = c(0.0, 0.2, 0.3, 0.5, 0.0, 0.0, 0.0) ,size=length(xxx),replace=T) }
if ( m==4 ) { dat.b[dat.b[,2]==coverscale[-1,][m,2],2] <- sample( c(0.01,coverscale[2:7,2]), prob = c(0.0, 0.0, 0.2, 0.3, 0.5, 0.0, 0.0) ,size=length(xxx),replace=T) }
if ( m==5 ) { dat.b[dat.b[,2]==coverscale[-1,][m,2],2] <- sample( c(0.01,coverscale[2:7,2]), prob = c(0.0, 0.0, 0.0, 0.2, 0.3, 0.5, 0.0) ,size=length(xxx),replace=T) }
if ( m==6 ) { dat.b[dat.b[,2]==coverscale[-1,][m,2],2] <- sample( c(0.01,coverscale[2:7,2]), prob = c(0.0, 0.0, 0.0, 0.0, 0.2, 0.3, 0.5) ,size=length(xxx),replace=T) }
}
dat.b[!is.na(dat.b[,2]) & dat.b[,2]<=(0),2] <- 0.01
dat.b[!is.na(dat.b[,2]) & dat.b[,2]>1,2] <- 1
}
for (k in 1:length(colnames(ind))) {
if ( nrow(dat.b)>2 ) {
ind.b <- sum(dat.b[!is.na(dat.b[,2+k]),2] * dat.b[!is.na(dat.b[,2+k]),2+k] , na.rm=T) / sum(dat.b[!is.na(dat.b[,2+k]),2],na.rm=T)
ind.list[[k]][i,j] <- ind.b
} else {ind.list[[k]][i,j] <- NA}
}
# print(paste(i,"",j))
}
}
return(ind.list)
}
```
```{r}
colnames(NiN.wetland)
# 1st column is the species
# 2nd-46th column is the abundances of sp in different ecosystem types
# 47th-50th column is the indicator values of the respective species
# we choose 1000 iterations
# species with abundance 1 (i.e. a max of 100%, must be included in each sample)
# each sample re-samples 2/3 of the number of species
# the abundance of the re-sampled species may vary (see bootstrap function for details)
```
Running the bootstraps:
```{r, eval = F}
wetland.ref.cov <- indBoot.freq(sp=NiN.wetland.cov[,1],abun=NiN.wetland.cov[,2:46],ind=NiN.wetland.cov[,47:50],
iter=1000,obl=1,rat=2/3,var.abun=T)
# fixing NaNs
for (i in 1:length(wetland.ref.cov) ) {
for (j in 1:ncol(wetland.ref.cov[[i]]) ) {
v <- wetland.ref.cov[[i]][,j]
v[is.nan(v)] <- NA
wetland.ref.cov[[i]][,j] <- v
}
}
```
<!-- Please insert all the code that produces the cached data. Probably just needs to add the saveRDS() part to the code chunk above. -->
```{r, include = F}
# Data from cache
wetland.ref.cov<-readRDS(paste0(here::here(), "/data/cache/wetland.ref.cov.RDS"))
#load("/data/P-Prosjekter2/41201785_okologisk_tilstand_2022_2023/data/FPI_output large files for markdown/ref_lists_wetland.RData")
```
```{r}
head(wetland.ref.cov[[1]]) %>%
kable("html", caption = "Table showing the first 6 rows of the boostrapped data set.") %>% kable_styling("striped") %>% scroll_box(width = "100%")
```
This results in an R-list with a slot for every selected indicator, and in every slot there's a data frame with as many columns as there are NiN species lists and as many rows as there were iterations in the bootstrap.
Next, we need to derive scaling values from these bootstrap-lists (the columns) for every mapping unit in NiN. Here, we define things in the following way:
- Median = reference values
- 0.025 and 0.975 quantiles = lower and upper limit values
- min and max of the respective indicator's scale = min/max values
```{r, attr.output='style="max-height: 300px;"', results='hide'}
# every NiN-type is represented by one 'generalisert artsliste'
# some NiN-types are represented by two such species lists
# in some cases two NiN-types are represented by the same species list
head(wetland.ref.cov[[1]])
wetland.ref.cov[[1]][0,]
# checking the actual NiN-types in the wetland lists
wetland.NiNtypes <- colnames(wetland.ref.cov[["Light"]])
wetland.NiNtypes <- substr(wetland.NiNtypes,1,5)
unique(wetland.NiNtypes)
# 4 indicator-value indicators: Tyler's Light, Moisture, Soil_reaction_pH, "Nitrogen"
indEll.n=4
# creating a table to hold:
# Tyler: the 0.5 quantile (median), 0.05 quantile and 0.95 quantile for each NiN-type
# for every nature type (nrows)
tab <- matrix(ncol=3*indEll.n, nrow=length(unique(wetland.NiNtypes)) ) # 43 basic ecosystem types
# coercing the values into the table
# NiN-types where each type is represented by one species list (including when one species list represents two NiN-types)
names(wetland.ref.cov[["Light"]])
x <- c(27,28,41:45)
for (i in 1:length(x) ) {
tab[i,1:3] <- quantile(as.matrix(wetland.ref.cov[["Light"]][,x[i]]),probs=c(0.025,0.5,0.975),na.rm=T)
tab[i,4:6] <- quantile(as.matrix(wetland.ref.cov[["Moisture"]][,x[i]]),probs=c(0.025,0.5,0.975),na.rm=T)
tab[i,7:9] <- quantile(as.matrix(wetland.ref.cov[["Soil_reaction_pH"]][,x[i]]),probs=c(0.025,0.5,0.975),na.rm=T)
tab[i,10:12] <- quantile(as.matrix(wetland.ref.cov[["Nitrogen"]][,x[i]]),probs=c(0.025,0.5,0.975),na.rm=T)
}
tab <- as.data.frame(tab)
tab$NiN <- NA
tab$NiN[1:length(x)] <- names(wetland.ref.cov[[1]])[x]
# NiN-types represented by several species lists
wetland.NiNtypes2 <- wetland.NiNtypes[-x]
unique(wetland.NiNtypes2)
grep(pattern=unique(wetland.NiNtypes2)[1], x=wetland.NiNtypes) # finds columns in e.g. colnames(wetland.ref.cov[["Continentality"]]) that match the first NiN-type
for (i in 1:length(unique(wetland.NiNtypes2)) ) {
tab[length(x)+i,1:3] <- quantile(as.matrix(wetland.ref.cov[["Light"]][,grep(pattern=unique(wetland.NiNtypes2)[i], x=wetland.NiNtypes)]),probs=c(0.025,0.5,0.975),na.rm=T)
tab[length(x)+i,4:6] <- quantile(as.matrix(wetland.ref.cov[["Moisture"]][,grep(pattern=unique(wetland.NiNtypes2)[i], x=wetland.NiNtypes)]),probs=c(0.025,0.5,0.975),na.rm=T)
tab[length(x)+i,7:9] <- quantile(as.matrix(wetland.ref.cov[["Soil_reaction_pH"]][,grep(pattern=unique(wetland.NiNtypes2)[i], x=wetland.NiNtypes)]),probs=c(0.025,0.5,0.975),na.rm=T)
tab[length(x)+i,10:12] <- quantile(as.matrix(wetland.ref.cov[["Nitrogen"]][,grep(pattern=unique(wetland.NiNtypes2)[i], x=wetland.NiNtypes)]),probs=c(0.025,0.5,0.975),na.rm=T)
tab$NiN[length(x)+i] <- unique(wetland.NiNtypes2)[i]
}
tab
# making it a proper data frame
round(tab[,1:12],digits=2)
colnames(tab) <- c("Light_q2.5","Light_q50","Light_q97.5",
"Moist_q2.5","Moist_q50","Moist_q97.5",
"pH_q2.5","pH_q50","pH_q97.5",
"Nitrogen_q2.5","Nitrogen_q50","Nitrogen_q97.5",
"NiN")
summary(tab)
tab$NiN <- gsub("C", "C-", tab$NiN) # add extra hyphon after C for NiN-types
tab
# restructuring into separate indicators for lower (q2.5) and higher (q97.5) than reference value (=median, q50)
y.Light <- numeric(length=nrow(tab)*2)
y.Light[((1:dim(tab)[1])*2)-1] <- tab$Light_q2.5
y.Light[((1:dim(tab)[1])*2)] <- tab$Light_q97.5
y.Moist <- numeric(length=nrow(tab)*2)
y.Moist[((1:dim(tab)[1])*2)-1] <- tab$Moist_q2.5
y.Moist[((1:dim(tab)[1])*2)] <- tab$Moist_q97.5
y.pH <- numeric(length=nrow(tab)*2)
y.pH[((1:dim(tab)[1])*2)-1] <- tab$pH_q2.5
y.pH[((1:dim(tab)[1])*2)] <- tab$pH_q97.5
y.Nitrogen <- numeric(length=nrow(tab)*2)
y.Nitrogen[((1:dim(tab)[1])*2)-1] <- tab$Nitrogen_q2.5
y.Nitrogen[((1:dim(tab)[1])*2)] <- tab$Nitrogen_q97.5
# creating final objects holding the reference and limit values for all indicators
# ref object for indicators
wetland.ref.cov.val <- data.frame(N1=rep('wetland',(nrow(tab)*2*indEll.n)),
hoved=c(rep('NA',(nrow(tab)*2*indEll.n))),
grunn=c(rep(rep(tab$NiN,each=2),indEll.n)),
county=rep('all',(nrow(tab)*2*indEll.n)),
region=rep('all',(nrow(tab)*2*indEll.n)),
Ind=c(rep(c('Light1','Light2'),nrow(tab)),
rep(c('Moist1','Moist2'),nrow(tab)),
rep(c('pH1','pH2'),nrow(tab)),
rep(c('Nitrogen1','Nitrogen2'),nrow(tab))
),
Rv=c(rep(tab$Light_q50,each=2),
rep(tab$Moist_q50,each=2),
rep(tab$pH_q50,each=2),
rep(tab$Nitrogen_q50,each=2)
),
Gv=c(y.Light,y.Moist,y.pH,y.Nitrogen),
maxmin=c(rep(c(1,7),nrow(tab)), # 7 levels of light
rep(c(1,12),nrow(tab)), # 12 levels of moisture
rep(c(1,8),nrow(tab)), # 8 levels of soil reaction pH
rep(c(1,9),nrow(tab)) # 9 levels of nitrogen
)
)
wetland.ref.cov.val
wetland.ref.cov.val$grunn <- as.factor(wetland.ref.cov.val$grunn)
wetland.ref.cov.val$Ind <- as.factor(wetland.ref.cov.val$Ind)
summary(wetland.ref.cov.val)
```
```{r}
wetland.ref.cov.val %>%
kable("html", caption = "Reference values (Rv and threshold values (Gv) for each indicator and nature type combination") %>% kable_styling("striped") %>% scroll_box(width = "100%", height = "300px")
```
Once test data (ANO) and the scaling values from the reference data (NiN) are in place, we can calculate CWMs of the selected indicators for the ANO community data and scale them against the scaling values from the reference distribution. Note that we scale each ANO plot's CWM against either the lower threshold value and the min value OR the upper threshold value and the max value based on whether the CWM is smaller or higher than the reference value. Since the scaled values for both sides range between 0 and 1, we generate separate lower and upper indicators for each plant functional indicator type. An ANO plot can only have a scaled value in either the lower or the upper indicator (the other one will be 'NA'), except for the unlikely event that the CWM exactly matches the reference value, in which case both lower and upper indicator will receive a scaled indicator value of 1.
Here is the scaling function:
```{r}
#### scaled values ####
r.s <- 1 # reference value
l.s <- 0.6 # limit value
a.s <- 0 # abscence of indicator, or indicator at maximum
#### function for calculating scaled values for measured value ####
## scaling function including truncation
scal <- function() {
# place to hold the result
x <- numeric()
if (maxmin < ref) {
# values >= the reference value equal 1
if (val >= ref) {x <- 1}
# values < the reference value and >= the limit value can be deducted from the linear relationship between these two
if (val < ref & val >= lim) {x <- (l.s + (val-lim) * ( (r.s-l.s) / (ref-lim) ) )}
# values < the limit value and > maxmin can be deducted from the linear relationship between these two
if (val < lim & val > maxmin) {x <- (a.s + (val-maxmin) * ( (l.s-a.s) / (lim-maxmin) ) )}
# value equals or lower than maxmin
if (val <= maxmin) {x <-0}
} else {
# values <= the reference value equal 1
if (val <= ref) {x <- 1}
# values > the reference value and <= the limit value can be deducted from the linear relationship between these two
if (val > ref & val <= lim) {x <- ( r.s - ( (r.s - l.s) * (val - ref) / (lim - ref) ) )}
# values > the limit value and < maxmin can be deducted from the linear relationship between these two
if (val > lim) {x <- ( l.s - (l.s * (val - lim) / (maxmin - lim) ) )}
# value equals or larger than maxmin
if (val >= maxmin) {x <-0}
}
return(x)
}
```
We then can prepare a list of data frames to hold the results and perform the scaling according to the principles described in NINA report 1967 (Töpper and Jakobsson 2021).
```{r, results='hide'}
unique(ANO.geo$hovedtype_rute) # NiN types in data
unique(substr(wetland.ref.cov.val$grunn,1,2)) # NiN types in reference
#### creating dataframe to hold the results for wetlands ####
# all ANO points
nrow(ANO.geo)
# all wetland ANO points
nrow(ANO.geo[ANO.geo$hovedtype_rute %in% list("V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13"),])
# all wetland ANO points with a NiN-type represented in the reference
nrow(ANO.geo[ANO.geo$hovedtype_rute %in% unique(substr(wetland.ref.cov.val$grunn,1,2)),])
# ok, we'll be losing 70 (our of 1349) that are not covered by the reference
ANO.wetland <- ANO.geo[ANO.geo$hovedtype_rute %in% list("V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13"),]
head(ANO.wetland)
# update row-numbers
row.names(ANO.wetland) <- 1:nrow(ANO.wetland)
head(ANO.wetland)
dim(ANO.wetland)
colnames(ANO.wetland)
length(levels(as.factor(ANO.wetland$ano_flate_id)))
length(levels(as.factor(ANO.wetland$ano_punkt_id)))
summary(as.factor(ANO.wetland$ano_punkt_id))
# four points that are double
ANO.wetland[ANO.wetland$ano_punkt_id=="ANO0159_55",] # double registration, said so in comment. -> choose row 207 over 206
ANO.wetland <- ANO.wetland[-206,]
row.names(ANO.wetland) <- 1:nrow(ANO.wetland) # update row-numbers
ANO.wetland[ANO.wetland$ano_punkt_id=="ANO0283_22",] # 2019 & 2021. Lot of NA's in 2019 -> omit 2019
ANO.wetland <- ANO.wetland[-156,]
row.names(ANO.wetland) <- 1:nrow(ANO.wetland) # update row-numbers