ensemble.concave.hull {BiodiversityR}R Documentation

Analysis of Niche Overlap in Environmental Space for Changed Climates via Concave Hulls

Description

Building on methodologies described by Pironon et al. (doi:10.1038/s41558-019-0585-7), function ensemble.concave.hull constructs two hulls in environmental space for the baseline and a changed (typically a future climate, but possibly also a historical or paleo-climate) for a focal species. Functions ensemble.concave.venn and ensemble.concave.union create a third hull for candidate accessions that represent different geographies and/or different species. Subsequently overlaps between hulls are investigated. Information is also provided for each accession of the focal species in the novel climate if these are included within the hull of the candidate accessions.

Usage

ensemble.concave.hull(
    baseline.data,
    change.data,
    complete.cases = TRUE,
    VIF = TRUE, VIF.max = 20, VIF.silent = TRUE,
    method = c("rda", "pca", "prcomp"),
    ax1 = 1, ax2 = 2,
    concavity = 2.5,
    buffer.dist = NA,
    ggplot = TRUE)

ensemble.concave.venn(
    x,
    candidate.data,
    concavity = x$concavity,
    buffer.dist = x$buffer.dist,
    ggplot = TRUE,
    show.candidate.points = TRUE)

ensemble.concave.union(
    x,
    candidate.venns,
    buffer.dist = x$buffer.dist,
    ggplot = TRUE,
    show.candidate.points = TRUE)

ensemble.outliers(
    x,
    ID.var = NULL, bioc.vars = NULL,
    fence.k = 2.5, n_min = 5) 

Arguments

baseline.data

data.frame with climatic variables for the accessions in the baseline climate.

change.data

data.frame with climatic variables for the accessions in the changed (potentially future) climate.

complete.cases

Reduce cases with those without missing data via complete.cases.

VIF

Select a subset of climatic variables via ensemble.VIF.dataframe.

VIF.max

Argument setting for ensemble.VIF.dataframe.

VIF.silent

Argument setting for ensemble.VIF.dataframe.

method

Method of constructing the hulls; see details.

ax1

Idex for the first ordination axis to be analyzed; see also scores.

ax2

Index for second ordination axis to be analyzed; see also scores.

concavity

A relative measure of concavity used by concaveman.

buffer.dist

Buffer width used internally by st_buffer.

ggplot

Should a ggplot object be included in the output?

x

Output similar to those of ensemble.concave.hull.

candidate.data

data.frame with climatic variables for candidate accessions such as accessions from other geographical areas or other species.

show.candidate.points

Should the ggplot object show the locations of the candidate accessions?

candidate.venns

list with outputs from the ensemble.concave.venn function.

ID.var

Variable name used as identifier

bioc.vars

Variables included in the analysis of outliers

fence.k

Multiplier to calculate distance of observation from Interquartile lower and upper limits as used by Tukey's Fences method to detect outliers

n_min

Minimum number of variables for identifying outliers

Details

Whereas the metholology of Pironon et al. (2019) uses convex hulls, concave hulls can also be used in the methodology provided here. Convex hulls will be obtained by using large values for the concavity argument (see the description for the concaveman function). By using more concave hulls, the influence of outliers on measures of niche overlap can be reduced.

Three methods are available for mapping accessions in environmental space. Methods pca and prcomp use principal components analysis, respectively via the rda and prcomp functions. In both the methods, climatic variables are scaled. As results with pca are also rescaled via caprescale, both methods of pca and prcomp should theoretically result in the same configurations.

Method rda internally uses envfit to select a subset of climatic variables that are significantly correlated (P <= 0.05, R2 >= 0.50) with the first two axes of a redundancy analysis that uses the climate (baseline vs. changed) as predictor variable.

Candidate accessions are mapped in the environmental space created by ensemble.concave.hull via prediction methods available from predict.cca and predict.prcomp.

Function ensemble.concave.union combines candidate hulls obtained from ensemble.concave.venn, using st_union internally.

Both ensemble.concave.venn and ensemble.concave.union return measures of niche overlap based on areas of overlap between the candidate hull and the part of hull for the changed climate that is not covered by the hull for the baseline climate. These functions also indicate for each of the accessions of the focal species in the changed climate whether they occur in a novel climate (novel == TRUE; this information was obtained by ensemble.concave.hull) and whether they are inside the hull of the candidate accessions (candidate.in == TRUE).

The optional plot shows the locations of accessions for the changed climate. For ensemble.concave.hull, colouring is based on having novel climates (not occurring in the overlap between the two hulls) or not. For the other functions, locations are only shown for accessions with novel climates. Colouring is based on being inside the hull for the candidate accessions or not.

Function ensemble.outliers generalizes Tukey's fences method to require that a multivariate outlier is a univariate outlier for a minimum number of n_min variables (see )

Value

Function ensemble.concave.hull returns a list with following elements:

- rda.object: result of the ordination method used; - method: method used in the function; - baseline.hull: polygon for the hull for the baseline climate; - baseline.area: area of the baseline hull; - change.hull: polygon for the hull for the changed climate; - change.area: area of the hull for the changed climate; - overlap.hull: polygon for the overlap (intersection) of the baseline and changed hull; - overlap.area: area of the overlap hull; - novel.hull: polygon for the part of the changed hull that does not cover the baseline hull; - change.area: area of the novel hull; - buffer.dist: distance used in checking whether accessions are in novel conditions; - change.points: plotting coordinates and details on novel conditions for accessions of the changed climate; - baseline.points: plotting coordinates for accessions of the baseline climate

