OCN 683 - Homework 2

Sarah Pennington

Here we will analyze experimental data from Leibold et al. (2017), in which they used mesocosm manipulations to test whether grazers promote phytoplankton diversity in ponds. They factorially implemented a number of experimental treatments: N:P ratio, light, nutrient level, presence of grazers, and presence of a predator of the grazers. For the purposes of this assignment we will only use the balanced N:P treatment, and we will include both light levels but will not analyze the effect of light (the authors found it has no effect).

The column NutrientLevel has two levels (L = low and H = high), and the column FoodWeb has three levels (A = algae, G = algae + grazers, P = algae + grazers + predator). The treatments were randomly assigned to mesocosms within four blocks (column Block). The response variable we will analyze is the column Phyto_Chao1, which is the Chao-1 estimator of taxonomic richness.

getwd()
## [1] "C:/Users/sarah/Desktop/Masters program/Classes_spring_25"
div <- read_csv("leibold_mesocosm_data_subset.csv", 
    col_types = cols(NtoPratio = col_number(), 
        NutrientLevel = col_factor(levels = c("H", 
            "L")), ShadeCloth = col_factor(levels = c("N", 
            "Y")), FoodWeb = col_factor(levels = c("A", 
            "G", "P")), Zoop_Chao1 = col_number(), 
        `Phyto#taxa` = col_number(), Phyto_Chao1 = col_number(), 
        Block = col_number()))
names(div) #names of columns #Phyto_Chao1 is the response variable
## [1] "NtoPratio"     "NutrientLevel" "ShadeCloth"    "FoodWeb"      
## [5] "Tank"          "Zoop_Chao1"    "Phyto#taxa"    "Phyto_Chao1"  
## [9] "Block"
str(div)
## spc_tbl_ [39 × 9] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ NtoPratio    : num [1:39] 14 14 14 14 14 14 14 14 14 14 ...
##  $ NutrientLevel: Factor w/ 2 levels "H","L": 1 1 1 1 1 1 1 1 1 1 ...
##  $ ShadeCloth   : Factor w/ 2 levels "N","Y": 1 1 1 1 1 1 1 1 1 2 ...
##  $ FoodWeb      : Factor w/ 3 levels "A","G","P": 1 1 2 2 2 2 3 3 3 1 ...
##  $ Tank         : num [1:39] 15 115 1 66 84 89 36 75 86 11 ...
##  $ Zoop_Chao1   : num [1:39] 0 0 9.33 9.5 5 ...
##  $ Phyto#taxa   : num [1:39] 9 8 16 13 8 10 12 12 5 17 ...
##  $ Phyto_Chao1  : num [1:39] 9 11 19 19 8 ...
##  $ Block        : num [1:39] 1 4 1 2 3 4 1 2 3 1 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   NtoPratio = col_number(),
##   ..   NutrientLevel = col_factor(levels = c("H", "L"), ordered = FALSE, include_na = FALSE),
##   ..   ShadeCloth = col_factor(levels = c("N", "Y"), ordered = FALSE, include_na = FALSE),
##   ..   FoodWeb = col_factor(levels = c("A", "G", "P"), ordered = FALSE, include_na = FALSE),
##   ..   Tank = col_double(),
##   ..   Zoop_Chao1 = col_number(),
##   ..   `Phyto#taxa` = col_number(),
##   ..   Phyto_Chao1 = col_number(),
##   ..   Block = col_number()
##   .. )
##  - attr(*, "problems")=<externalptr>
div$Block <-as.factor(div$Block)
str(div)
## spc_tbl_ [39 × 9] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ NtoPratio    : num [1:39] 14 14 14 14 14 14 14 14 14 14 ...
##  $ NutrientLevel: Factor w/ 2 levels "H","L": 1 1 1 1 1 1 1 1 1 1 ...
##  $ ShadeCloth   : Factor w/ 2 levels "N","Y": 1 1 1 1 1 1 1 1 1 2 ...
##  $ FoodWeb      : Factor w/ 3 levels "A","G","P": 1 1 2 2 2 2 3 3 3 1 ...
##  $ Tank         : num [1:39] 15 115 1 66 84 89 36 75 86 11 ...
##  $ Zoop_Chao1   : num [1:39] 0 0 9.33 9.5 5 ...
##  $ Phyto#taxa   : num [1:39] 9 8 16 13 8 10 12 12 5 17 ...
##  $ Phyto_Chao1  : num [1:39] 9 11 19 19 8 ...
##  $ Block        : Factor w/ 4 levels "1","2","3","4": 1 4 1 2 3 4 1 2 3 1 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   NtoPratio = col_number(),
##   ..   NutrientLevel = col_factor(levels = c("H", "L"), ordered = FALSE, include_na = FALSE),
##   ..   ShadeCloth = col_factor(levels = c("N", "Y"), ordered = FALSE, include_na = FALSE),
##   ..   FoodWeb = col_factor(levels = c("A", "G", "P"), ordered = FALSE, include_na = FALSE),
##   ..   Tank = col_double(),
##   ..   Zoop_Chao1 = col_number(),
##   ..   `Phyto#taxa` = col_number(),
##   ..   Phyto_Chao1 = col_number(),
##   ..   Block = col_number()
##   .. )
##  - attr(*, "problems")=<externalptr>

