library("tidyverse") library("traitdata") # Match names traits = traitdata::elton_mammals names_unique = unique(traits$scientificNameStd) pb = txtProgressBar(min = 0, max = length(names_unique), style = 3) trait_names_matched = lapply(seq_along(names_unique), function(i){ tryCatch({ name = names_unique[i] setTxtProgressBar(pb, i) match_result = Symobio::gbif_match_name(name = name) if(match_result$status != "ACCEPTED"){ match_result = Symobio::gbif_match_name(usageKey = match_result$acceptedUsageKey) } match_result$name_orig = name return(match_result) }, error = function(e){ return(NULL) }) }) %>% bind_rows() close(pb) traits_matched = trait_names_matched %>% dplyr::select("name_orig", "species", "scientificName") %>% dplyr::distinct() %>% dplyr::inner_join(traits, by = c("name_orig" = "scientificNameStd")) save(traits_matched, file = "data/r_objects/traits_matched.RData") # Clean trait data diet_cols = c("Diet.Inv", "Diet.Vend", "Diet.Vect", "Diet.Vfish", "Diet.Vunk", "Diet.Scav", "Diet.Fruit", "Diet.Nect", "Diet.Seed", "Diet.PlantO") strata_cols = c("ForStrat.Value") activity_cols = c("Activity.Nocturnal", "Activity.Crepuscular", "Activity.Diurnal") bodymass_cols = c("BodyMass.Value") traits_proc = traits_matched %>% mutate(match_genus = stringr::str_detect(species, Genus), match_epithet = stringr::str_detect(species, Species)) %>% dplyr::group_by(species) %>% dplyr::group_modify(~ { if (nrow(.x) == 1) { return (.x) } x_mod = .x while (nrow(x_mod) > 1){ if(any(isFALSE(x_mod$match_genus))){ x_mod = dplyr::filter(x_mod, isTRUE(match_genus)) next } if(any(isFALSE(x_mod$match_epithet))){ x_mod = dplyr::filter(x_mod, isTRUE(match_epithet)) next } x_mod = x_mod[1,] } if(nrow(x_mod) == 1){ return(x_mod) } else { return(.x[1,]) } }) %>% dplyr::select(c("species", diet_cols, strata_cols, activity_cols, bodymass_cols)) save(traits_proc, file = "data/r_objects/traits_proc.RData") # Calculate Distances library("vegan") load("data/r_objects/range_maps.RData") load("data/r_objects/traits_proc.RData") target_species = unique(range_maps$name_matched[!is.na(range_maps$name_matched)]) traits_target = dplyr::filter(traits_proc, species %in% target_species) # some pre-processing traits_target$`ForStrat.Value` = as.numeric(factor(traits_target$`ForStrat.Value`, levels = c("G", "S", "Ar", "A"))) traits_target$`BodyMass.Value` = scale(log(traits_target$`BodyMass.Value`)) diet_dist = vegan::vegdist(traits_target[,diet_cols], "bray") foraging_dist = dist(traits_target[,strata_cols]) activity_dist = vegan::vegdist(traits_target[,activity_cols], "bray") bodymass_dist = dist(traits_target[,bodymass_cols]) func_dist = (diet_dist + foraging_dist/max(foraging_dist) + activity_dist + bodymass_dist/max(bodymass_dist)) / 4 names(func_dist) = traits_target$species func_dist = as.matrix(func_dist) save(func_dist, file = "data/r_objects/func_dist.RData")