## ----setup, include=FALSE----------------------------------------------------- knitr::opts_chunk$set(echo = TRUE) ## ----------------------------------------------------------------------------- species_df = data.frame( species = c("a", "b", "c"), trait_value = c(-1, 0, 0.5) ) species_distance = dist(c(a = -1, b = 0, c = 0.5)) species_distance ## ----new_distinctiveness------------------------------------------------------ alternative_distinctiveness = function(pres_mat, distance_obj, given_T) { dist_mat = as.matrix(distance_obj) kept_sp = funrar:::species_in_common(pres_mat, dist_mat) dist_mat = dist_mat[kept_sp, kept_sp, drop = FALSE] # Correspondence matrix (tracking which species we want to keep) corr_dist = dist_mat corr_dist[dist_mat > given_T] = 0 corr_dist[dist_mat <= given_T] = 1 diag(corr_dist) = 0 # Across sites # given_pres is a vector of presences per site di_mat = apply(pres_mat, 1, function(given_pres) { # Sum of distances per species index_mat = given_pres %*% (dist_mat * corr_dist) # Number of distances considered per species denom_mat = given_pres %*% corr_dist index_mat = index_mat / denom_mat index_mat[given_pres == 0] = NA index_mat[is.nan(index_mat)] = 1 return(index_mat) }) di_mat = t(di_mat) dimnames(di_mat) = dimnames(pres_mat) di_df = funrar::matrix_to_stack(di_mat, "Di") di_df$given_range = given_T return(di_df) } ## ----------------------------------------------------------------------------- presence_matrix = matrix(c(rep(1, 3), 1, 0, 1, 1, 1, 0), nrow = 3, ncol = 3, dimnames = list(site = c("s1", "s2", "s3"), species = c("a", "b", "c"))) # Test over a ragne of possible T values all_T = lapply(seq(0.5, 1.5, length.out = 50), function(given_number) alternative_distinctiveness( presence_matrix, species_distance, given_number)) all_T = do.call(rbind.data.frame, all_T) ## ----------------------------------------------------------------------------- library(ggplot2) ggplot(all_T, aes(given_range, Di, color = species)) + geom_line(size = 1, alpha = 1/2) + facet_grid(~site) + labs(x = "Fixed distance range", y = "Functional Distinctiveness", color = "Species") ## ----aravo_new_distinct------------------------------------------------------- library("funrar") data("aravo", package = "ade4") # Site-species matrix mat = as.matrix(aravo$spe) # Convert matrix to presence-absence matrix mat[mat > 0] = 1 # Example of trait table tra = aravo$traits[, c("Height", "SLA", "N_mass")] # Distance matrix dist_mat = compute_dist_matrix(tra, metric = "gower") dist_mat = (dist_mat - min(dist_mat))/diff(range(dist_mat)) names(dimnames(mat)) = c("site", "species") # Compute different values of distinctiveness using various ranges all_ranges = lapply(seq(0, 1, length.out = 50), function(given_range) { alternative_distinctiveness(mat, as.dist(dist_mat), given_range) }) all_ranges = do.call(rbind.data.frame, all_ranges) ## ----------------------------------------------------------------------------- ggplot(subset(all_ranges, site %in% c("AR07", "AR51", "AR02")), aes(given_range, Di, group = species)) + geom_line(alpha = 1/3) + facet_wrap(~site) + labs(x = "Maximum Distance Range Considered\n(Trait Range)", y = "Functional Distinctiveness") ## ----scaled_range------------------------------------------------------------- all_ranges$scaled_Di = ifelse( all_ranges$Di != 1, all_ranges$Di / all_ranges$given_range, all_ranges$Di) ggplot(subset(all_ranges, site %in% c("AR07", "AR51", "AR02")), aes(given_range, scaled_Di, group = species)) + geom_line(alpha = 1/4) + facet_wrap(~site) + labs(x = "Considered Trait Range\n(Functional Distance)", y = "Scaled Functional Distinctiveness\n(over trait range)") ## ----new_distinctiveness_ab--------------------------------------------------- ab_mat = matrix( c(rep(1/3, 3), 1/6, 1/6, 4/6, 4/6, 1/6, 1/6), nrow = 3, ncol = 3, dimnames = list(site = c("s1", "s2", "s3"), species = c("a", "b", "c")), byrow = TRUE ) alternative_distinctiveness_abundance = function(abund_mat, dist_matrix, given_range) { dist_mat = dist_matrix kept_sp = funrar:::species_in_common(abund_mat, dist_mat) dist_mat = dist_mat[kept_sp, kept_sp, drop = FALSE] # Correspondence matrix (tracking which species we want to keep) corr_dist = dist_mat corr_dist[dist_mat > given_range] = 0 corr_dist[dist_mat <= given_range] = 1 diag(corr_dist) = 0 # Across sites # given_pres is a vector of presences per site di_mat = apply(abund_mat, 1, function(given_ab) { # Sum of distances per species index_mat = given_ab %*% (dist_mat * corr_dist) # Number of distances considered per species denom_mat = given_ab %*% corr_dist index_mat = (index_mat / denom_mat) * (1 - denom_mat) index_mat[given_ab == 0 | is.na(given_ab)] = NA index_mat[is.nan(index_mat)] = 1 return(index_mat) }) di_mat = t(di_mat) dimnames(di_mat) = dimnames(abund_mat) di_df = funrar::matrix_to_stack(di_mat, "Di") di_df$given_range = given_range return(di_df) } ## ----------------------------------------------------------------------------- ab_di_all_ranges = lapply( seq(0, 1.5, length.out = 50), function(given_number) alternative_distinctiveness_abundance( ab_mat, as.matrix(species_distance), given_number ) ) ab_di_all_ranges = do.call(rbind.data.frame, ab_di_all_ranges) ggplot(ab_di_all_ranges, aes(given_range, Di, color = species)) + geom_line(size = 1) + facet_wrap( ~site, labeller = as_labeller( c(s1 = "s1 (1/3 rel. abund each)", s2 = "s2 (a=1/6, b=1/6, c=4/6)", s3 = "s3 (a=4/6, b=1/6, c=1/6)") ) ) + labs(x = "Considered Range", y = "Functional Distinctiveness")