Create a linear model that tests whether richness is explained by nutrient level and/or food web treatment, and whether the effect of food web treatment differs between nutrient levels, while also accounting for the blocked structure of the experiment. Why is it important to account for the blocks? Analyze the results of the linear model as we did in Homework 1. What is your interpretation of these results so far?

#Create a linear model that tests whether richness is explained by nutrient level and/or food web treatment, and whether the effect of food web treatment differs between nutrient levels, while also accounting for the blocked structure of the experiment.
div.model = lm(Phyto_Chao1 ~ NutrientLevel * FoodWeb + Block, data = div)
summary(div.model)
## 
## Call:
## lm(formula = Phyto_Chao1 ~ NutrientLevel * FoodWeb + Block, data = div)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -7.9575 -3.1031  0.1463  2.2300  9.2563 
## 
## Coefficients:
##                         Estimate Std. Error t value Pr(>|t|)    
## (Intercept)              10.7437     2.3171   4.637 6.48e-05 ***
## NutrientLevelL            2.3912     2.6524   0.902   0.3745    
## FoodWebG                  6.1100     2.6524   2.304   0.0284 *  
## FoodWebP                 -0.3990     2.9133  -0.137   0.8920    
## Block2                   -0.1676     2.1969  -0.076   0.9397    
## Block3                   -0.9499     2.1048  -0.451   0.6550    
## Block4                   -1.6725     2.3149  -0.722   0.4756    
## NutrientLevelL:FoodWebG   0.7125     3.7948   0.188   0.8523    
## NutrientLevelL:FoodWebP   5.1877     3.9864   1.301   0.2030    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4.885 on 30 degrees of freedom
## Multiple R-squared:  0.4046, Adjusted R-squared:  0.2458 
## F-statistic: 2.548 on 8 and 30 DF,  p-value: 0.03008
#Why is it important to account for the blocks?
  ###If block had a significant effect on richness(Phto_Chao1), then that would mean some other factor in individual blocks that was impacting our results.


#Analyze the results of the linear model as we did in Homework 1.
library(ggResidpanel)
resid_panel(div.model, plots = c('resid', 'qq', 'lev', 'hist'))

#Report F tests for terms of the model. 
Anova(div.model)
## Anova Table (Type II tests)
## 
## Response: Phyto_Chao1
##                       Sum Sq Df F value   Pr(>F)   
## NutrientLevel         163.07  1  6.8341 0.013853 * 
## FoodWeb               314.91  2  6.5985 0.004217 **
## Block                  14.80  3  0.2068 0.890886   
## NutrientLevel:FoodWeb  45.82  2  0.9601 0.394315   
## Residuals             715.86 30                    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##F values 
##NutrientLevel 7.2289  
##FoodWeb    7.0042 
##NutrientLevel:FoodWeb  1.0368


