Last updated: 2021-04-09
Checks: 7 0
Knit directory: RainDrop_biodiversity/
This reproducible R Markdown analysis was created with workflowr (version 1.6.2). The Checks tab describes the reproducibility checks that were applied when the results were created. The Past versions tab lists the development history.
Great! Since the R Markdown file has been committed to the Git repository, you know the exact version of the code that produced these results.
Great job! The global environment was empty. Objects defined in the global environment can affect the analysis in your R Markdown file in unknown ways. For reproduciblity it’s best to always run the code in an empty environment.
The command set.seed(20210406)
was run prior to running the code in the R Markdown file. Setting a seed ensures that any results that rely on randomness, e.g. subsampling or permutations, are reproducible.
Great job! Recording the operating system, R version, and package versions is critical for reproducibility.
Nice! There were no cached chunks for this analysis, so you can be confident that you successfully produced the results during this run.
Great job! Using relative paths to the files within your workflowr project makes it easier to run your code on other machines.
Great! You are using Git for version control. Tracking code development and connecting the code version to the results is critical for reproducibility.
The results in this page were generated with repository version 1e1c114. See the Past versions tab to see a history of the changes made to the R Markdown and HTML files.
Note that you need to be careful to ensure that all relevant files for the analysis have been committed to Git prior to generating the results (you can use wflow_publish
or wflow_git_commit
). workflowr only checks the R Markdown file, but you know if there are other scripts or data files that it depends on. Below is the status of the Git repository when the results were generated:
Ignored files:
Ignored: .Rhistory
Ignored: .Rproj.user/
Ignored: analysis/site_libs/
Unstaged changes:
Deleted: analysis/about.Rmd
Note that any generated files, e.g. HTML, png, CSS, etc., are not included in this status report because it is ok for generated content to have uncommitted changes.
These are the previous versions of the repository in which changes were made to the R Markdown (analysis/exploratory_analysis.Rmd
) and HTML (docs/exploratory_analysis.html
) files. If you’ve configured a remote Git repository (see ?wflow_git_remote
), click on the hyperlinks in the table below to view the files as they were in that past version.
File | Version | Author | Date | Message |
---|---|---|---|---|
Rmd | 1e1c114 | jjackson-eco | 2021-04-09 | Adding species diversity |
html | cc963a5 | jjackson-eco | 2021-04-08 | Build site. |
Rmd | b427f16 | jjackson-eco | 2021-04-08 | exploration update 2 |
html | 104d3f2 | jjackson-eco | 2021-04-08 | Build site. |
Rmd | 0faa75d | jjackson-eco | 2021-04-08 | exploration update |
html | c69c14a | jjackson-eco | 2021-04-08 | Build site. |
Rmd | f8308af | jjackson-eco | 2021-04-08 | exploration for biomass |
html | 7a899b4 | jjackson-eco | 2021-04-07 | Build site. |
Rmd | 9381cc9 | jjackson-eco | 2021-04-07 | wflow_publish(files = c(“README.md”, "analysis/_site.yml“,”analysis/exploratory_analysis.Rmd", |
Here we present some exploratory analysis and plots investigating general patterns in the two biodiversity measures estimated at the RainDrop site as part of the Drought-Net experiment, above-ground biomass (biomass
) and species diversity (percent_cover
).
First some housekeeping. We’ll start by loading the necessary packages for exploring the data, the data itself and then specifying the colour palette for the treatments.
# packages
library(tidyverse)
library(patchwork)
library(vegan)
# load data
load("../../RainDropRobotics/Data/raindrop_biodiversity_2016_2020.RData",
verbose = TRUE)
Loading objects:
biomass
percent_cover
# colours
raindrop_colours <-
tibble(treatment = c("Ambient", "Control", "Drought", "Irrigated"),
num = rep(100,4),
colour = c("#61D94E", "#BFBFBF", "#EB8344", "#6ECCFF"))
ggplot(raindrop_colours, aes(x = treatment, y = num, fill = treatment)) +
geom_col() +
geom_text(aes(label = colour, x = treatment, y = 50), size = 3) +
scale_fill_manual(values = raindrop_colours$colour) +
theme_void()
Here, cuttings of 1m x 0.25m strips (from ~1cm above the ground) from each treatment and block are sorted by functional group and after drying at 70\(^\circ\)C for over 48 hours their dry mass is weighed in grams. Measurements occur twice per year- one harvest in June in the middle of the growing season and one and in September at the end of the growing season.
Here a summary of the data:
glimpse(biomass)
Rows: 1,199
Columns: 6
$ year <dbl> 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, ~
$ harvest <chr> "Mid", "Mid", "Mid", "Mid", "Mid", "Mid", "Mid", "Mid", "Mid~
$ block <chr> "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", ~
$ treatment <chr> "Ambient", "Ambient", "Ambient", "Ambient", "Ambient", "Ambi~
$ group <chr> "Bryophytes", "Dead", "Forbs", "Graminoids", "Legumes", "Woo~
$ biomass_g <dbl> 0.7, 4.5, 16.5, 49.7, 7.7, 0.0, 0.3, 2.4, 20.0, 46.7, 3.6, 1~
Let us first have a look at the response variable biomass_g
. We’ll remove any zero observations of biomass. If we plot out the frequency histogram of the raw data, we can see there is some strong positive skew in this variable, because of the differences in biomass scale between our functional groups (i.e. grasses very over-represented).
biomass <- biomass %>%
filter(biomass_g > 0)
ggplot(biomass, aes(x = biomass_g)) +
geom_histogram(bins = 20) +
labs(x = "Above-ground biomass (g)", y = "Frequency") +
theme_bw(base_size = 14) +
theme(panel.grid = element_blank())
So, instead, for statistical analysis and visualisation, we take the natural logarithm \(\ln\) of the raw biomass value.
biomass <- biomass %>%
mutate(biomass_log = log(biomass_g))
ggplot(biomass, aes(x = biomass_log)) +
geom_histogram(bins = 20) +
labs(x = expression(paste(ln," Above-ground biomass")), y = "Frequency") +
theme_bw(base_size = 14) +
theme(panel.grid = element_blank())
Using the ln biomass variable, we can explore patterns relating to our drought treatments, functional groups, temporal patterns and any potential block effects.
The first interesting question to explore is how biomass overall, which indicates primary productivity, is affected by the rainfall treatments. Here we need to sum up the biomass across functional groups. We again look at the \(\ln\) total biomass too. We present here the density plots (violins) with median (total biomass) and mean (\(\ln\) total biomass) points (large holes) as well as underlying raw data (small points).
totbiomass <- biomass %>%
group_by(year, harvest, block, treatment) %>%
summarise(tot_biomass = sum(biomass_g),
log_tot_biomass = log(tot_biomass)) %>%
ungroup()
And now we can look at how this is affected by the rainfall treatments.
tb_1 <- totbiomass %>%
ggplot(aes(x = treatment, y = tot_biomass,
fill = treatment)) +
geom_violin() +
stat_summary(fun = median, geom = "point",
size = 6, shape = 21, fill = "white") +
geom_jitter(width = 0.1, alpha = 0.4, size = 1) +
scale_fill_manual(values = raindrop_colours$colour,
guide = F) +
labs(x = "Rainfall treatment", y = "Total above-ground biomass (g)") +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank())
tb_2 <- totbiomass %>%
ggplot(aes(x = treatment, y = log_tot_biomass,
fill = treatment)) +
geom_violin() +
stat_summary(fun = mean, geom = "point",
size = 6, shape = 21, fill = "white") +
geom_jitter(width = 0.1, alpha = 0.4, size = 1)+
scale_fill_manual(values = raindrop_colours$colour,
guide = F) +
labs(x = "Rainfall treatment",
y = expression(paste(ln, " Total above-ground biomass"))) +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank())
tb_1 + tb_2
Across all functional groups, years and blocks, it looks like there is a reduction in total biomass associated with the drought treatment.
Now we’ll look at potential temporal effects i.e. whether there is a change in total biomass over time. We first have to add in temporal information to the year and harvest columns, and then we can plot out the total biomass.
# adding temporal information
totbiomass <- totbiomass %>%
mutate(month = if_else(harvest == "End", 9, 6),
date = as.Date(paste0(year,"-",month,"-15")),
harvest = factor(harvest, levels = c("Mid", "End")))
# plots
totbiomass %>%
ggplot(aes(x = date, y = log_tot_biomass, colour = treatment,
group = treatment, shape = harvest)) +
stat_summary(geom = "line", fun = mean, size = 0.9) +
stat_summary(geom = "point", fun = mean, size = 3) +
scale_colour_manual(values = raindrop_colours$colour) +
labs(x = "Year", y = expression(paste("Mean ", ln, " total biomass")),
colour = "Treatment", shape = "Harvest") +
theme_bw(base_size = 14) +
theme(panel.grid = element_blank())
And also splitting out the harvests, as the end of the growing season has lower biomass
totbiomass %>%
ggplot(aes(x = year, y = log_tot_biomass, colour = treatment,
group = treatment)) +
stat_summary(geom = "line", fun = mean, size = 0.9) +
stat_summary(geom = "point", fun = mean, size = 3) +
scale_colour_manual(values = raindrop_colours$colour) +
labs(x = "Year", y = expression(paste("Mean ", ln, " total biomass")),
colour = "Treatment") +
facet_wrap(~harvest) +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
strip.background = element_blank())
It looks like there may have been declines in total biomass over the years (perhaps reflecting wider climatic patterns?), but this also seems to be more prominent in the drought treatment.
Finally for total biomass, we want to look if we have any evidence for block effects at the experimental site. Here we will repeat the first treatment violin plot, but splitting by block. Here each violin is a different block (A-E from left to right) with the 50% quantile.
totbiomass %>%
ggplot(aes(x = treatment, y = log_tot_biomass,
fill = treatment,
group = interaction(treatment, block))) +
geom_violin(draw_quantiles = 0.5) +
scale_fill_manual(values = raindrop_colours$colour,
guide = F) +
labs(x = "Rainfall treatment",
y = expression(paste(ln, " Total above-ground biomass"))) +
theme_bw(base_size = 14) +
theme(panel.grid = element_blank())
It seems that largely blocks are consistent across the RainDrop site.
Now we can go a little further and look at whether we observe any differences in biomass between different functional groups, which occur at different proportions. First, lets look at the overall differences in biomass, or relative biomass, between functional groups.
biomass %>%
ggplot(aes(x = group, y = biomass_log,
fill = group)) +
geom_violin() +
stat_summary(fun = mean, geom = "point",
size = 5, shape = 21, fill = "white") +
geom_jitter(width = 0.15, alpha = 0.2, size = 1) +
scale_fill_brewer(palette = "Set2", guide = F) +
labs(x = "Functional group",
y = expression(paste(ln, " Above-ground biomass"))) +
theme_bw(base_size = 14) +
theme(panel.grid = element_blank())
We can see that there is a large representation (as expected) of Graminoids, and lower representation of Woody species and Bryophytes.
Now lets look at the rainfall treatments by functional group.
biomass %>%
ggplot(aes(x = treatment, y = biomass_log,
fill = treatment)) +
geom_violin() +
stat_summary(fun = mean, geom = "point",
size = 5, shape = 21, fill = "white") +
geom_jitter(width = 0.15, alpha = 0.2, size = 1) +
scale_fill_manual(values = raindrop_colours$colour,
guide = F) +
labs(x = "Rainfall treatment",
y = expression(paste(ln, " Above-ground biomass"))) +
facet_wrap(~ group, ncol = 2) +
theme_bw(base_size = 22) +
theme(panel.grid = element_blank(),
strip.background = element_blank())
It isn’t as clear hear as total biomass. However, for the group with the most representation, the Graminoids, this reduction in the drought treatment looks to be maintained.
Finally we can look at whether there are differences in the temporal patterns between the functional groups.
# adding temporal information
biomass <- biomass %>%
mutate(month = if_else(harvest == "End", 9, 6),
date = as.Date(paste0(year,"-",month,"-15")),
harvest = factor(harvest, levels = c("Mid", "End")))
# plot
biomass %>%
ggplot(aes(x = date, y = biomass_log, colour = treatment,
group = treatment, shape = harvest)) +
stat_summary(geom = "line", fun = mean, size = 0.9) +
stat_summary(geom = "point", fun = mean, size = 3) +
scale_colour_manual(values = raindrop_colours$colour) +
facet_wrap(~group) +
labs(x = "Year", y = expression(paste(ln, " Above-ground biomass")),
colour = "Treatment", shape = "Harvest") +
theme_bw(base_size = 22) +
theme(panel.grid = element_blank(),
strip.background = element_blank())
Again, specific patterns are hard to discern here, but it looks like biomass is decreasing slightly again in general.
The species diversity data is in in the form of percentage cover of individually id’ species in a 1m x 1m quadrant in the center of each experimental plot. These percentage cover measurements were generally made at the peak of the growing season (June), but in 2016 there were recordings in both June and September.
Here a summary of the data:
glimpse(percent_cover)
Rows: 2,956
Columns: 8
$ year <dbl> 2018, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, 20~
$ month <chr> "June", "June", "June", "June", "June", "June", "June", ~
$ block <chr> "C", "B", "B", "C", "E", "A", "E", "C", "D", "B", "D", "~
$ treatment <chr> "Control", "Ambient", "Control", "Irrigated", "Control",~
$ species_level <chr> "No", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "~
$ species <chr> "Acer_sp", "Agrimonia_eupatoria", "Agrimonia_eupatoria",~
$ plant_type <chr> NA, "Forb", "Forb", "Forb", "Forb", "Forb", "Forb", "For~
$ percent_cover <dbl> 1.0, 1.0, 2.0, 4.0, 4.0, 5.0, 5.0, 7.0, 8.0, 10.0, 15.0,~
For the purpose of analysis here, we are interested in species diversity, and so we only want to include observations for which we have species-level data. Also, we want to clean any NA observations.
percent_cover <- percent_cover %>%
drop_na(percent_cover) %>%
filter(species_level == "Yes")
Our first key question regarding the percentage cover is how the rainfall treatments are influencing the community diversity of the plots. For this we will calculate some key biodiversity indices:
where \(p_i\) is the relative proportion of type (here species) \(i\).
Here we calculate these diversity indices for each plot (i.e. each year, month, block, treatment combination)
diversity <- percent_cover %>%
# first convert percentages to a proportion
mutate(proportion = percent_cover/100) %>%
group_by(year, month, block, treatment) %>%
# diversity indices for each group
summarise(richness = n(),
simpsons = sum(proportion^2),
shannon = -sum(proportion * log(proportion))) %>%
ungroup() %>%
pivot_longer(cols = c(richness, simpsons, shannon),
names_to = "index") %>%
mutate(index_lab = case_when(
index == "richness" ~ "Species richness",
index == "simpsons" ~ "Simpson's index",
index == "shannon" ~ "Shannon-Wiener index"
))
Now we can explore how the diversity indices for each plot are related to the experimental treatments, temporal patterns, and any block effects.
First the treatment effects
diversity %>%
ggplot(aes(x = treatment, y = value,
fill = treatment)) +
geom_violin() +
stat_summary(fun = mean, geom = "point",
size = 6, shape = 21, fill = "white") +
geom_jitter(width = 0.1, alpha = 0.4, size = 1) +
scale_fill_manual(values = raindrop_colours$colour,
guide = F) +
labs(x = "Rainfall treatment", y = "Species diverity index") +
facet_wrap(~index_lab, ncol = 1, scales = "free") +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
strip.background = element_blank())
There isn’t a clear pattern here. But interestingly, it actually looks like for Shannon-Wiener, diversity is greatest in the drought treatment.
And now for potential temporal patterns
diversity %>%
mutate(month = if_else(month == "June", 6, 9),
date = as.Date(paste0(year,"-",month,"-15"))) %>%
ggplot(aes(x = date, y = value, colour = treatment)) +
stat_summary(geom = "line", fun = mean, size = 0.9) +
stat_summary(geom = "point", fun = mean, size = 3) +
scale_colour_manual(values = raindrop_colours$colour) +
labs(x = "Year", y = "Mean diversity index", colour = "Treatment") +
facet_wrap(~ index_lab, scales = "free", ncol = 1) +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
strip.background = element_blank())
Again clear patterns are not sticking out with general indices. And finally we explore any potential block effects
diversity %>%
ggplot(aes(x = treatment, y = value,
fill = treatment,
group = interaction(treatment, block))) +
geom_violin(draw_quantiles = 0.5) +
scale_fill_manual(values = raindrop_colours$colour,
guide = F) +
labs(x = "Rainfall treatment",
y = "Species diversity index") +
facet_wrap(~ index_lab, scales = "free", ncol = 1) +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
strip.background = element_blank())
While there may not be overall patterns in species diversity, what is interesting whether there are shifts to community structure. So, here we can perform a simple non-metric multidimensional scaling (NMDS) analysis, to look at changes to community structure with our treatments, general plant types, and also whether there are key species.
Here we perform the NMDS analysis using the vegan
package, with two dimensions for 122 species in total and using the default bray distances. Firstly some cleaning though, to convert the percent cover data to a species by sample (our plots) matrix.
# data frame of the community matrix
species_community_df <- percent_cover %>%
mutate(sample = paste(month, year, block, treatment, sep = "_")) %>%
filter(species_level == "Yes") %>%
dplyr::select(sample, species, percent_cover) %>%
pivot_wider(id_cols = sample, names_from = species, values_from = percent_cover,
values_fill = 0)
# convert to a matrix
species_community_mat <- as.matrix(species_community_df[,2:123])
rownames(species_community_mat) <- species_community_df$sample
# have a look
glimpse(species_community_mat)
num [1:120, 1:122] 1 2 4 4 5 5 7 8 10 15 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:120] "June_2016_B_Ambient" "June_2016_B_Control" "June_2016_C_Irrigated" "June_2016_E_Control" ...
..$ : chr [1:122] "Agrimonia_eupatoria" "Agrimonia_eupatorium" "Agrostis_capillaris" "Agrostis_stolonifera" ...
# the NMDS
raindrop_NMDS <- metaMDS(species_community_mat, k = 2, trymax = 500)
Square root transformation
Wisconsin double standardization
Run 0 stress 0.2767962
Run 1 stress 0.277602
Run 2 stress 0.2932021
Run 3 stress 0.2853559
Run 4 stress 0.2978406
Run 5 stress 0.2955674
Run 6 stress 0.2770975
... Procrustes: rmse 0.02702161 max resid 0.2110902
Run 7 stress 0.2961353
Run 8 stress 0.2805795
Run 9 stress 0.3132602
Run 10 stress 0.2992073
Run 11 stress 0.2816689
Run 12 stress 0.286314
Run 13 stress 0.2841294
Run 14 stress 0.2867314
Run 15 stress 0.3167791
Run 16 stress 0.2846884
Run 17 stress 0.3013173
Run 18 stress 0.2769089
... Procrustes: rmse 0.03336828 max resid 0.283892
Run 19 stress 0.2839498
Run 20 stress 0.2758683
... New best solution
... Procrustes: rmse 0.01609963 max resid 0.1033264
Run 21 stress 0.2825197
Run 22 stress 0.2849962
Run 23 stress 0.2825475
Run 24 stress 0.2769696
Run 25 stress 0.2826515
Run 26 stress 0.2870934
Run 27 stress 0.2861942
Run 28 stress 0.2787106
Run 29 stress 0.2806181
Run 30 stress 0.2970536
Run 31 stress 0.2853741
Run 32 stress 0.2870647
Run 33 stress 0.2827175
Run 34 stress 0.3162331
Run 35 stress 0.2939082
Run 36 stress 0.2814939
Run 37 stress 0.281456
Run 38 stress 0.2863874
Run 39 stress 0.2824177
Run 40 stress 0.2767683
Run 41 stress 0.2769162
Run 42 stress 0.2947656
Run 43 stress 0.4135299
Run 44 stress 0.2831778
Run 45 stress 0.2824217
Run 46 stress 0.3100015
Run 47 stress 0.2837495
Run 48 stress 0.2803849
Run 49 stress 0.2761917
... Procrustes: rmse 0.01950759 max resid 0.1959354
Run 50 stress 0.2844196
Run 51 stress 0.276545
Run 52 stress 0.2768445
Run 53 stress 0.280588
Run 54 stress 0.2766072
Run 55 stress 0.2850416
Run 56 stress 0.2898506
Run 57 stress 0.2939252
Run 58 stress 0.2813066
Run 59 stress 0.2776316
Run 60 stress 0.2854541
Run 61 stress 0.286179
Run 62 stress 0.2788558
Run 63 stress 0.2760823
... Procrustes: rmse 0.02841787 max resid 0.2148264
Run 64 stress 0.2951946
Run 65 stress 0.291162
Run 66 stress 0.2769294
Run 67 stress 0.2759591
... Procrustes: rmse 0.02819276 max resid 0.2160721
Run 68 stress 0.2816072
Run 69 stress 0.2817325
Run 70 stress 0.2993286
Run 71 stress 0.2823217
Run 72 stress 0.3138409
Run 73 stress 0.2756409
... New best solution
... Procrustes: rmse 0.006688926 max resid 0.05479494
Run 74 stress 0.2857355
Run 75 stress 0.2834664
Run 76 stress 0.2834251
Run 77 stress 0.2954893
Run 78 stress 0.286071
Run 79 stress 0.2884071
Run 80 stress 0.3051241
Run 81 stress 0.2816083
Run 82 stress 0.2829201
Run 83 stress 0.3141665
Run 84 stress 0.2783938
Run 85 stress 0.2818005
Run 86 stress 0.2831755
Run 87 stress 0.2763259
Run 88 stress 0.2888579
Run 89 stress 0.3062602
Run 90 stress 0.2856563
Run 91 stress 0.2895439
Run 92 stress 0.275793
... Procrustes: rmse 0.02787599 max resid 0.2133164
Run 93 stress 0.2856758
Run 94 stress 0.292898
Run 95 stress 0.2863794
Run 96 stress 0.2764144
Run 97 stress 0.2774566
Run 98 stress 0.2990053
Run 99 stress 0.286001
Run 100 stress 0.2800643
Run 101 stress 0.2995309
Run 102 stress 0.2854035
Run 103 stress 0.313981
Run 104 stress 0.2802067
Run 105 stress 0.2769166
Run 106 stress 0.2871338
Run 107 stress 0.301517
Run 108 stress 0.2813973
Run 109 stress 0.2803757
Run 110 stress 0.2825412
Run 111 stress 0.2819544
Run 112 stress 0.3106356
Run 113 stress 0.2857158
Run 114 stress 0.28054
Run 115 stress 0.2847235
Run 116 stress 0.2963966
Run 117 stress 0.2764471
Run 118 stress 0.2916034
Run 119 stress 0.2862926
Run 120 stress 0.2822926
Run 121 stress 0.2854575
Run 122 stress 0.2837994
Run 123 stress 0.2888163
Run 124 stress 0.2937464
Run 125 stress 0.2752022
... New best solution
... Procrustes: rmse 0.01839457 max resid 0.1949325
Run 126 stress 0.2782642
Run 127 stress 0.2903909
Run 128 stress 0.2849397
Run 129 stress 0.277819
Run 130 stress 0.2917427
Run 131 stress 0.2928313
Run 132 stress 0.3075153
Run 133 stress 0.2837128
Run 134 stress 0.2818714
Run 135 stress 0.3225496
Run 136 stress 0.2945228
Run 137 stress 0.3009094
Run 138 stress 0.2869416
Run 139 stress 0.2864973
Run 140 stress 0.2871134
Run 141 stress 0.2756778
... Procrustes: rmse 0.01598282 max resid 0.1684395
Run 142 stress 0.2896974
Run 143 stress 0.2817277
Run 144 stress 0.2763396
Run 145 stress 0.2856764
Run 146 stress 0.285556
Run 147 stress 0.3037158
Run 148 stress 0.2832145
Run 149 stress 0.3136607
Run 150 stress 0.2773844
Run 151 stress 0.2832705
Run 152 stress 0.2757909
Run 153 stress 0.276911
Run 154 stress 0.2761916
Run 155 stress 0.2753927
... Procrustes: rmse 0.004412328 max resid 0.0278875
Run 156 stress 0.2815538
Run 157 stress 0.2839197
Run 158 stress 0.2776063
Run 159 stress 0.2856053
Run 160 stress 0.2909764
Run 161 stress 0.2824001
Run 162 stress 0.2945936
Run 163 stress 0.2851243
Run 164 stress 0.2952075
Run 165 stress 0.2937954
Run 166 stress 0.2821778
Run 167 stress 0.289577
Run 168 stress 0.3101815
Run 169 stress 0.2899911
Run 170 stress 0.2851066
Run 171 stress 0.2920318
Run 172 stress 0.2955044
Run 173 stress 0.2873532
Run 174 stress 0.2826145
Run 175 stress 0.2831905
Run 176 stress 0.2825163
Run 177 stress 0.2819337
Run 178 stress 0.2761917
Run 179 stress 0.293661
Run 180 stress 0.2909376
Run 181 stress 0.2966224
Run 182 stress 0.2948812
Run 183 stress 0.2902538
Run 184 stress 0.2759996
Run 185 stress 0.2883574
Run 186 stress 0.2843423
Run 187 stress 0.3000871
Run 188 stress 0.2964049
Run 189 stress 0.2876698
Run 190 stress 0.2807912
Run 191 stress 0.2866172
Run 192 stress 0.2850386
Run 193 stress 0.2768287
Run 194 stress 0.2769162
Run 195 stress 0.2914567
Run 196 stress 0.2833897
Run 197 stress 0.2853156
Run 198 stress 0.2802875
Run 199 stress 0.2820744
Run 200 stress 0.2761915
Run 201 stress 0.2831963
Run 202 stress 0.2831736
Run 203 stress 0.2767927
Run 204 stress 0.2774054
Run 205 stress 0.2756942
... Procrustes: rmse 0.01598043 max resid 0.1670758
Run 206 stress 0.2777929
Run 207 stress 0.2931061
Run 208 stress 0.2844497
Run 209 stress 0.2852446
Run 210 stress 0.2783617
Run 211 stress 0.2999261
Run 212 stress 0.2956568
Run 213 stress 0.2821161
Run 214 stress 0.2754694
... Procrustes: rmse 0.006474131 max resid 0.05279246
Run 215 stress 0.2921575
Run 216 stress 0.2831807
Run 217 stress 0.2918956
Run 218 stress 0.2851382
Run 219 stress 0.2858284
Run 220 stress 0.2933459
Run 221 stress 0.2855018
Run 222 stress 0.2816954
Run 223 stress 0.2812924
Run 224 stress 0.2817054
Run 225 stress 0.2923533
Run 226 stress 0.2841288
Run 227 stress 0.2904194
Run 228 stress 0.2813527
Run 229 stress 0.2839412
Run 230 stress 0.2815432
Run 231 stress 0.2769522
Run 232 stress 0.2797161
Run 233 stress 0.2868148
Run 234 stress 0.2788169
Run 235 stress 0.2758682
Run 236 stress 0.2878844
Run 237 stress 0.2818175
Run 238 stress 0.2802102
Run 239 stress 0.2903001
Run 240 stress 0.2852655
Run 241 stress 0.2829224
Run 242 stress 0.2883752
Run 243 stress 0.4131698
Run 244 stress 0.3148125
Run 245 stress 0.2878972
Run 246 stress 0.2809798
Run 247 stress 0.280497
Run 248 stress 0.2768593
Run 249 stress 0.2912055
Run 250 stress 0.2758684
Run 251 stress 0.2999398
Run 252 stress 0.282178
Run 253 stress 0.2870254
Run 254 stress 0.275199
... New best solution
... Procrustes: rmse 0.001180725 max resid 0.01078959
Run 255 stress 0.3084651
Run 256 stress 0.2827973
Run 257 stress 0.3013574
Run 258 stress 0.2756295
... Procrustes: rmse 0.007690206 max resid 0.05152554
Run 259 stress 0.2852168
Run 260 stress 0.2819611
Run 261 stress 0.30995
Run 262 stress 0.2902704
Run 263 stress 0.2819535
Run 264 stress 0.2825163
Run 265 stress 0.2803926
Run 266 stress 0.285498
Run 267 stress 0.2874139
Run 268 stress 0.2760015
Run 269 stress 0.294528
Run 270 stress 0.2892038
Run 271 stress 0.2757909
Run 272 stress 0.2897887
Run 273 stress 0.3042521
Run 274 stress 0.2841449
Run 275 stress 0.308743
Run 276 stress 0.2853573
Run 277 stress 0.2823228
Run 278 stress 0.2824113
Run 279 stress 0.2939282
Run 280 stress 0.2811827
Run 281 stress 0.2754026
... Procrustes: rmse 0.005491697 max resid 0.03938792
Run 282 stress 0.280312
Run 283 stress 0.2853019
Run 284 stress 0.2993653
Run 285 stress 0.2848496
Run 286 stress 0.2835985
Run 287 stress 0.2759896
Run 288 stress 0.2756956
... Procrustes: rmse 0.01607401 max resid 0.1673164
Run 289 stress 0.2836377
Run 290 stress 0.2783561
Run 291 stress 0.2965925
Run 292 stress 0.2842897
Run 293 stress 0.2753913
... Procrustes: rmse 0.005077171 max resid 0.03917087
Run 294 stress 0.2769208
Run 295 stress 0.2826611
Run 296 stress 0.2836992
Run 297 stress 0.288379
Run 298 stress 0.2783109
Run 299 stress 0.2906245
Run 300 stress 0.2925783
Run 301 stress 0.2833795
Run 302 stress 0.2788488
Run 303 stress 0.2804165
Run 304 stress 0.2768885
Run 305 stress 0.2921951
Run 306 stress 0.2817128
Run 307 stress 0.2842166
Run 308 stress 0.2816443
Run 309 stress 0.2799539
Run 310 stress 0.2761916
Run 311 stress 0.2905186
Run 312 stress 0.2792492
Run 313 stress 0.2764148
Run 314 stress 0.2768102
Run 315 stress 0.2767552
Run 316 stress 0.2757909
Run 317 stress 0.2825181
Run 318 stress 0.2827509
Run 319 stress 0.2937944
Run 320 stress 0.2756779
... Procrustes: rmse 0.01601981 max resid 0.1691432
Run 321 stress 0.280515
Run 322 stress 0.2812731
Run 323 stress 0.2796134
Run 324 stress 0.2822521
Run 325 stress 0.288614
Run 326 stress 0.287689
Run 327 stress 0.2815311
Run 328 stress 0.2893268
Run 329 stress 0.307549
Run 330 stress 0.2817905
Run 331 stress 0.2925788
Run 332 stress 0.276416
Run 333 stress 0.2923969
Run 334 stress 0.277821
Run 335 stress 0.2820126
Run 336 stress 0.2899776
Run 337 stress 0.2756919
... Procrustes: rmse 0.01878761 max resid 0.1966573
Run 338 stress 0.310885
Run 339 stress 0.2819317
Run 340 stress 0.2830859
Run 341 stress 0.2771782
Run 342 stress 0.276415
Run 343 stress 0.2810702
Run 344 stress 0.2817051
Run 345 stress 0.2976131
Run 346 stress 0.3000953
Run 347 stress 0.2854301
Run 348 stress 0.2873747
Run 349 stress 0.2840335
Run 350 stress 0.2847668
Run 351 stress 0.2877928
Run 352 stress 0.2761237
Run 353 stress 0.2816047
Run 354 stress 0.2857891
Run 355 stress 0.2967727
Run 356 stress 0.2868496
Run 357 stress 0.2760473
Run 358 stress 0.321193
Run 359 stress 0.2826918
Run 360 stress 0.2876268
Run 361 stress 0.2752018
... Procrustes: rmse 0.001113995 max resid 0.01032134
Run 362 stress 0.2824346
Run 363 stress 0.281036
Run 364 stress 0.2819728
Run 365 stress 0.2825744
Run 366 stress 0.2957984
Run 367 stress 0.2989419
Run 368 stress 0.2768681
Run 369 stress 0.2871297
Run 370 stress 0.3062691
Run 371 stress 0.287284
Run 372 stress 0.4136489
Run 373 stress 0.280988
Run 374 stress 0.2934075
Run 375 stress 0.285402
Run 376 stress 0.275641
... Procrustes: rmse 0.01855291 max resid 0.1969236
Run 377 stress 0.2907737
Run 378 stress 0.3015324
Run 379 stress 0.2897734
Run 380 stress 0.2819079
Run 381 stress 0.275199
... New best solution
... Procrustes: rmse 0.0001407104 max resid 0.0008498833
... Similar to previous best
*** Solution reached
And now we can pull out the NMDS scores (2 dimensions), and explore their patterns in relation to the RainDrop study. First we look at the rainfall treatments in relation to community structure.
# scores and species points
rd_scores <- as.data.frame(raindrop_NMDS$points)
rd_species <- as.data.frame(raindrop_NMDS$species)
# converting to a nice data frame
rd_scores <- rd_scores %>%
mutate(plot = rownames(.)) %>%
mutate(month = as.character(map(strsplit(plot, "_"), 1)),
year = as.numeric(map(strsplit(plot, "_"), 2)),
block = as.character(map(strsplit(plot, "_"), 3)),
treatment = as.character(map(strsplit(plot, "_"), 4)))
# and for species
species_types <- percent_cover %>%
group_by(species) %>%
summarise(plant_type = plant_type[1])
rd_species <- rd_species %>%
mutate(species = rownames(.)) %>%
left_join(x = ., y = species_types, by = "species")
# treatment plot
rd_scores %>%
ggplot(aes(x = MDS1, y = MDS2, colour = treatment)) +
geom_point(alpha = 0.8, size = 4) +
stat_ellipse(level = 0.8, size = 1, show.legend = F) +
scale_colour_manual(values = raindrop_colours$colour) +
labs(x = "NMDS1", y = "NMDS2", colour = "Rainfall\ntreatment") +
theme_bw(base_size = 14) +
theme(panel.grid = element_blank())
And now whether there are any interesting temporal effects
rd_scores %>%
ggplot(aes(x = MDS1, y = MDS2, colour = as.factor(year))) +
geom_point(alpha = 0.8, size = 4) +
stat_ellipse(level = 0.8, size = 1, show.legend = F) +
scale_colour_viridis_d() +
labs(x = "NMDS1", y = "NMDS2", colour = "Year") +
theme_bw(base_size = 14) +
theme(panel.grid = element_blank())
It does look like there are interesting temporal patterns in community structure here.
And we can now see whether there are important groups of species or groups of species that may be driving community structure differences. This is essentially the ‘loading’ of each species to the two NMDS axes.
# pulling the 95% quantiles to identify most extreme data
q1 <- quantile(rd_species$MDS1, c(0.025, 0.975))
q2 <- quantile(rd_species$MDS2, c(0.025, 0.975))
rd_species_extreme <- rd_species %>%
mutate(species_lab = gsub("_", " ", species),
extreme_species = if_else(MDS1 > q1[2] | MDS1 < q1[1] |
MDS2 > q2[2] | MDS2 < q2[1],
"yes", "no"))
ggplot(rd_species_extreme,
aes(x = MDS1, y = MDS2, colour = plant_type)) +
geom_point(alpha = 0.8, size = 4) +
stat_ellipse(level = 0.8, size = 1, show.legend = F) +
geom_text(data = filter(rd_species_extreme,
extreme_species == "yes"),
aes(label = species_lab), nudge_y = -0.1, show.legend = F) +
labs(x = "NMDS1", y = "NMDS2", colour = "Plant\ntype") +
lims(x = c(-1.2,1.7)) +
theme_bw(base_size = 14) +
theme(panel.grid = element_blank())
sessionInfo()
R version 4.0.5 (2021-03-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19042)
Matrix products: default
locale:
[1] LC_COLLATE=English_United Kingdom.1252
[2] LC_CTYPE=English_United Kingdom.1252
[3] LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United Kingdom.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] vegan_2.5-7 lattice_0.20-41 permute_0.9-5 patchwork_1.1.1
[5] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.5 purrr_0.3.4
[9] readr_1.4.0 tidyr_1.1.3 tibble_3.1.0 ggplot2_3.3.3
[13] tidyverse_1.3.0 workflowr_1.6.2
loaded via a namespace (and not attached):
[1] httr_1.4.2 sass_0.3.1 viridisLite_0.3.0 jsonlite_1.7.2
[5] splines_4.0.5 modelr_0.1.8 bslib_0.2.4 assertthat_0.2.1
[9] highr_0.8 cellranger_1.1.0 yaml_2.2.1 pillar_1.5.1
[13] backports_1.2.1 glue_1.4.2 digest_0.6.27 RColorBrewer_1.1-2
[17] promises_1.2.0.1 rvest_1.0.0 colorspace_2.0-0 htmltools_0.5.1.1
[21] httpuv_1.5.5 Matrix_1.3-2 pkgconfig_2.0.3 broom_0.7.5
[25] haven_2.3.1 scales_1.1.1 whisker_0.4 later_1.1.0.1
[29] git2r_0.28.0 mgcv_1.8-34 generics_0.1.0 farver_2.1.0
[33] ellipsis_0.3.1 withr_2.4.1 cli_2.3.1 magrittr_2.0.1
[37] crayon_1.4.1 readxl_1.3.1 evaluate_0.14 ps_1.6.0
[41] fs_1.5.0 fansi_0.4.2 nlme_3.1-152 MASS_7.3-53.1
[45] xml2_1.3.2 tools_4.0.5 hms_1.0.0 lifecycle_1.0.0
[49] munsell_0.5.0 reprex_2.0.0 cluster_2.1.1 compiler_4.0.5
[53] jquerylib_0.1.3 rlang_0.4.10 grid_4.0.5 rstudioapi_0.13
[57] labeling_0.4.2 rmarkdown_2.7 gtable_0.3.0 DBI_1.1.1
[61] R6_2.5.0 lubridate_1.7.10 knitr_1.31 utf8_1.2.1
[65] rprojroot_2.0.2 stringi_1.5.3 parallel_4.0.5 Rcpp_1.0.6
[69] vctrs_0.3.7 dbplyr_2.1.0 tidyselect_1.1.0 xfun_0.22