--- title: "How to Deal With Functional Entities" author: "Camille Magneville" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{How to Deal With Functional Entities} %\VignetteEngine{knitr::rmarkdown} \usepackage[utf8]{inputenc} ---
# 1. Why Functional Entities (FEs)?
`mFD` allows gathering species into **functional entities (FEs)** *i.e.* **groups of species with same trait values** when many species are described with a few categorical or ordinal traits. It is particularly useful when using large datasets with "functionally similar" species. FEs also allow to understand the links between functional diversity and ecological processes as redundant species that are supposed to have similar ecological roles are clustered in this method.
# 2. Tutorial's data
**DATA** The dataset used to illustrate this tutorial is a **fruits dataset** based on 25 types of fruits (*i.e.* species) distributed in 10 fruit baskets (*i.e.* assemblages). Each fruit is characterized by six trait values summarized in the following table:
| Trait name | Trait measurement | Trait type | Number of classes | Classes code | Unit | |:-------------:|:------------------:|:-------------:|:-------------------:|:----------------------:|:-----:| | Size | Maximal diameter | Ordinal | 5 | small ; medium ; large | cm | | Plant | Growth form | Categorical | 4 | tree ; not tree | NA | | Climate | Climatic niche | Ordinal | 3 | temperate ; tropical | NA | | Seed | Seed type | Ordinal | 3 | none ; pip ; pit | NA |
**NOTE** We reduced the dataset used in [mFD General Workflow](https://cmlmagneville.github.io/mFD/articles/mFD_general_workflow.html) to only keep ordinal and categorical traits. Categorical traits are restrained to 2 or 3 modalities per traits to limit the number of unique combinations.
The following data frame and matrix are needed: * the data frame summarizing traits values for each species called *fruits_traits* data frame in this tutorial:
```{r} data("fruits_traits", package = "mFD") fruits_traits <- fruits_traits[ , 1:4] # only keep the first 4 traits to illustrate FEs # Decrease the number of modalities per trait for convenience ... # ... (to have less unique combinations of trait values): # Size grouped into only 3 categories: fruits_traits[ , "Size"] <- as.character(fruits_traits[ , "Size"]) fruits_traits[which(fruits_traits[ , "Size"] %in% c("0-1cm", "1-3cm", "3-5cm")), "Size"] <- "small" fruits_traits[which(fruits_traits[ , "Size"] == "5-10cm"), "Size"] <- "medium" fruits_traits[which(fruits_traits[ , "Size"] == "10-20cm"), "Size"] <- "large" fruits_traits[ , "Size"] <- factor(fruits_traits[, "Size"], levels = c("small", "medium", "large"), ordered = TRUE) # Plant type grouped into only 2 categories: fruits_traits[ , "Plant"] <- as.character(fruits_traits[, "Plant"]) fruits_traits[which(fruits_traits[ , "Plant"] != "tree"), "Plant"] <- "Not_tree" fruits_traits[ , "Plant"] <- factor(fruits_traits[ , "Plant"], levels = c("Not_tree", "tree"), ordered = TRUE) # Plant Origin grouped into only 2 categories: fruits_traits[ , "Climate"] <- as.character(fruits_traits[ , "Climate"]) fruits_traits[which(fruits_traits[ , "Climate"] != "temperate"), "Climate"] <- "tropical" fruits_traits[ , "Climate"] <- factor(fruits_traits[, "Climate"], levels = c("temperate", "tropical"), ordered = TRUE) # Display the table: knitr::kable(head(fruits_traits), caption = "Species x traits dataframe based on *fruits* dataset") ```
* the matrix summarizing assemblages called *basket_fruits_weights* in this tutorial:
```{r} data("baskets_fruits_weights", package = "mFD") knitr::kable(as.data.frame(baskets_fruits_weights[1:6, 1:6]), caption = "Species x assemblages dataframe based on *fruits* dataset") ```
* the data frame summarizing traits categories called *fruits_traits_cat* in this tutorial: (for details: [mFD General Workflow](https://cmlmagneville.github.io/mFD/articles/mFD_general_workflow.html))
```{r} data("fruits_traits_cat", package = "mFD") # only keep traits 1 - 4: fruits_traits_cat <- fruits_traits_cat[1:4, ] knitr::kable(head(fruits_traits_cat), caption = "Traits types based on *fruits & baskets* dataset") ```
Using the `mFD::asb.sp.summary()` function, we can sum up the assemblages data and retrieve species occurrence data:
```{r} # summarize species assemblages: asb_sp_fruits_summ <- mFD::asb.sp.summary(baskets_fruits_weights) # retrieve species occurrences for the first 3 assemblages (fruits baskets): head(asb_sp_fruits_summ$asb_sp_occ, 3) asb_sp_fruits_occ <- asb_sp_fruits_summ$"asb_sp_occ" ```
# 3. Gather species into FEs
`mFD` allows you to gather species into FEs using the `mFD::sp.to.fe()` function. It uses the following arguments:
**USAGE** ```{r, results = "hide", eval = FALSE} mFD::sp.to.fe( sp_tr = fruits_traits, tr_cat = fruits_traits_cat, fe_nm_type = "fe_rank", check_input = TRUE) ```
* *sp_tr* the data frame of species traits * *tr_cat* the data frame summarizing traits categories * *fe_nm_type* is a character string referring to the way FEs should be named: they can be named after their decreasing rank in term of number of species (*i.e. fe_1 is the one gathering most species*) (*fe_rank*) or they can be named after names of traits * *check_input* is a logical value reflecting whether inputs should be checked or not. Possible error messages will thus be more understandable for the user than R error messages **NOTE** Recommendation: set it as `TRUE` Let's use this function with the *fruits dataset*:
```{r} sp_to_fe_fruits <- mFD::sp.to.fe( sp_tr = fruits_traits, tr_cat = fruits_traits_cat, fe_nm_type = "fe_rank", check_input = TRUE) ```
`mFD::sp.to.fe()` returns: * a vector containing FEs names:
```{r} sp_to_fe_fruits$"fe_nm" ```
* a vector containing for each species, the FE it belongs to:
```{r} sp_fe <- sp_to_fe_fruits$"sp_fe" sp_fe ```
* a data frame containing for FEs, the values of traits for each FE:
```{r} fe_tr <- sp_to_fe_fruits$"fe_tr" fe_tr ```
* a vector containing the number of species per FE:
```{r} fe_nb_sp <- sp_to_fe_fruits$"fe_nb_sp" fe_nb_sp ```
* a detailed list containing vectors or list with supplementary information about FEs:
```{r} sp_to_fe_fruits$"details_fe" ```
# 4. Compute alpha and beta functional indices
Then based on the data frame containing the value of traits for each FE, the workflow is the same as the one listed in [mFD General Workflow](https://cmlmagneville.github.io/mFD/articles/mFD_general_workflow.html) to compute functional trait based distance, multidimensional functional space and associated plots and compute alpha and beta functional indices (step 3 till the end). It will thus not be summed up in this tutorial.
`mFD` also allows to compute functional indices based on FEs following the framework proposed in [Mouillot _et al._ 2014](https://www.pnas.org/doi/abs/10.1073/pnas.1317625111)) using the `mFD::alpha.fd.fe()` function. It computes: * *Functional Redundancy* that reflects the average number of species per FE * *Functional Overredundancy* that reflects the proportion of species in excess in species-rich FE *ie* it represents the percentage of species that fill functional entities above the mean level of functional redundancy * *Functional Vulnerability* that reflects the proportion of FE with only one species
`mFD::alpha.fd.fe()` function is used as follows:
**USAGE** ```{r, results = "hide", eval = FALSE} mFD::alpha.fd.fe( asb_sp_occ = asb_sp_fruits_occ, sp_to_fe = sp_to_fe_fruits, ind_nm = c("fred", "fored", "fvuln"), check_input = TRUE, details_returned = TRUE) ```
It takes as inputs: * *asb_sp_occ* the assemblages-species occurrence dataframe retrieved on **step 2** with `mFD::sp.tr.summary()` function * *sp_to_fe* a list with details of species clustering into FE from `mFD::sp.to.fe()` * *ind_nm* a vector referring to the indices to compute: *fred* for Functional Redundancy, *fored* for Functional Overredundancy and *fvuln* for Functional Vulnerability. * *check_input* is a logical value reflecting whether inputs should be checked or not. Possible error messages will thus be more understandable for the user than R error messages **NOTE** Recommendation: set it as `TRUE`. * *details_returned* is a logical value indicating whether the user wants to details_returned. Details are used in graphical functions and thus must be kept if the user want to have graphical outputs for the computed indices.
Let's apply this function with the *fruits* dataset:
```{r} alpha_fd_fe_fruits <- mFD::alpha.fd.fe( asb_sp_occ = asb_sp_fruits_occ, sp_to_fe = sp_to_fe_fruits, ind_nm = c("fred", "fored", "fvuln"), check_input = TRUE, details_returned = TRUE) ```
This function returns a dataframe of indices values for each assemblage and a detailed list containing a matrix gathering the number of species per FE in each assemblage:
```{r} # dataframe with indices values for each assemblage: alpha_fd_fe_fruits$"asb_fdfe" # a matrix gathering the number of species per FE in each assemblage alpha_fd_fe_fruits$"details_fdfe" ```
# 5. Plot functional indices based on FEs
Then, it is possible to have a graphical representation of FE-based indices for a given assemblage using the `mFD::alpha.fe.fd.plot()` function:
**USAGE** ```{r, results = FALSE, eval = FALSE} mFD::alpha.fd.fe.plot( alpha_fd_fe = alpha_fd_fe_fruits, plot_asb_nm = c("basket_1"), plot_ind_nm = c("fred", "fored", "fvuln"), name_file = NULL, color_fill_fored = "darkolivegreen2", color_line_fred = "darkolivegreen4", color_fill_bar = "grey80", color_fill_fvuln = "lightcoral", color_arrow_fvuln = "indianred4", size_line_fred = 1.5, size_arrow_fvuln = 1, check_input = TRUE) ```
This function takes as inputs: * *alpha_fe_fe_fruits* the output from the function `mFD::alpha.fd.fe()` applied on assemblage of interest with `details_returned = TRUE` * *plot_asb_nm* a vector containing the name of the assemblage to plot * *plot_ind_nm* a vector containing the names of the indices to plot. It `fred` to plot functional redundancy (FRed), `fored` to plot functional over-redundancy (FOred) and/or `fvuln` to plot functional vulnerability (FVuln) * *name_file* a character string with name of file to save the figure. If set to `NULL` the plot is only displayed * inputs to personalize the plot (for details: see help file of the `mFD::alpha.fd.fe.plot`) * *check_input* is a logical value reflecting whether inputs should be checked or not. Possible error messages will thus be more understandable for the user than R error messages **NOTE** Recommendation: set it as `TRUE`
For the studied example, the plot looks as follows:
``` {r, fig.height = 7, fig.width = 12, fig.align = "center"} mFD::alpha.fd.fe.plot( alpha_fd_fe = alpha_fd_fe_fruits, plot_asb_nm = c("basket_1"), plot_ind_nm = c("fred", "fored", "fvuln"), name_file = NULL, color_fill_fored = "darkolivegreen2", color_line_fred = "darkolivegreen4", color_fill_bar = "grey80", color_fill_fvuln = "lightcoral", color_arrow_fvuln = "indianred4", size_line_fred = 1.5, size_arrow_fvuln = 1, check_input = TRUE) ```
All FE except "fe_3" contain only one species thus FRed and FVuln are close to 1. Only "fe_3" has more species than the average number of species thus the proportion of species in excess in FE richer than average is quite low (FORed = 0.107).
# References
- Mouillot _et al._ (2014) Functional over-redundancy and high functional vulnerability in global fish faunas on tropical reefs. _PNAS_, **38**, 13757-13762.