#Create an effects plot displaying fitted effects 
library(ggeffects)
plot(ggeffect(div.model, terms = c('FoodWeb', 'NutrientLevel')))

#What is your interpretation of the results so far? 
  ###Richness is lower for higher nutrient levels across foodwebs. Foodwebs A and G appear to have the largest difference in richness based on the effect sizes model. 

Now we will use contrasts to test some hypotheses, and we will imagine that we formulated these hypotheses a priori (as opposed to formulating them after we looked at the data). We would like to know specifically whether the grazer treatment (G) has greater richness than the algae treament (A), and whether the effect of grazers differs between high and low nutrient levels (we think the effect of grazers on coexistence may be greater at high nutrient loading).

Use emmeans to calculate the estimated marginal means of each combination of nutrient level and food web treatment (i.e., H + A, H + G, H + P, L + A, L + G, L + P). Now define contrasts totest (1) whether G is different from A in the H treatment, (2) whether G is different from A in the L treatment, and (3) whether G is different from A when averaging over the L and H treatments.

#Use emmeans to calculate the estimated marginal means of each combination of nutrient level and food web treatment (i.e., H + A, H + G, H + P, L + A, L + G, L + P).
library(emmeans)
## Welcome to emmeans.
## Caution: You lose important information if you filter this package's results.
## See '? untidy'
trt.control.contrast = emmeans(div.model, specs = trt.vs.ctrl ~ NutrientLevel * FoodWeb)
summary(trt.control.contrast)
## $emmeans
##  NutrientLevel FoodWeb emmean   SE df lower.CL upper.CL
##  H             A        10.05 2.01 30     5.94     14.2
##  L             A        12.44 1.73 30     8.91     16.0
##  H             G        16.16 1.73 30    12.63     19.7
##  L             G        19.26 2.05 30    15.07     23.5
##  H             P         9.65 2.06 30     5.44     13.9
##  L             P        17.23 2.26 30    12.61     21.8
## 
## Results are averaged over the levels of: Block 
## Confidence level used: 0.95 
## 
## $contrasts
##  contrast  estimate   SE df t.ratio p.value
##  L A - H A    2.391 2.65 30   0.902  0.7930
##  H G - H A    6.110 2.65 30   2.304  0.1106
##  L G - H A    9.214 2.85 30   3.237  0.0130
##  H P - H A   -0.399 2.91 30  -0.137  0.9985
##  L P - H A    7.180 3.05 30   2.353  0.1000
## 
## Results are averaged over the levels of: Block 
## P value adjustment: dunnettx method for 5 tests
plot(trt.control.contrast$contrast)

#(1) whether G is different from A in the H treatment
levels(div$FoodWeb)
## [1] "A" "G" "P"
   ###[1] "A" "G" "P"
N.colimitation = contrast(emmeans(div.model, ~ FoodWeb * NutrientLevel, at = list(NutrientLevel = "H")), method 
= list("G - A in H" = c(-1, 1, 0)))
print(N.colimitation)
##  contrast   estimate   SE df t.ratio p.value
##  G - A in H     6.11 2.65 30   2.304  0.0284
## 
## Results are averaged over the levels of: Block
#(2) whether G is different from A in the L treatment
N.colimitation1 = contrast(emmeans(div.model, ~ FoodWeb * NutrientLevel, at = list(NutrientLevel = "L")), method 
= list("G - A in L" = c(-1, 1, 0)))
print(N.colimitation1)
##  contrast   estimate   SE df t.ratio p.value
##  G - A in L     6.82 2.68 30   2.543  0.0164
## 
## Results are averaged over the levels of: Block
#(3) whether G is different from A when averaging over the L and H treatments. 
N.colimitation2 = contrast(emmeans(div.model, ~ FoodWeb), method 
= list("G - A in H + L" = c(-1, 1, 0)))
## NOTE: Results may be misleading due to involvement in interactions
print(N.colimitation2)
##  contrast       estimate   SE df t.ratio p.value
##  G - A in H + L     6.47 1.88 30   3.448  0.0017
## 
## Results are averaged over the levels of: NutrientLevel, Block