Author(s)

Roeland Kindt (World Agroforestry Centre) and Maarten van Zonneveld (World Vegetable Center)

References

Pironon et al. (2019). Potential adaptive strategies for 29 sub-Saharan crops under future climate change. Nat. Clim. Chang. 9: 758-736. doi:10.1038/s41558-019-0585-7

van Zonneveld et al. (2018). Tree genetic resources at risk in South America: a spatial threat assessment to prioritize populations for conservation. Diversity and Distributions 24: 718-729

van Zonneveld et al. (2023). Forgotten food crops in sub-Saharan Africa for healthy diets in a changing climate. Proceedings of the National Academy of Sciences (PNAS) 120 (14) e2205794120. doi:10.1073/pnas.2205794120

Examples


## Not run: 
library(ggplot2)
library(sf)
library(concaveman)

data(CucurbitaClim)

alata.data <- CucurbitaClim[CucurbitaClim$species == "Cucurbita_palmata", ]

bioc.names <- paste0("bioc", 1:19)

alata.data2 <- alata.data[alata.data$ADM0_A3 == "USA", ]
alata.base <- alata.data2[alata.data2$climate == "baseline", bioc.names]
alata.fut  <- alata.data2[alata.data2$climate == "future", bioc.names]

conc2.res <- ensemble.concave.hull(baseline.data=alata.base,
                                  change.data=alata.fut,
                                  method="pca",
                                  VIF.max=40,
                                  concavity=2)

plot(conc2.res$ggplot.out)
conc2.res$baseline.area
conc2.res$change.area
conc2.res$novel.area
conc2.res$novel.area / conc2.res$change.area

# Which accessions have novel climates?
summary(conc2.res$change.points)
change.points <- conc2.res$change.points
rownames(change.points[change.points$novel == TRUE, ])
nrow(change.points[change.points$novel == TRUE, ]) / nrow(change.points)

# Analysis via convex hulls
conc100.res <- ensemble.concave.hull(baseline.data=alata.base,
                                  change.data=alata.fut,
                                  method="pca",
                                  concavity=100)

plot(conc100.res$ggplot.out)
conc100.res$baseline.area
conc100.res$change.area
conc100.res$novel.area
conc100.res$novel.area / conc100.res$change.area

# Which accessions have novel climates?
summary(conc100.res$change.points)
change.points <- conc100.res$change.points
rownames(change.points[change.points$novel == TRUE, ])
nrow(change.points[change.points$novel == TRUE, ]) / nrow(change.points)

# Checking niche overlaps with other accessions
# Alternative 1: niche overlap with accessions from Mexico
alata.data2 <- alata.data[alata.data$ADM0_A3 == "MEX", ]
alata.MEX <- alata.data2[alata.data2$climate == "baseline", bioc.names]

venn2.res <- ensemble.concave.venn(conc2.res,
                                   candidate.data=alata.MEX,
                                   concavity=2)
plot(venn2.res$ggplot.out)
table(venn2.res$change.points[ , c("novel", "candidate.in")])


# alternative 1 for convex hulls
venn100.res <- ensemble.concave.venn(conc100.res,
                                   candidate.data=alata.MEX,
                                   concavity=100)
plot(venn100.res$ggplot.out)
table(venn100.res$change.points[ , c("novel", "candidate.in")])

# alternative 2: niche overlap with other species
cucurbita2 <- CucurbitaClim[CucurbitaClim$climate == "baseline", ]
cordata.data <- cucurbita2[cucurbita2$species == "Cucurbita_cordata", bioc.names]
digitata.data <- cucurbita2[cucurbita2$species == "Cucurbita_digitata", bioc.names]

venn.cordata <- ensemble.concave.venn(conc2.res,
                                      candidate.data=cordata.data,
                                      concavity=2)
plot(venn.cordata$ggplot.out)

venn.digitata <- ensemble.concave.venn(conc2.res,
                                      candidate.data=digitata.data,
                                      concavity=2)
plot(venn.digitata$ggplot.out)

# check the union of the two species
spec.res <- vector("list", 2)
spec.res[[1]] <- venn.cordata
spec.res[[2]] <- venn.digitata
union2.res <- ensemble.concave.union(conc2.res,
                                     candidate.venns=spec.res)
table(union2.res$change.points[ , c("novel", "candidate.in")])

# Analysis via convex hulls
venn.digitata <- ensemble.concave.venn(conc100.res,
                                      candidate.data=digitata.data,
                                      concavity=100)

venn.cordata <- ensemble.concave.venn(conc100.res,
                                      candidate.data=cordata.data,
                                      concavity=100)
spec.res <- vector("list", 2)
spec.res[[1]] <- venn.cordata
spec.res[[2]] <- venn.digitata

union100.res <- ensemble.concave.union(conc100.res,
                                     candidate.venns=spec.res)
plot(union100.res$ggplot.out)
table(union100.res$change.points[ , c("novel", "candidate.in")])

# Identify outliers
baseline.outliers <- ensemble.outliers(alata.base,
    bioc.vars=paste0("bioc", 1:19))
baseline.outliers[baseline.outliers$outlier == TRUE, ]


## End(Not run)


[Package BiodiversityR version 2.16-1 Index]