This function calculates a single O-statistic across multiple traits by estimating hypervolumes for each species in multivariate trait space that contain the trait values for all the individuals in each species. It uses a stochastic estimation procedure implemented in the R package hypervolume. The community-level O-statistics estimated from the hypervolume overlaps can be evaluated against a null model.

Ostats_multivariate(
  traits,
  plots,
  sp,
  output = "median",
  weight_type = "hmean",
  run_null_model = TRUE,
  nperm = 99,
  nullqs = c(0.025, 0.975),
  shuffle_weights = FALSE,
  swap_means = FALSE,
  random_seed = NULL,
  hypervolume_args = list(),
  hypervolume_set_args = list(),
  verbose = FALSE
)

Arguments

traits

matrix of trait measurements. The number of rows in the matrix is the number of individuals, and the number of columns of the matrix is the number of traits.

plots

a factor with length equal to nrow(traits) that indicates the community each individual belongs to.

sp

a factor with length equal to nrow(traits) that indicates the taxon of each individual.

output

specifies whether median or mean is calculated.

weight_type

specifies weights to be used to calculate the median or mean.

run_null_model

whether to run a null model (if TRUE) and evaluate the O-statistics against it, or simply return the raw O-statistics (if FALSE). Defaults to TRUE.

nperm

the number of null model permutations to generate. Defaults to 99.

nullqs

numeric vector of probabilities with values in [0,1] to set effect size quantiles. Defaults to c(0.025, 0.975).

shuffle_weights

If TRUE, shuffle weights given to pairwise overlaps within a community when generating null models.

swap_means

If TRUE, swap means of body sizes within a community when generating null models.

random_seed

User may supply a random seed to enable reproducibility of null model output. A warning is issued, and a random seed is generated based on the local time, if the user does not supply a seed.

hypervolume_args

additional arguments to pass to hypervolume, such as method. If none are provided, default values are used. By default, method = "gaussian".

hypervolume_set_args

additional arguments to pass to hypervolume_set, such as num.points.max. If none are provided, default values are used.

verbose

If TRUE, progress messages are displayed. Defaults to FALSE.

Value

The function returns a list containing four objects:

overlaps_norm

a matrix showing the O-statistic for each community, with the area under all density functions normalized to 1.

overlaps_unnorm

a matrix showing O-stats calculated with the area under all density functions proportional to the number of observations in that group.

overlaps_norm_ses

List of matrices of effect size statistics against a null model with the area under all density functions normalized to 1. ses contains the effect sizes (z-scores), ses_lower contains the effect size lower critical values for significance at the level determined by nullqs, and ses_upper contains the upper critical values. raw_lower and raw_upper are the critical values in raw units ranging from 0 to 1.

overlaps_unnorm_ses

List of matrices of effect size statistics against a null model with the area under all density functions proportional to the number of observations in that group. Elements are as in overlaps_norm_ses.

Details

This function calculates multivariate O-statistics and optionally evaluates them against a local null model. By default, it calculates the median of pairwise hypervolume overlaps, weighted by harmonic mean of species abundaces of the species pairs in each community. Two results are produced, one normalizing the area under all density functions to 1, the other making the area under all density functions proportional to the number of observations in that group.

Functions from the R package hypervolume by Blonder and colleagues (Blonder 2018) are used internally. The function hypervolume stochastically estimates hypervolumes for each species in each community, and the function hypervolume_set finds the proportional overlap between each pair of hypervolumes.

If run_null_model is TRUE, the O-statistics are evaluated relative to a null model. When both shuffle_weights and swap_means are FALSE, null communities are generated by randomly assigning a taxon that is present in the community to each individual. If shuffle_weights is TRUE, species abundances are also randomly assigned to each species to weight the O-statistic for each null community. If swap_means is TRUE, instead of sampling individuals randomly, species means are sampled randomly among species, keeping the deviation of each individual from its species mean the same. After the null communities are generated, O-stats are calculated for each null community to compare with the observed O-stat.

Effect size statistics are calculated by z-transforming the O-statistics using the mean and standard deviation of the null distribution.

References

Blonder, B. Hypervolume concepts in niche- and trait-based ecology. Ecography 41, 1441–1455 (2018). https://doi.org/10.1111/ecog.03187

See also

Ostats for univariate data.

Ostats_multivariate_plot for plotting multivariate trait overlap in each community.

Examples

if (FALSE) {
# overlap statistic between populations of pitcher plants at two different sites

# Select two sites and three dimensions and scale data
site_index <- pitcher_traits[, 'site_id'] %in% c('FLK', 'MYR')
dat <- as.matrix(pitcher_traits[site_index,
                               c('rosette_diameter_1', 'pitcher_width', 'mouth_diameter')])
dat <- scale(dat, center = TRUE, scale = TRUE)

# Here a low number is used for num.points.max for example purposes
Ostats_multi_example <- Ostats_multivariate(traits = dat,
                                            plots = factor(rep(1, nrow(dat))),
                                            sp = factor(pitcher_traits$site_id[site_index]),
                                            random_seed = 111,
                                            run_null_model = FALSE,
                                            hypervolume_args = list(method = 'box'),
                                            hypervolume_set_args = list(num.points.max = 100)
)
}