prepare_shade_data <- function (parEst, parSE) {
parEst <- parEst %>%
mutate (
region = sapply (log, extract_region),
genus = sapply (species, extract_genus),
continent = ifelse (region == "europe" , "EU" , "NA" ),
species_region = paste0 (species, "_" , region)
)
shade_se <- if ("bfec.shade" %in% colnames (parSE)) {
parSE$ bfec.shade
} else {
rep (NA_real_ , nrow (parEst))
}
shade_data_raw <- tibble (
species = parEst$ species,
species_region = parEst$ species_region,
region = parEst$ region,
continent = parEst$ continent,
genus = parEst$ genus,
shade_sensitivity = parEst$ bfec.shade,
shade_se = shade_se,
n_trees = parEst$ trees,
n_treeYr = parEst$ treeYr
) %>%
filter (! is.na (region))
return (shade_data_raw)
}
filter_shade_data <- function (shade_data_raw,
min_trees = 50 ,
min_treeYr = 100 ) {
shade_data_filtered <- shade_data_raw %>%
filter (
n_trees >= min_trees,
n_treeYr >= min_treeYr
)
genera_before <- shade_data_raw %>%
count (genus, continent) %>%
pivot_wider (names_from = continent,
values_from = n,
values_fill = 0 )
genera_after <- shade_data_filtered %>%
count (genus, continent) %>%
pivot_wider (names_from = continent,
values_from = n,
values_fill = 0 )
lost_genera <- setdiff (
genera_before %>% filter (EU > 0 & NA > 0 ) %>% pull (genus),
genera_after %>% filter (EU > 0 & NA > 0 ) %>% pull (genus)
)
return (list (
shade_data_filtered = shade_data_filtered,
lost_genera = lost_genera
))
}
compare_shade_by_genus <- function (shade_data_filtered,
exclude_genera = c ("castanea" ),
min_trees_per_continent = NULL ) {
df <- shade_data_filtered %>%
filter (! genus %in% exclude_genera)
shade_by_genus_region <- df %>%
group_by (genus, continent) %>%
summarise (
shade_mean = mean (shade_sensitivity, na.rm = TRUE ),
shade_se = ifelse (n () > 1 ,
sd (shade_sensitivity, na.rm = TRUE ) / sqrt (n ()),
mean (shade_se, na.rm = TRUE )),
n_species = n (),
total_trees = sum (n_trees),
total_treeYr = sum (n_treeYr),
.groups = "drop"
)
if (! is.null (min_trees_per_continent)) {
shade_by_genus_region <- shade_by_genus_region %>%
filter (total_trees >= min_trees_per_continent) %>%
group_by (genus) %>%
filter (n () == 2 ) %>%
ungroup ()
}
shade_wide <- shade_by_genus_region %>%
pivot_wider (
names_from = continent,
values_from = c (shade_mean, shade_se,
n_species, total_trees, total_treeYr),
names_sep = "_"
) %>%
filter (! is.na (shade_mean_EU),
! is.na (shade_mean_NA)) %>%
mutate (
diff = shade_mean_EU - shade_mean_NA,
eu_more_sensitive = diff < 0
)
n_total <- nrow (shade_wide)
n_eu_more <- sum (shade_wide$ eu_more_sensitive)
binom_result <- if (n_total >= 5 ) {
binom.test (n_eu_more, n_total, p = 0.5 , alternative = "greater" )
} else NULL
return (list (
shade_wide = shade_wide,
n_genera = n_total,
n_eu_more_sensitive = n_eu_more,
binom_test = binom_result
))
}
plot_shade_sensitivity <- function (shade_comparison) {
df <- shade_comparison$ shade_wide
if (nrow (df) == 0 ) return (NULL )
lims <- range (c (df$ shade_mean_EU,
df$ shade_mean_NA),
na.rm = TRUE ) + c (- 0.3 , 0.3 )
ggplot (df, aes (x = shade_mean_NA,
y = shade_mean_EU)) +
geom_abline (slope = 1 , intercept = 0 ,
linetype = "dashed" ,
color = "gray50" ) +
geom_point (aes (color = eu_more_sensitive),
size = 3.5 ) +
coord_fixed (xlim = lims,
ylim = lims) +
scale_color_manual (
values = c ("TRUE" = "#E69F00" ,
"FALSE" = "#56B4E9" ),
labels = c ("EU more sensitive" ,
"NA more sensitive" ),
name = ""
) +
theme_bw (base_size = 12 )
}
prepare_phylo_trait_data <- function (shade_data_filtered,
traits,
tree) {
shade_by_species <- shade_data_filtered %>%
group_by (species) %>%
summarise (
shade_sensitivity = mean (shade_sensitivity, na.rm = TRUE ),
.groups = "drop"
)
phylo_data <- shade_by_species %>%
left_join (
traits %>%
select (code8, gmPerSeed, maxHt) %>%
rename (species = code8),
by = "species"
) %>%
mutate (
genus = sub ("^([a-z]+).*" , " \\ 1" , species),
epithet = tolower (sub ("^[a-z]+" , "" , species)),
tree_name = paste0 (
toupper (substr (genus, 1 , 1 )),
substr (genus, 2 , nchar (genus)),
"_" ,
epithet
)
)
return (phylo_data)
}
analyze_oak_shade <- function (shade_data_filtered) {
oak_data <- shade_data_filtered %>%
filter (genus == "quercus" )
if (nrow (oak_data) == 0 ) return (NULL )
oak_summary <- oak_data %>%
group_by (continent) %>%
summarise (
mean_shade = mean (shade_sensitivity, na.rm = TRUE ),
se_shade = sd (shade_sensitivity, na.rm = TRUE ) / sqrt (n ()),
n = n (),
total_trees = sum (n_trees),
.groups = "drop"
)
oak_eu <- oak_data$ shade_sensitivity[oak_data$ continent == "EU" ]
oak_na <- oak_data$ shade_sensitivity[oak_data$ continent == "NA" ]
t_result <- if (length (oak_eu) >= 2 && length (oak_na) >= 2 )
t.test (oak_eu, oak_na, alternative = "less" ) else NULL
wilcox_result <- if (length (oak_eu) >= 2 && length (oak_na) >= 2 )
wilcox.test (oak_eu, oak_na, alternative = "less" ) else NULL
return (list (
oak_data = oak_data,
oak_summary = oak_summary,
t_test = t_result,
wilcox_test = wilcox_result
))
}
analyze_oak_seedmass_categorical <- function (shade_data_filtered, traits) {
oak_data <- shade_data_filtered %>%
filter (genus == "quercus" ) %>%
left_join (
traits %>%
select (code8, gmPerSeed) %>%
rename (species = code8),
by = "species"
) %>%
filter (! is.na (gmPerSeed))
if (nrow (oak_data) < 6 ) return (NULL )
median_seed <- median (oak_data$ gmPerSeed, na.rm = TRUE )
oak_data <- oak_data %>%
mutate (seed_category =
ifelse (gmPerSeed > median_seed,
"Large seed" , "Small seed" ))
seed_summary <- oak_data %>%
group_by (seed_category, continent) %>%
summarise (
n = n (),
mean_shade = mean (shade_sensitivity, na.rm = TRUE ),
se_shade = sd (shade_sensitivity, na.rm = TRUE ) / sqrt (n ()),
.groups = "drop"
)
return (list (
data = oak_data,
summary = seed_summary,
median_seed = median_seed
))
}