(4) define an interaction contrast that tests whether the difference between G and A is itself different between L and H treatments. I.e., is (G – A) for the high nutrient treatments greater or smaller than (G – A) for the low nutrient treatments? Hint: for the interaction contrast you are essentially taking contrast #2 and subtracting it from contrast #1, in order to test whether the two contrasts are the same, which means that the difference between them is zero.How do you interpret these results?

interaction <- contrast(emmeans(div.model, ~ FoodWeb * NutrientLevel), method = list("G - A in H vs G - A in L" = c(-1, 1, 0, 1, -1, 0)))
print(interaction)
##  contrast                 estimate   SE df t.ratio p.value
##  G - A in H vs G - A in L   -0.712 3.79 30  -0.188  0.8523
## 
## Results are averaged over the levels of: Block
#How do you interpret these results? 
   ### Going all the way back to the first two contrasts, G-A in H or L,  showed richness was significantly different between G and A when Nutrient levels were high and when they were low. The combined contrast with between G-A in H and L nutrient levels showed richness was also significantly different. Lastly, there was no significant difference in G and A difference between L and H treatments. The difference wasn't different between nutrient levels. This could imply  perhaps nutrient level is the driver of the difference seen in the first contrasts (?)

Now, repeat the same set of 4 contrasts, but this time ask whether the P treatment is different from the G treatment. We are interested in these contrasts a priori because we think that adding a predator of the grazers may mean that grazers have a weaker effect on phytoplankton diversity, and that this trophic cascade may be more important under high nutrient supply. How do you interpret the results?

#(1) whether G is different from P in the H treatment
levels(div$FoodWeb)
## [1] "A" "G" "P"
   ###[1] "A" "G" "P"
N.colimitation = contrast(emmeans(div.model, ~ FoodWeb * NutrientLevel, at = list(NutrientLevel = "H")), method 
= list("G - P in H" = c(0,-1, 1)))
print(N.colimitation)
##  contrast   estimate   SE df t.ratio p.value
##  G - P in H    -6.51 2.69 30  -2.421  0.0217
## 
## Results are averaged over the levels of: Block
#(2) whether G is different from P in the L treatment
N.colimitation1 = contrast(emmeans(div.model, ~ FoodWeb * NutrientLevel, at = list(NutrientLevel = "L")), method 
= list("G - P in L" = c(0,-1, 1)))
print(N.colimitation1)
##  contrast   estimate   SE df t.ratio p.value
##  G - P in L    -2.03 3.11 30  -0.654  0.5182
## 
## Results are averaged over the levels of: Block
#(3) whether G is different from P when averaging over the L and H treatments. 
N.colimitation2 = contrast(emmeans(div.model, ~ FoodWeb), method 
= list("G - P in H + L" = c(0,-1, 1)))
## NOTE: Results may be misleading due to involvement in interactions
print(N.colimitation2)
##  contrast       estimate  SE df t.ratio p.value
##  G - P in H + L    -4.27 2.1 30  -2.033  0.0510
## 
## Results are averaged over the levels of: NutrientLevel, Block
# (4) define an interaction contrast that tests whether the difference between G and P is itself different between L and H treatments.
interaction <- contrast(emmeans(div.model, ~ FoodWeb * NutrientLevel), method = list("G - A in H vs G - A in L" = c(0, -1, 1, 0, 1, -1)))
print(interaction)
##  contrast                 estimate   SE df t.ratio p.value
##  G - A in H vs G - A in L    -4.48 4.02 30  -1.114  0.2742
## 
## Results are averaged over the levels of: Block
#We are interested in these contrasts a priori because we think that adding a predator of the grazers may mean that grazers have a weaker effect on phytoplankton diversity, and that this trophic cascade may be more important under high nutrient supply. How do you interpret the results? 

   ###Based on the results of these contrasts, we can see that food web does have an impact on richness. However, it appears the nutrient supply is a large driver of richness differnces also.The researchers probably shouldn't draw the conclusion that trophic cascade is more important than nutrient supply in determining species richness.