--- title: "Macroecological analysis at the species level" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{species-level-macroecological-analysis} %\VignetteEncoding{UTF-8} %\VignetteEngine{knitr::rmarkdown} editor_options: chunk_output_type: console --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.height = 5, fig.width = 6, fig.align = 'center') ``` In another post, I have shown how to use [`letsR`](https://besjournals.onlinelibrary.wiley.com/doi/abs/10.1111/2041-210X.12401) to analyze species traits at the community level. But, in many cases this type of analysis can lead to spurious patterns ([click here for further discussion on this issue](https://onlinelibrary.wiley.com/doi/full/10.1111/jbi.12953)). An alternative can be analyzing the data at the species-level. In this post, I will show two examples on how to make macroecological analysis at the species level using the `letsR` package. In the first example, we will continue the test of Rapoport's rule on Phyllomedusa frogs using species centroids. In the second example, we will summarize climate spatial data at the species level to explore how temperature correlates with Phyllomedusa species extinction risk. To start this test we can load our example `PresenceAbsence` object. *Note: I recommend to use the latest version of the `letsR` package on [GitHub](https://github.com/macroecology/letsR)* ```{r, message = FALSE, warning = FALSE, r, fig.width = 4} # Load the package library(letsR) # Load the data data("PAM") # Plot plot(PAM) ``` ## Example 1: Species level test of Rapoport's rule on Phyllomedusa frogs. We first have to calculate species range size. We can do it directly on the species shapefiles for higher precision. ```{r} data("Phyllomedusa") rangesize <- lets.rangesize(Phyllomedusa, coordinates = "geographic") rangesize <- rangesize / 1000 # Transform in km2 ``` The second step is to calculate species geographical centroid/midpoint using the function `lets.midpoint`. There are several ways to calculate species geographic centroid, and this function offers several methods to do it. When species range are both circular and continuous, all of the methods will provide the same answer. However, as the shape of distributions start to become more complex, different methods will provide very different answers. For this example, we will use the default option "PC" (polygon centroid). This method will generate a polygon from the raster, and calculate the centroid of this polygon. ```{r} centroids <- lets.midpoint(PAM) ``` ```{r, message=FALSE, warning=FALSE, echo=FALSE} library(knitr) library(dplyr) library(kableExtra) ``` ```{r, eval=FALSE} centroids ``` ```{r, echo = FALSE} kable(centroids, "html") %>% kable_styling() %>% scroll_box(width = "600px", height = "400px") ``` We can also plot the geographical centroids. ```{r} d <- data.frame(centroids[, 2:3], "Species" = centroids[, 1], "Range size" = rangesize) sp <- terra::vect(x = d, geom = c("x", "y")) plot(sp) plot(sf::st_geometry(wrld_simpl), add = TRUE) ``` To check the Rapoport's rule we can plot the latitude against the range size: ```{r, message = FALSE, warning=FALSE} library(ggplot2) ``` ```{r, message=F} data_plot <- data.frame(centroids[, 2:3], "Range size" = rangesize) g <- ggplot(data_plot, aes(x, Range_size)) g + geom_smooth() + geom_point() + labs(x = "Latitude(x)", y = "Range size") ``` Again, the data indicate that Rapoport's rule does not apply for Phyllomedusa genus. However, there seems to be an interesting pattern where range size decreases from the center towards the extremes of the group. This could be an effect of niche conservatism, where species in the extreme latitude would face very different conditions from the ancestral Phylllomedusa. Another possibility is that this pattern could be due to the shape of the continent, where extreme latitudes means smaller longitudes. ## Example 2: Extinction risk correlation with temperature To evaluate how temperature correlates with extinction risk, we first have to add the temperature variable to the `PresenceAbsence` object. ```{r} data(temp) r <- terra::unwrap(temp) PAM_env <- lets.addvar(PAM, r, fun = mean) ``` Next step is to get the average temperature values per species. The `lets.summarizer` can do this directly on the resulting object of `lets.addvar` function (note that this can only be done if `onlyvar = FALSE`). We only have to indicate the position of the variable in the matrix using the argument `pos`. ```{r} pos <- which(colnames(PAM_env) == "wc2.1_10m_bio_1_mean") temp_mean <- lets.summarizer(PAM_env, pos) ``` ```{r, eval=FALSE} temp_mean ``` ```{r, echo = FALSE} kable(temp_mean, "html") %>% kable_styling() %>% scroll_box(width = "400px", height = "400px") ``` Following our example, we need to obtain the IUCN extinction risk data. Previous version of the package included functions to do this, but they are no longer supported. Luckily, there is a new package called [`rredlist`](https://docs.ropensci.org/rredlist/) that can do this for us. Yet, for now, we can use the example data in the `letsR` package called `IUCN`. ```{r} data("IUCN") ``` ```{r, eval=FALSE} IUCN ``` ```{r, echo = FALSE} kable(IUCN, "html") %>% kable_styling() %>% scroll_box(width = "800px", height = "400px") ``` Finally, we can verify the relationship between temperature and extinction risk. ```{r} level_order <- c("DD", "LC", "EN", "CR") # ordering for the plot data <- data.frame("Status" = factor(IUCN$Status, levels = level_order), "Temperature" = temp_mean[, 2] / 10) g <- ggplot(data, aes(Status, Temperature)) g + geom_boxplot() + coord_flip() ``` The graph indicate that there is a tendency for threatened Phyllomedusa species to occur in colder regions. Still, further statistical analysis should be done to confirm this pattern. **To cite letsR in publications use:** *Bruno Vilela and Fabricio Villalobos (2015). letsR: a new R package for data handling and analysis in macroecology. Methods in Ecology and Evolution. DOI: 10.1111/2041-210X.12401*