Repository:
https://github.com/egage/EVMP
This document contains code and results from frequentist statistical analyses of Elk Vegetation Management Plan (EVMP) data collected through the 2018 sampling season for a subset of data as requested by RMNP staff. Analyses are provided as a supplement to the NPS NRR Report “Monitoring of Vegetation Response to Elk Population and Habitat Management in Rocky Mountain National Park - Analysis of Elk Vegetation Management Plan monitoring Data: 2008–2018.” The frequentist analyses here differ in philosophical foundation and interpretation than the Bayesian analyses presented in the report and are presented for comparison to past analyses.
The code and results presented here start from and build upon derived data produced in a separate code document focused on ingesting, compiling, and cleaning raw data provided by RMNP staff. See other Appendices for details on data processing used to transform raw files to the derived data ingested for analyses here.
Per guidance from RMNP, for willow plots, only macroplot data are analyzed here. Based on data structure, a repeated measures Analysis of Variance (ANOVA) approach is used. Following methods used in Zeigenfuss and Johnson (2015), the minimum non-zero proportion of shrub cover was substituted for areas with no shrub cover and (1 - this minimum) was used for sites with a proportion of 1 so that a log of proportion of cover coul be tested statistically (Zeigenfuss and Johnson 2015).
#### Data import and munging
# read in willow. These data are the output of extensive munging accomplished using code in "EVMP_munging_20210131.Rmd"
willow <- read_csv("./output/exported_data/willow_mcro.csv")
## create timeClass var
willow.ht <- willow %>%
filter(!is.na(PLANT_HT_CM)) %>%
mutate(timeClass = case_when(yr == 2008 ~ "BL",
yr == 2009 ~ "BL",
TRUE ~ as.character(yr)))
## filter out just the willow species
willow.ht <- willow.ht %>%
clean_names() %>%
filter(str_detect(species_code, pattern = "SA"))
## filter out 0
willow.ht <- willow.ht %>%
filter(plant_ht_cm > 0)
### calculate the mean and max height for all the willows
willow.ht <- willow.ht %>%
group_by(time_class,site_type, fenced, burned, site_id) %>%
summarise(ht_mean = mean(plant_ht_cm, na.rm=TRUE), ht_max = max(plant_ht_cm, na.rm=TRUE)) %>%
mutate(burned = case_when(is.na(burned) ~ "N",
TRUE ~ burned)) %>%
ungroup()
# parse out the WK plots
willow.ht.wk <- willow.ht %>%
filter(site_type == "WK")
##
## filter to 5 yr sampling interval, chr to factor conversions
willow.ht <- willow.ht %>%
filter(time_class == "BL" | time_class == "2013" | time_class == "2018") %>%
mutate(time_class = as.factor(time_class)) %>%
mutate(time_class = fct_relevel(time_class, "2018", "2013", "BL")) %>%
mutate(fenced = as.factor(fenced))
## reorder the time class
willow.ht <- willow.ht %>%
mutate(time_class = fct_rev(time_class))
## factor reverse: fenced
willow.ht <- willow.ht %>%
mutate(fenced = fct_rev(fenced))
## create separate df for WC, WNC, combined WC & WNC, and KV
willow.ht.wc <- willow.ht %>%
filter(site_type == "WC")
# non core
willow.ht.nc <- willow.ht %>%
# distinct(site_type)
filter(site_type == "WNC")
## combined winter range (WC and WNC)
willow.ht.wcwnc <- willow.ht %>%
filter(site_type == "WNC" | site_type == "WC")
# WK defined above
# time class only
aov_model_wcwnc <- aov(ht_mean ~ time_class + Error(1/site_id), data = willow.ht.wcwnc)
summary(aov_model_wcwnc)
##
## Error: Within
## Df Sum Sq Mean Sq F value Pr(>F)
## time_class 2 49318 24659 2.76 0.0651 .
## Residuals 275 2457341 8936
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# time x fenced x location
aov_model_wcwnc.tcXfXsite_type <- aov(ht_mean ~ time_class*fenced*site_type + Error(1/site_id), data = willow.ht.wcwnc)
broom::tidy(aov_model_wcwnc.tcXfXsite_type) %>%
mutate(across(where(is.numeric),round,2)) %>%
gt() %>%
tab_header(title = "ht_mean ~ time_class*fenced*site_type + Error(1/site_id)")
| ht_mean ~ time_class*fenced*site_type + Error(1/site_id) | ||||||
|---|---|---|---|---|---|---|
| stratum | term | df | sumsq | meansq | statistic | p.value |
| Within | time_class | 2 | 49318.36 | 24659.18 | 3.36 | 0.04 |
| Within | fenced | 1 | 56195.44 | 56195.44 | 7.65 | 0.01 |
| Within | site_type | 1 | 373791.01 | 373791.01 | 50.89 | 0.00 |
| Within | time_class:fenced | 2 | 50881.55 | 25440.77 | 3.46 | 0.03 |
| Within | time_class:site_type | 2 | 553.81 | 276.90 | 0.04 | 0.96 |
| Within | Residuals | 269 | 1975919.69 | 7345.43 | NA | NA |
# add burned
aov_model_wcwnc.tcXfXbXsite_type <- aov(ht_mean ~ time_class*site_type*fenced*burned + Error(1/site_id), data = willow.ht.wcwnc)
broom::tidy(aov_model_wcwnc.tcXfXbXsite_type) %>%
mutate(across(where(is.numeric),round,2)) %>%
gt() %>%
tab_header(title = "plant_ht_cm ~ time_class*site_type*fenced*burned + Error(1/site_id)")
| plant_ht_cm ~ time_class*site_type*fenced*burned + Error(1/site_id) | ||||||
|---|---|---|---|---|---|---|
| stratum | term | df | sumsq | meansq | statistic | p.value |
| Within | time_class | 2 | 49318.36 | 24659.18 | 3.54 | 0.03 |
| Within | site_type | 1 | 424969.12 | 424969.12 | 61.05 | 0.00 |
| Within | fenced | 1 | 5017.34 | 5017.34 | 0.72 | 0.40 |
| Within | burned | 1 | 117511.68 | 117511.68 | 16.88 | 0.00 |
| Within | time_class:site_type | 2 | 7154.26 | 3577.13 | 0.51 | 0.60 |
| Within | time_class:fenced | 2 | 47366.86 | 23683.43 | 3.40 | 0.03 |
| Within | time_class:burned | 2 | 24103.04 | 12051.52 | 1.73 | 0.18 |
| Within | fenced:burned | 1 | 17.94 | 17.94 | 0.00 | 0.96 |
| Within | time_class:fenced:burned | 2 | 442.06 | 221.03 | 0.03 | 0.97 |
| Within | Residuals | 263 | 1830759.19 | 6961.06 | NA | NA |
| ht_mean ~ time_class | ||||||
|---|---|---|---|---|---|---|
| Effect | DFn | DFd | F | p | p<.05 | ges |
| time_class | 2 | 275 | 2.76 | 0.065 | 0.02 | |
| ht_mean ~ time_class+fenced+burned | ||||||
|---|---|---|---|---|---|---|
| Effect | DFn | DFd | F | p | p<.05 | ges |
| time_class | 2 | 273 | 3.674 | 2.70e-02 | * | 0.026 |
| fenced | 1 | 273 | 0.428 | 5.13e-01 | 0.002 | |
| burned | 1 | 273 | 30.178 | 9.03e-08 | * | 0.100 |
| ht_mean ~ time_class*fenced*burned | ||||||
|---|---|---|---|---|---|---|
| Effect | DFn | DFd | F | p | p<.05 | ges |
| time_class | 2 | 266 | 3.76 | 0.03 | * | 0.03 |
| fenced | 1 | 266 | 0.49 | 0.49 | 0.00 | |
| burned | 1 | 266 | 31.19 | 0.00 | * | 0.10 |
| time_class:fenced | 2 | 266 | 3.82 | 0.02 | * | 0.03 |
| time_class:burned | 2 | 266 | 1.32 | 0.27 | 0.01 | |
| fenced:burned | 1 | 266 | 2.24 | 0.14 | 0.01 | |
| time_class:fenced:burned | 2 | 266 | 0.00 | 1.00 | 0.00 | |
Model summary, combined core and non-core winter range:
The repeated-measures ANOVA (formula: ht_mean ~ time_class * site_type * fenced * burned + Error(1/site_id)) suggests that:
Effect sizes were labelled following Field’s (2013) recommendations.
# GT table: location: WC and WNC only
aov_model_wcwnc %>%
broom::tidy() %>%
mutate(across(where(is.numeric), round,2)) %>%
gt() %>%
tab_header(title="plant_ht_cm ~ time_class*location*fenced*burned + Error(1/site_id)", subtitle = "WC and WNC")
| plant_ht_cm ~ time_class*location*fenced*burned + Error(1/site_id) | ||||||
|---|---|---|---|---|---|---|
| WC and WNC | ||||||
| stratum | term | df | sumsq | meansq | statistic | p.value |
| Within | time_class | 2 | 49318.36 | 24659.18 | 2.76 | 0.07 |
| Within | Residuals | 275 | 2457341.50 | 8935.79 | NA | NA |
| stratum | term | df | sumsq | meansq | statistic | p.value |
|---|---|---|---|---|---|---|
| Within | time_class | 2 | 65553.866 | 32776.933 | 6.4713998 | 0.001941084 |
| Within | fenced | 1 | 4928.339 | 4928.339 | 0.9730395 | 0.325277455 |
| Within | time_class:fenced | 2 | 43983.834 | 21991.917 | 4.3420319 | 0.014431970 |
| Within | Residuals | 176 | 891420.775 | 5064.891 | NA | NA |
Model summary, mean plot willow height, core winter range:
The repeated-measures ANOVA (formula: ht_mean ~ time_class * fenced + Error(1/site_id)) suggests that:
Effect sizes were labelled following Field’s (2013) recommendations.
broom::tidy(aov_model_wc) %>%
mutate(across(.cols = where(is.numeric),.fns = round, 2)) %>%
gt()
| stratum | term | df | sumsq | meansq | statistic | p.value |
|---|---|---|---|---|---|---|
| Within | time_class | 2 | 65553.87 | 32776.93 | 6.47 | 0.00 |
| Within | fenced | 1 | 4928.34 | 4928.34 | 0.97 | 0.33 |
| Within | time_class:fenced | 2 | 43983.83 | 21991.92 | 4.34 | 0.01 |
| Within | Residuals | 176 | 891420.77 | 5064.89 | NA | NA |
## save as table (.csv)
broom::tidy(aov_model_wc) %>%
mutate(across(.cols = where(is.numeric),.fns = round, 3)) %>%
write_csv("output/tables/aov_wc_ht_TC_fenced.csv")
## aov_model_wc <- aov(plant_ht_cm ~ time_class*fenced + Error(1/site_id), data = willow.ht.wc)
willow.ht.stype.nest <- willow.ht %>%
nest_by(site_type)
### create AOV models
# plant_ht_cm ~ time_class + Error(1/site_id)
# not enough factor levels for WK
mods.aov.willHt.tc <- willow.ht.stype.nest %>%
# filter(site_type == "WC") %>%
filter(site_type != "WK") %>%
mutate(mod = list(aov(ht_mean ~ time_class + Error(1/site_id), data = data)))
# plant_ht_cm ~ time_class*fenced + Error(1/site_id)
# not enough factor levels for WK OR WNC
mods.aov.willHt.tc.fen <- willow.ht.stype.nest %>%
filter(site_type == "WC") %>%
mutate(mod = list(aov(ht_mean ~ time_class*fenced + Error(1/site_id), data = data))) %>%
mutate(mod.max = list(aov(ht_max ~ time_class*fenced + Error(1/site_id), data = data)))
## WNC
mods.aov.willHt.wnc <- willow.ht.stype.nest %>%
filter(site_type == "WNC") %>%
mutate(mod = list(aov(ht_mean ~ time_class + Error(1/site_id), data = data)))%>%
mutate(mod.max = list(aov(ht_max ~ time_class + Error(1/site_id), data = data)))
# GT table: location: WC only
aov.willHt.tc.fen <- mods.aov.willHt.tc.fen %>%
mutate(aov_summary = list(summary(mod))) %>%
mutate(aov_tidy = list(broom::tidy(mod))) %>%
unnest(aov_tidy) %>%
mutate(across(where(is.numeric), round, 3)) %>%
select(site_type,term,df,sumsq,meansq,statistic,p.value) %>%
gt::gt() %>%
gt::tab_header(title = "aov: plant_ht_cm ~ time_class*fenced + Error(1/site_id)", subtitle = "WC")
aov.willHt.tc.fen
| aov: plant_ht_cm ~ time_class*fenced + Error(1/site_id) | |||||
|---|---|---|---|---|---|
| WC | |||||
| term | df | sumsq | meansq | statistic | p.value |
| WC | |||||
| time_class | 2 | 65553.866 | 32776.933 | 6.471 | 0.002 |
| fenced | 1 | 4928.339 | 4928.339 | 0.973 | 0.325 |
| time_class:fenced | 2 | 43983.834 | 21991.917 | 4.342 | 0.014 |
| Residuals | 176 | 891420.775 | 5064.891 | NA | NA |
aov_model_wnc <- aov(ht_mean ~ time_class + Error(1/site_id), data = willow.ht.nc)
Model summary, non-core winter range:
The repeated-measures ANOVA (formula: ht_mean ~ time_class + Error(1/site_id)) suggests that:
Effect sizes were labelled following Field’s (2013) recommendations.
# GT table: location: WNC only
aov.willHt.tc.fen.wnc <- mods.aov.willHt.wnc %>%
mutate(aov_summary = list(summary(mod))) %>%
mutate(aov_tidy = list(broom::tidy(mod))) %>%
unnest(aov_tidy) %>%
mutate(across(where(is.numeric), round, 3)) %>%
select(site_type,term,df,sumsq,meansq,statistic,p.value) %>%
gt::gt() %>%
gt::tab_header(title = "aov: plant_ht_cm ~ time_class + Error(1/site_id)", subtitle = "WNC. All unfenced")
aov.willHt.tc.fen.wnc
| aov: plant_ht_cm ~ time_class + Error(1/site_id) | |||||
|---|---|---|---|---|---|
| WNC. All unfenced | |||||
| term | df | sumsq | meansq | statistic | p.value |
| WNC | |||||
| time_class | 2 | 14754.75 | 7377.374 | 0.633 | 0.533 |
| Residuals | 93 | 1084498.91 | 11661.279 | NA | NA |
2016-2018 only
# model for wk
# willow.ht.wk %>%
# distinct(time_class)
aov_model_wk <- aov(ht_mean ~ time_class + Error(1/site_id), data = willow.ht.wk)
Model summary, non-core winter range:
The repeated-measures ANOVA (formula: ht_mean ~ time_class + Error(1/site_id)) suggests that:
Effect sizes were labelled following Field’s (2013) recommendations.
aov_model_wk %>%
broom::tidy() %>%
mutate(across(where(is.numeric), round,2)) %>%
gt() %>%
tab_header(title="ht_mean ~ time_class + Error(1/site_id)", subtitle = "Kawuneeche Valley")
| ht_mean ~ time_class + Error(1/site_id) | ||||||
|---|---|---|---|---|---|---|
| Kawuneeche Valley | ||||||
| stratum | term | df | sumsq | meansq | statistic | p.value |
| Within | time_class | 2 | 22.17 | 11.09 | 0.01 | 0.99 |
| Within | Residuals | 20 | 16118.89 | 805.94 | NA | NA |
willow.ht %>%
filter(site_type != "WK") %>%
ggplot(aes(ht_mean, ht_max)) +
geom_point(aes(color=fenced, shape = fenced)) +
geom_smooth(aes(color = fenced), se = FALSE, ) +
geom_abline(intercept = 0, slope = 1, lty = "dashed", size=1, color="gray80") +
scale_color_manual(values = c("blue","red")) +
theme_minimal() +
labs(x="Mean willow height (cm)", y = "Mean willow height (cm)", shape = "", color = "") +
facet_wrap(~site_type)
### Combined Core and Noncore Winter Range
# read in data
# canopy.all.willow.sum <- read_csv("./output/exported_data/willow_cover_20200725.csv") %>%
# janitor::clean_names()
canopy.all.willow.sum <- read_csv("./output/exported_data/willow_macroplot_cover_BLto2018.csv") %>%
janitor::clean_names()
### create subsets of data for modeling
# pull out WK, note different years of data
cov.wk <- canopy.all.willow.sum %>%
filter(site_type == "WK") %>%
mutate(time_class = as.character(time_class)) %>%
filter(time_class == "2016" | time_class == "2017" | time_class == "2018") %>%
mutate(time_class = as.factor(time_class))
# pull out the core plus noncore winter range plots
cov.wc.wnc <- canopy.all.willow.sum %>%
filter(time_class == "BL" | time_class == "2013" | time_class == "2018") %>%
filter(site_type == "WNC" | site_type == "WC") %>%
mutate(cover_allwillow = cover_allwillow/100) %>%
filter(!is.na(cover_allwillow))
# pull out the core winter range plots
cov.wc <- canopy.all.willow.sum %>%
filter(site_type == "WC") %>%
filter(time_class == "BL" | time_class == "2013" | time_class == "2018") %>%
mutate(cover_allwillow = cover_allwillow/100) %>%
filter(!is.na(cover_allwillow))
# pull out the noncore winter range plots
cov.wnc <- canopy.all.willow.sum %>%
filter(site_type == "WNC") %>%
filter(time_class == "BL" | time_class == "2013" | time_class == "2018") %>%
mutate(cover_allwillow = cover_allwillow/100) %>%
filter(!is.na(cover_allwillow))
Summary table: time class and fenced
#### Summary Tables
#### summary tables: time class and fenced
cov.wc.wnc %>%
group_by(time_class, fenced) %>%
summarytools::descr(cover_allwillow,stats = "common") %>%
summarytools::tb() %>%
mutate_if(.predicate = is.numeric,.funs = round, digits = 2) %>%
gt() %>%
tab_header(title = "Combined WC and WNC macroplot data")
| Combined WC and WNC macroplot data | |||||||||
|---|---|---|---|---|---|---|---|---|---|
| time_class | fenced | variable | mean | sd | min | med | max | n.valid | pct.valid |
| BL | Unfenced | cover_allwillow | 0.33 | 0.27 | 0.00 | 0.27 | 1 | 53 | 100 |
| BL | Fenced | cover_allwillow | 0.16 | 0.23 | 0.00 | 0.10 | 1 | 19 | 100 |
| 2013 | Unfenced | cover_allwillow | 0.29 | 0.29 | 0.00 | 0.24 | 1 | 64 | 100 |
| 2013 | Fenced | cover_allwillow | 0.28 | 0.29 | 0.00 | 0.21 | 1 | 30 | 100 |
| 2018 | Unfenced | cover_allwillow | 0.43 | 0.35 | 0.00 | 0.39 | 1 | 69 | 100 |
| 2018 | Fenced | cover_allwillow | 0.54 | 0.34 | 0.05 | 0.50 | 1 | 30 | 100 |
Summary table: time class,fenced,burned
## time class, fenced and burned
cov.wc.wnc %>%
group_by(time_class, fenced, burned) %>%
summarytools::descr(cover_allwillow, stats = "common") %>%
summarytools::tb() %>%
mutate_if(.predicate = is.numeric,.funs = round, digits = 2) %>%
gt() %>%
tab_header(title = "Combined WC and WNC macroplot data")
| Combined WC and WNC macroplot data | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| time_class | fenced | burned | variable | mean | sd | min | med | max | n.valid | pct.valid |
| BL | Unfenced | Unburned | cover_allwillow | 0.33 | 0.27 | 0.00 | 0.27 | 1.00 | 53 | 100 |
| BL | Fenced | Unburned | cover_allwillow | 0.16 | 0.23 | 0.00 | 0.10 | 1.00 | 19 | 100 |
| 2013 | Unfenced | Unburned | cover_allwillow | 0.33 | 0.29 | 0.00 | 0.26 | 1.00 | 54 | 100 |
| 2013 | Unfenced | Burned | cover_allwillow | 0.10 | 0.22 | 0.01 | 0.02 | 0.72 | 10 | 100 |
| 2013 | Fenced | Unburned | cover_allwillow | 0.41 | 0.29 | 0.02 | 0.40 | 1.00 | 17 | 100 |
| 2013 | Fenced | Burned | cover_allwillow | 0.12 | 0.21 | 0.00 | 0.04 | 0.79 | 13 | 100 |
| 2018 | Unfenced | Unburned | cover_allwillow | 0.47 | 0.34 | 0.00 | 0.41 | 1.00 | 61 | 100 |
| 2018 | Unfenced | Burned | cover_allwillow | 0.15 | 0.34 | 0.00 | 0.03 | 1.00 | 8 | 100 |
| 2018 | Fenced | Unburned | cover_allwillow | 0.66 | 0.33 | 0.14 | 0.64 | 1.00 | 17 | 100 |
| 2018 | Fenced | Burned | cover_allwillow | 0.39 | 0.29 | 0.05 | 0.26 | 1.00 | 13 | 100 |
# ### AOV: cov ~ time class * condition
# cull to just bl, 13, 18 and WC WNC
canopy.all.willow.sum.5yr.wcwnc <- canopy.all.willow.sum %>%
filter(site_type != "WK") %>%
filter(time_class %in% c("BL", "2013","2018")) %>%
mutate(time_class = fct_drop(time_class))
# nest by TC
willow.cov.tc.nest <- canopy.all.willow.sum.5yr.wcwnc %>%
nest_by(time_class)
### create AOV models
mods.aov.willcov.tcxZcond2 <- willow.cov.tc.nest %>%
mutate(mod = list(aov(cover_transformed ~ z_cond2 + Error(1/site_id), data = data)))
## nest by z cond & TC
willow.cov.zc.wcwnc.nest <- canopy.all.willow.sum.5yr.wcwnc %>%
nest_by(z_cond2)
willow.cov.zc.wcwnc.nest <- willow.cov.zc.wcwnc.nest %>%
mutate(mod = list(aov(cover_transformed ~ time_class + Error(1/site_id), data = data)))
# GT table
willow.cov.zc.wcwnc.nest %>%
mutate(aov_summary = list(summary(mod))) %>%
mutate(aov_tidy = list(broom::tidy(mod))) %>%
unnest(aov_tidy) %>%
mutate(across(where(is.numeric), round, 3)) %>%
select(z_cond2,term,df,sumsq,meansq,statistic,p.value) %>%
gt::gt() %>%
gt::tab_header(title = "aov: cover (transformed) ~ condition + Error(1/site_id)", subtitle = "analysis on transformed scale")
| aov: cover (transformed) ~ condition + Error(1/site_id) | |||||
|---|---|---|---|---|---|
| analysis on transformed scale | |||||
| term | df | sumsq | meansq | statistic | p.value |
| WC-BF | |||||
| time_class | 2 | 71.862 | 35.931 | 11.251 | 0.000 |
| Residuals | 30 | 95.811 | 3.194 | NA | NA |
| WC-BG | |||||
| time_class | 2 | 0.361 | 0.181 | 0.041 | 0.960 |
| Residuals | 16 | 71.135 | 4.446 | NA | NA |
| WC-UF | |||||
| time_class | 2 | 36.998 | 18.499 | 7.158 | 0.002 |
| Residuals | 43 | 111.128 | 2.584 | NA | NA |
| WC-UG | |||||
| time_class | 2 | 8.453 | 4.227 | 1.097 | 0.339 |
| Residuals | 73 | 281.261 | 3.853 | NA | NA |
| WNC-UG | |||||
| time_class | 2 | 13.411 | 6.706 | 2.254 | 0.111 |
| Residuals | 88 | 261.813 | 2.975 | NA | NA |
# write csv
willow.cov.zc.wcwnc.nest %>%
mutate(aov_summary = list(summary(mod))) %>%
mutate(aov_tidy = list(broom::tidy(mod))) %>%
unnest(aov_tidy) %>%
mutate(across(where(is.numeric), round, 3)) %>%
select(z_cond2,term,df,sumsq,meansq,statistic,p.value) %>%
write_csv("output/tables/willow_cover/frequentist/aov_willcov_zcond2.csv")
# ### Table for manuscript
# extract model info, tidy
wcov.pval <- willow.cov.zc.wcwnc.nest %>%
mutate(aov_summary = list(summary(mod))) %>%
mutate(aov_tidy = list(broom::tidy(mod))) %>%
unnest(aov_tidy) %>%
mutate(across(where(is.numeric), round, 3)) %>%
select(z_cond2,term,df,sumsq,meansq,statistic,p.value) %>%
filter(term == "time_class")
## calc empirical mean of cover then join in results from freq aov
# cover transformed ~
canopy.all.willow.sum.5yr.wcwnc %>%
group_by(time_class, z_cond2) %>%
summarise(cov.mean = mean(cover_allwillow, na.rm=TRUE)) %>%
ungroup() %>%
pivot_wider(names_from = time_class,
names_glue = "Cover-{time_class}",
values_from = cov.mean) %>%
left_join(.,wcov.pval, by="z_cond2") %>%
mutate(across(where(is.numeric), round, 2)) %>%
gt()
| z_cond2 | Cover-BL | Cover-2013 | Cover-2018 | term | df | sumsq | meansq | statistic | p.value |
|---|---|---|---|---|---|---|---|---|---|
| WC-BF | 2.89 | 12.00 | 38.63 | time_class | 2 | 71.86 | 35.93 | 11.25 | 0.00 |
| WC-BG | 2.82 | 10.11 | 15.14 | time_class | 2 | 0.36 | 0.18 | 0.04 | 0.96 |
| WC-UF | 24.04 | 41.07 | 65.54 | time_class | 2 | 37.00 | 18.50 | 7.16 | 0.00 |
| WC-UG | 26.80 | 22.69 | 37.08 | time_class | 2 | 8.45 | 4.23 | 1.10 | 0.34 |
| WNC-UG | 36.99 | 43.00 | 55.57 | time_class | 2 | 13.41 | 6.71 | 2.25 | 0.11 |
# wcov.pval %>%
# write_csv("output/tables/willow_cover/frequentist/aov_willcov_pval_zcond2_wcwnc.csv")
#### Frequentist AOV. Single model: WNC ~ TC*zcond2
aov_model_wcov_wcwnc <- aov(cover_transformed ~ time_class*z_cond2 + Error(1/site_id), data = cov.wc.wnc)
Model summary:
The repeated-measures ANOVA (formula: cover_transformed ~ time_class * z_cond2 + Error(1/site_id)) suggests that:
Effect sizes were labelled following Field’s (2013) recommendations.
broom::tidy(aov_model_wcov_wcwnc) %>%
mutate(across(.cols = where(is.numeric),.fns = round, 3)) %>%
gt() %>%
tab_header(title = "cover_transformed ~ time_class + z_cond2 + Error(1/site_id)", subtitle = "Combined WC and WNC")
| cover_transformed ~ time_class + z_cond2 + Error(1/site_id) | ||||||
|---|---|---|---|---|---|---|
| Combined WC and WNC | ||||||
| stratum | term | df | sumsq | meansq | statistic | p.value |
| Within | time_class | 2 | 69.203 | 34.601 | 10.534 | 0.000 |
| Within | z_cond2 | 4 | 254.848 | 63.712 | 19.397 | 0.000 |
| Within | time_class:z_cond2 | 8 | 49.106 | 6.138 | 1.869 | 0.065 |
| Within | Residuals | 250 | 821.147 | 3.285 | NA | NA |
## save as table (.csv)
# broom::tidy(aov_model_wc) %>%
# mutate(across(.cols = where(is.numeric),.fns = round, 3)) %>%
# write_csv("output/tables/aov_wc_ht_TC_fenced.csv")
#_Estimated marginal means_
emmeans (aov_model_wcwnc, ~ time_class) %>%
broom::tidy() %>%
mutate(across(where(is.numeric), round, 3)) %>%
gt()
| time_class | estimate | std.error | df | statistic | p.value |
|---|---|---|---|---|---|
| BL | 118.103 | 10.145 | 275 | 11.642 | 0 |
| 2013 | 136.237 | 9.707 | 275 | 14.035 | 0 |
| 2018 | 151.716 | 9.737 | 275 | 15.581 | 0 |
emmeans(aov_model_wcov_wcwnc, ~ z_cond2|time_class) %>%
pairs() %>%
plot() +
theme_minimal() +
geom_vline(aes(xintercept=0), color = "grey40", size=1) +
labs(x = "Contrast", y = "", caption = "cover_transformed ~ time_class + z_cond2 + Error(1/site_id)")
emmeans(aov_model_wcov_wcwnc, ~ z_cond2|time_class) %>%
pairs() %>%
as_tibble() %>%
dplyr::arrange(time_class, contrast) %>%
mutate(across(where(is.numeric), round,2)) %>%
filter(p.value <0.1) %>%
gt() %>%
tab_header(title = "cover_transformed ~ time_class + z_cond2 + Error(1/site_id)", subtitle = "Only contrasts with p <0.1 displayed. P value adjustment: tukey method for comparing estimates")
| cover_transformed ~ time_class + z_cond2 + Error(1/site_id) | ||||||
|---|---|---|---|---|---|---|
| Only contrasts with p <0.1 displayed. P value adjustment: tukey method for comparing estimates | ||||||
| contrast | time_class | estimate | SE | df | t.ratio | p.value |
| (WC-BF) - (WC-UF) | BL | -2.66 | 0.86 | 250 | -3.08 | 0.02 |
| (WC-BF) - (WC-UG) | BL | -2.64 | 0.80 | 250 | -3.31 | 0.01 |
| (WC-BF) - (WNC-UG) | BL | -3.41 | 0.76 | 250 | -4.51 | 0.00 |
| (WC-BF) - (WC-UF) | 2013 | -2.68 | 0.67 | 250 | -4.01 | 0.00 |
| (WC-BF) - (WNC-UG) | 2013 | -2.87 | 0.61 | 250 | -4.68 | 0.00 |
| (WC-BG) - (WC-UF) | 2013 | -2.82 | 0.72 | 250 | -3.90 | 0.00 |
| (WC-BG) - (WNC-UG) | 2013 | -3.01 | 0.67 | 250 | -4.48 | 0.00 |
| (WC-UG) - (WNC-UG) | 2013 | -1.41 | 0.49 | 250 | -2.87 | 0.04 |
| (WC-BF) - (WC-BG) | 2018 | 2.52 | 0.81 | 250 | 3.10 | 0.02 |
| (WC-BG) - (WC-UF) | 2018 | -3.91 | 0.78 | 250 | -5.03 | 0.00 |
| (WC-BG) - (WC-UG) | 2018 | -2.10 | 0.72 | 250 | -2.91 | 0.03 |
| (WC-BG) - (WNC-UG) | 2018 | -3.33 | 0.72 | 250 | -4.64 | 0.00 |
| (WC-UF) - (WC-UG) | 2018 | 1.80 | 0.55 | 250 | 3.26 | 0.01 |
| (WC-UG) - (WNC-UG) | 2018 | -1.22 | 0.46 | 250 | -2.63 | 0.07 |
cov.wc.wnc %>%
ggplot() +
geom_boxplot(aes(x=z_cond2, y = cover_allwillow), fill="grey80") +
facet_wrap(~time_class) +
theme_minimal() +
labs(x="Condition", y = "Mean cover", caption = "WC & WNC plots, all willow species")
cov.wc.wnc %>%
group_by(time_class, z_cond2) %>%
descr(cover_allwillow, stats = "common") %>%
tb() %>%
mutate(across(where(is.numeric), round,2)) %>%
gt() %>%
tab_header(title="Summary statistics", subtitle = "WC & WNC plots, all willow species")
| Summary statistics | |||||||||
|---|---|---|---|---|---|---|---|---|---|
| WC & WNC plots, all willow species | |||||||||
| time_class | z_cond2 | variable | mean | sd | min | med | max | n.valid | pct.valid |
| BL | WC-BF | cover_allwillow | 0.03 | 0.03 | 0.00 | 0.02 | 0.09 | 7 | 100 |
| BL | WC-BG | cover_allwillow | 0.03 | NA | 0.03 | 0.03 | 0.03 | 1 | 100 |
| BL | WC-UF | cover_allwillow | 0.24 | 0.26 | 0.01 | 0.17 | 1.00 | 12 | 100 |
| BL | WC-UG | cover_allwillow | 0.27 | 0.23 | 0.00 | 0.25 | 1.00 | 20 | 100 |
| BL | WNC-UG | cover_allwillow | 0.37 | 0.28 | 0.03 | 0.32 | 1.00 | 32 | 100 |
| 2013 | WC-BF | cover_allwillow | 0.12 | 0.21 | 0.00 | 0.04 | 0.79 | 13 | 100 |
| 2013 | WC-BG | cover_allwillow | 0.10 | 0.22 | 0.01 | 0.02 | 0.72 | 10 | 100 |
| 2013 | WC-UF | cover_allwillow | 0.41 | 0.29 | 0.02 | 0.40 | 1.00 | 17 | 100 |
| 2013 | WC-UG | cover_allwillow | 0.23 | 0.22 | 0.00 | 0.18 | 1.00 | 27 | 100 |
| 2013 | WNC-UG | cover_allwillow | 0.43 | 0.32 | 0.02 | 0.37 | 1.00 | 27 | 100 |
| 2018 | WC-BF | cover_allwillow | 0.39 | 0.29 | 0.05 | 0.26 | 1.00 | 13 | 100 |
| 2018 | WC-BG | cover_allwillow | 0.15 | 0.34 | 0.00 | 0.03 | 1.00 | 8 | 100 |
| 2018 | WC-UF | cover_allwillow | 0.66 | 0.33 | 0.14 | 0.64 | 1.00 | 17 | 100 |
| 2018 | WC-UG | cover_allwillow | 0.37 | 0.32 | 0.00 | 0.29 | 1.00 | 29 | 100 |
| 2018 | WNC-UG | cover_allwillow | 0.56 | 0.33 | 0.01 | 0.53 | 1.00 | 32 | 100 |
emmeans(aov_model_wcov_wcwnc, ~ time_class) %>%
pairs(reverse=TRUE) %>%
plot() +
theme_minimal() +
geom_vline(aes(xintercept=0), color = "grey40", size=1) +
labs(x = "Contrast", y = "", caption = "cover_transformed ~ time_class + z_cond2 + Error(1/site_id)")
emmeans(aov_model_wcov_wcwnc, ~ time_class) %>%
pairs(reverse=TRUE) %>%
as_tibble() %>%
# dplyr::arrange(p.value) %>%
mutate(across(where(is.numeric), round,2)) %>%
gt() %>%
tab_header(title = "cover_transformed ~ time_class + Error(1/site_id)", subtitle = "P value adjustment: tukey method for comparing estimates")
| cover_transformed ~ time_class + Error(1/site_id) | |||||
|---|---|---|---|---|---|
| P value adjustment: tukey method for comparing estimates | |||||
| contrast | estimate | SE | df | t.ratio | p.value |
| 2013 - BL | 0.37 | 0.46 | 250 | 0.81 | 0.7 |
| 2018 - BL | 1.50 | 0.46 | 250 | 3.23 | 0.0 |
| 2018 - 2013 | 1.12 | 0.29 | 250 | 3.88 | 0.0 |
emmeans(aov_model_wcov_wcwnc, ~ z_cond2) %>%
pairs(reverse=TRUE) %>%
plot() +
theme_minimal() +
geom_vline(aes(xintercept=0), color = "grey40", size=1) +
labs(x = "Contrast", y = "", caption = "cover_transformed ~ time_class + z_cond2 + Error(1/site_id)")
emmeans(aov_model_wcov_wcwnc, ~ z_cond2) %>%
pairs(reverse=TRUE) %>%
as_tibble() %>%
dplyr::arrange(p.value) %>%
mutate(across(where(is.numeric), round,2)) %>%
gt() %>%
tab_header(title = "cover_transformed ~ time_class + z_cond2 + Error(1/site_id)", subtitle = "P value adjustment: tukey method for comparing estimates")
| cover_transformed ~ time_class + z_cond2 + Error(1/site_id) | |||||
|---|---|---|---|---|---|
| P value adjustment: tukey method for comparing estimates | |||||
| contrast | estimate | SE | df | t.ratio | p.value |
| (WNC-UG) - (WC-BF) | 2.36 | 0.38 | 250 | 6.20 | 0.00 |
| (WC-UF) - (WC-BF) | 2.24 | 0.43 | 250 | 5.25 | 0.00 |
| (WNC-UG) - (WC-BG) | 3.05 | 0.70 | 250 | 4.38 | 0.00 |
| (WC-UF) - (WC-BG) | 2.93 | 0.72 | 250 | 4.06 | 0.00 |
| (WNC-UG) - (WC-UG) | 1.14 | 0.28 | 250 | 4.00 | 0.00 |
| (WC-UG) - (WC-BF) | 1.22 | 0.39 | 250 | 3.13 | 0.02 |
| (WC-UG) - (WC-UF) | -1.02 | 0.34 | 250 | -2.97 | 0.03 |
| (WC-UG) - (WC-BG) | 1.91 | 0.70 | 250 | 2.73 | 0.05 |
| (WC-BG) - (WC-BF) | -0.69 | 0.75 | 250 | -0.92 | 0.89 |
| (WNC-UG) - (WC-UF) | 0.12 | 0.33 | 250 | 0.36 | 1.00 |
Model summary, core winter range:
The repeated-measures ANOVA (formula: cover_transformed ~ time_class * z_cond2 + Error(1/site_id)) suggests that:
Effect sizes were labelled following Field’s (2013) recommendations.
Model summary, non-core winter range:
The repeated-measures ANOVA (formula: cover_transformed ~ time_class + Error(1/site_id)) suggests that:
Effect sizes were labelled following Field’s (2013) recommendations.
# _Separate analyses by condition class._
### create subsets of data for modeling
# pull out WK, note different years of data
cov.wk <- canopy.all.willow.sum %>%
filter(site_type == "WK") %>%
mutate(time_class = as.character(time_class)) %>%
filter(time_class == "2016" | time_class == "2017" | time_class == "2018") %>%
mutate(time_class = as.factor(time_class))
# pull out the core plus noncore winter range plots
cov.wc.wnc <- canopy.all.willow.sum %>%
filter(time_class == "BL" | time_class == "2013" | time_class == "2018") %>%
filter(site_type == "WNC" | site_type == "WC") %>%
mutate(cover_allwillow = cover_allwillow/100) %>%
filter(!is.na(cover_allwillow))
# pull out the core winter range plots
cov.wc <- canopy.all.willow.sum %>%
filter(site_type == "WC") %>%
filter(time_class == "BL" | time_class == "2013" | time_class == "2018") %>%
mutate(cover_allwillow = cover_allwillow/100) %>%
filter(!is.na(cover_allwillow))
# pull out the noncore winter range plots
cov.wnc <- canopy.all.willow.sum %>%
filter(site_type == "WNC") %>%
filter(time_class == "BL" | time_class == "2013" | time_class == "2018") %>%
mutate(cover_allwillow = cover_allwillow/100) %>%
filter(!is.na(cover_allwillow))
# model for wk
aov_model_wcov_wk <- aov(cover_transformed ~ time_class + Error(1/site_id), data = cov.wk)
Model summary, Kawuneeche Valley:
The repeated-measures ANOVA (formula: cover_transformed ~ time_class + Error(1/site_id)) suggests that:
Effect sizes were labelled following Field’s (2013) recommendations.
aov_model_wcov_wk %>%
report::report() %>%
as.data.frame() %>%
gt()
| Group | Parameter | Sum_Squares | df | Mean_Square | F | p | Eta2_partial | Eta2_partial_CI_low | Eta2_partial_CI_high |
|---|---|---|---|---|---|---|---|---|---|
| Within | time_class | 0.5346485 | 2 | 0.2673242 | 0.1208116 | 0.8868427 | 0.01193694 | 0 | 0.0802567 |
| Within | Residuals | 44.2547459 | 20 | 2.2127373 | NA | NA | NA | NA | NA |
aov_model_wcov_wk %>%
report::report_model() %>%
as.data.frame() %>%
gt()
| . |
|---|
| repeated-measures ANOVA (formula: cover_transformed ~ time_class + Error(1/site_id)) |
R version 4.0.3 (2020-10-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19041)
Run date: 2021 March 18
report::report_table(sessionInfo()) %>%
as_tibble() %>%
gt() %>%
tab_header(title="Package Information")
| Package Information | ||
|---|---|---|
| Package | Version | Reference |
| dplyr | 1.0.4 | Hadley Wickham, Romain François, Lionel Henry and Kirill Müller (2021). dplyr: A Grammar of Data Manipulation. R package version 1.0.4. https://CRAN.R-project.org/package=dplyr |
| DT | 0.17 | Yihui Xie, Joe Cheng and Xianying Tan (2021). DT: A Wrapper of the JavaScript Library 'DataTables'. R package version 0.17. https://CRAN.R-project.org/package=DT |
| emmeans | 1.5.4 | Russell V. Lenth (2021). emmeans: Estimated Marginal Means, aka Least-Squares Means. R package version 1.5.4. https://CRAN.R-project.org/package=emmeans |
| forcats | 0.5.1 | Hadley Wickham (2021). forcats: Tools for Working with Categorical Variables (Factors). R package version 0.5.1. https://CRAN.R-project.org/package=forcats |
| ggplot2 | 3.3.3 | H. Wickham. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York, 2016. |
| ggpubr | 0.4.0 | Alboukadel Kassambara (2020). ggpubr: 'ggplot2' Based Publication Ready Plots. R package version 0.4.0. https://CRAN.R-project.org/package=ggpubr |
| glue | 1.4.2 | Jim Hester (2020). glue: Interpreted String Literals. R package version 1.4.2. https://CRAN.R-project.org/package=glue |
| gt | 0.2.2 | Richard Iannone, Joe Cheng and Barret Schloerke (2020). gt: Easily Create Presentation-Ready Display Tables. R package version 0.2.2. https://CRAN.R-project.org/package=gt |
| janitor | 2.1.0 | Sam Firke (2021). janitor: Simple Tools for Examining and Cleaning Dirty Data. R package version 2.1.0. https://CRAN.R-project.org/package=janitor |
| knitr | 1.31 | Yihui Xie (2021). knitr: A General-Purpose Package for Dynamic Report Generation in R. R package version 1.31. |
| lubridate | 1.7.9.2 | Garrett Grolemund, Hadley Wickham (2011). Dates and Times Made Easy with lubridate. Journal of Statistical Software, 40(3), 1-25. URL https://www.jstatsoft.org/v40/i03/. |
| purrr | 0.3.4 | Lionel Henry and Hadley Wickham (2020). purrr: Functional Programming Tools. R package version 0.3.4. https://CRAN.R-project.org/package=purrr |
| R | 4.0.3 | R Core Team (2020). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. URL https://www.R-project.org/. |
| readr | 1.4.0 | Hadley Wickham and Jim Hester (2020). readr: Read Rectangular Text Data. R package version 1.4.0. https://CRAN.R-project.org/package=readr |
| rstatix | 0.7.0 | Alboukadel Kassambara (2021). rstatix: Pipe-Friendly Framework for Basic Statistical Tests. R package version 0.7.0. https://CRAN.R-project.org/package=rstatix |
| stringr | 1.4.0 | Hadley Wickham (2019). stringr: Simple, Consistent Wrappers for Common String Operations. R package version 1.4.0. https://CRAN.R-project.org/package=stringr |
| summarytools | 0.9.8 | Dominic Comtois (2020). summarytools: Tools to Quickly and Neatly Summarize Data. R package version 0.9.8. https://CRAN.R-project.org/package=summarytools |
| tibble | 3.0.6 | Kirill Müller and Hadley Wickham (2021). tibble: Simple Data Frames. R package version 3.0.6. https://CRAN.R-project.org/package=tibble |
| tidyr | 1.1.2 | Hadley Wickham (2020). tidyr: Tidy Messy Data. R package version 1.1.2. https://CRAN.R-project.org/package=tidyr |
| tidyverse | 1.3.0 | Wickham et al., (2019). Welcome to the tidyverse. Journal of Open Source Software, 4(43), 1686, https://doi.org/10.21105/joss.01686 |
| viridis | 0.5.1 | Simon Garnier (2018). viridis: Default Color Maps from 'matplotlib'. R package version 0.5.1. https://CRAN.R-project.org/package=viridis |
| viridisLite | 0.3.0 | Simon Garnier (2018). viridisLite: Default Color Maps from 'matplotlib' (Lite Version). R package version 0.3.0. https://CRAN.R-project.org/package=viridisLite |