diff --git a/DESCRIPTION b/DESCRIPTION index 3dcf8e6..dc2c3cd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,17 +1,16 @@ Package: mobr Title: Measurment of Biodiveristy in R -Version: 0.1 +Version: 1.0 Authors@R: c(person("Xiao", "Xiao", email="xiao@weecology.org", role = c("aut", "cre")), person("Daniel", "McGlinn", email="danmcglinn@gmail.com", role = c("aut")), person("Felix", "May", email="felix.may@idiv.de", rol=c("aut"))) -Date: 2015 +Date: 2017 Description: This package is designed to help measure biodiversity and its changes across scales. Depends: R (>= 3.0.2), - Jade, pracma, scales, dplyr @@ -21,8 +20,6 @@ Imports: Suggests: knitr, rmarkdown -Remotes: - JohnsonHsieh/Jade, License: MIT LazyData: true RoxygenNote: 6.0.1 diff --git a/NAMESPACE b/NAMESPACE index b120c4a..faea0ec 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -12,14 +12,12 @@ export(make_mob_in) export(overlap_effects) export(permute_comm) export(plot_N) -export(plot_SNpie) export(plot_abu) +export(plot_rarefaction) export(rarefaction) -importFrom(Jade,SpecDist) importFrom(grDevices,rainbow) importFrom(graphics,par) importFrom(graphics,plot) importFrom(graphics,polygon) importFrom(pracma,pchip) -importFrom(rgl,plot3d) importFrom(scales,alpha) diff --git a/R/mobr.R b/R/mobr.R index 1a9844b..43fb058 100644 --- a/R/mobr.R +++ b/R/mobr.R @@ -216,7 +216,10 @@ rarefaction = function(x, method, effort=NULL, xy_coords=NULL, latlong=FALSE, n = sum(x) } if (is.null(effort)) - effort = 1:n + if (n == 0) + effort = 0 + else + effort = 1:n effort_names = effort if (any(effort > n)) { warning('"effort" larger than total number of samples') @@ -887,7 +890,7 @@ effect_agg_discrete = function(out, mob_in, ref_group, group_plots, group_data, #' the position of the points. If log_scale is TRUE, the points are equally #' spaced on logarithmic scale. If it is FALSE (default), the points are #' equally spaced on arithmetic scale. -#' @param min_plot minimal number of plots for test 'agg', where plots are +#' @param min_plots minimal number of plots for test 'agg', where plots are #' randomized within groups as null test. If it is given a value, all groups #' with fewer plots than min_plot are removed for this test. If it is NULL #' (default), all groups are kept. Warnings are issued if 1. there is only one @@ -1107,21 +1110,25 @@ pairwise_t = function(dat_sp, dat_plot, groups, lower_N = NA) { #' @param pooled boolean specifying if abundances should be pooled at the group level or #' not #' @param col optional vector of colors. -#' @param log specify which axes to apply log transformations to. +#' @param lwd a vector of line widths, see \code{\link[graphics]{par}}. +#' @param leg_loc the location of the legend. Defaults to 'topleft', +#' see \code{\link[graphics]{legend}}. +#' @inheritParams graphics::plot.default #' @importFrom scales alpha #' @export #' @examples #' data(inv_comm) #' data(inv_plot_attr) #' inv_mob_in = make_mob_in(inv_comm, inv_plot_attr) -#' plot_abu(inv_mob_in, 'group', 'sad', pooled=F, log='x') -#' plot_abu(inv_mob_in, 'group', 'rad', pooled=T, log='x') -plot_abu = function(mob_in, env_var, type=c('sad', 'rad'), pooled=FALSE, - col=NA, log='', leg_loc = 'topleft') { +#' plot_abu(inv_mob_in, 'group', 'uninvaded', 'sad', pooled=F, log='x') +#' plot_abu(inv_mob_in, 'group', 'uninvaded', 'rad', pooled=T, log='x') +plot_abu = function(mob_in, env_var, ref_group, type=c('sad', 'rad'), pooled=FALSE, + col=NULL, lwd=1, log='', leg_loc = 'topleft') { env_data = mob_in$env[ , env_var] - grps = unique(env_data) - if (is.na(col[1])) - col = rainbow(length(grps)) + grps = unique(as.character(env_data)) + grps = c(ref_group, sort(grps[grps != ref_group])) + if (is.null(col)) + col = c("#FFC000", "#2B83BA", rainbow(10))[1:length(grps)] else if (length(col) != length(grps)) stop('Length of col vector must match the number of unique groups') if ('sad' == type) { @@ -1175,41 +1182,85 @@ plot_abu = function(mob_in, env_var, type=c('sad', 'rad'), pooled=FALSE, legend(leg_loc, legend=grps, col = col, lwd = 2, bty='n') } - -#' Create 3d plot of richness, abundance, and probability of interspecific -#' encounter +#' Plot rarefaction curves for each treatment group #' -#' @param mob_in a 'mob_in' class object produced by 'make_mob_in' -#' @param env_var a string that specifies the column name in mob_in$env that -#' specifies the grouping variable. -#' @param col optional vector of colors. -#' @importFrom rgl plot3d +#' @param pooled boolean specifying if samples should be pooled at the group +#' level or not. Defaults to TRUE. This argument only applies when +#' the individual based rarefaction is used (i.e., method = 'indiv') +#' @param ... other arguments to provide to \code{\link[mobr]{rarefaction}} +#' @inheritParams plot_abu +#' @inheritParams rarefaction +#' @importFrom scales alpha #' @export #' @examples -#' \donttest{ #' data(inv_comm) #' data(inv_plot_attr) #' inv_mob_in = make_mob_in(inv_comm, inv_plot_attr) -#' plot_SNpie(inv_mob_in, 'group') -#' } -plot_SNpie = function(mob_in, env_var, col = NA) { - # TO DO: add check to ensure that col is the same length as treatments - if (!requireNamespace("rgl", quietly = TRUE)) { - stop("rgl package needed for this function to work. Please install it.") - } +#' # random individual based rarefaction curves +#' plot_rarefaction(inv_mob_in, 'group', 'uninvaded', 'indiv', +#' pooled=TRUE, leg_loc='bottomright') +#' plot_rarefaction(inv_mob_in, 'group', 'uninvaded', 'indiv', +#' pooled=FALSE, log='x') +#' # random sample based rarefaction curves +#' plot_rarefaction(inv_mob_in, 'group', 'uninvaded', 'samp', +#' log='xy') +#' # spatial sample based rarefaction curves +#' plot_rarefaction(inv_mob_in, 'group', 'uninvaded', 'spat', +#' log='xy', xy_coords = inv_mob_in$spat) +plot_rarefaction = function(mob_in, env_var, ref_group, method, pooled=T, + col=NULL, lwd=1, log='', leg_loc = 'topleft', + ...) { + if (pooled == FALSE & method != 'indiv') + stop('Samples can only not be pooled at the treatment level when individual-based rarefaction is used (i.e., method="indiv")') env_data = mob_in$env[ , env_var] - grps = unique(env_data) - if (is.na(col[1])) - col = rainbow(length(grps)) - S_list = rowSums(mob_in$comm > 0) - N_list = rowSums(mob_in$comm) - PIE_list = sapply(1:nrow(mob_in$comm), function(x) - N_list[x]/(N_list[x] - 1) * - (1 - sum((mob_in$comm[x, ] / N_list[x])^2))) - col_list = sapply(env_data, function(x) col[which(grps == x)]) - rgl::plot3d(S_list, N_list, PIE_list, "S", "N", "PIE", col = col_list, - size = 8) -} + grps = unique(as.character(env_data)) + grps = c(ref_group, sort(grps[grps != ref_group])) + if (is.null(col)) + col = c("#FFC000", "#2B83BA", rainbow(10))[1:length(grps)] + else if (length(col) != length(grps)) + stop('Length of col vector must match the number of unique groups') + if (method == 'indiv') + xlab = 'Number of individuals' + else + xlab = 'Number of samples' + if (pooled) { + Srare = lapply(grps, function(x) + rarefaction(mob_in$comm[env_data == x, ], method, ...)) + xlim = c(1, max(unlist(sapply(Srare, function(x) as.numeric(names(x)))))) + ylim = c(1, max(unlist(Srare))) + n = as.numeric(names(Srare[[1]])) + plot(n, Srare[[1]], type = "n", + xlab = xlab, ylab = "Species richness", + xlim = xlim, ylim = ylim, log = log) + for (i in seq_along(grps)) { + col_grp = col[i] + n = as.numeric(names(Srare[[i]])) + lines(n, Srare[[i]], col = col_grp, lwd = 1, type = "l") + } + } else { + Srare = lapply(grps, function(x) + apply(mob_in$comm[env_data == x, ], 1, function(y) + rarefaction(y, method, ...))) + xlim = c(1, max(unlist(lapply(Srare, function(x) + lapply(x, function(y) + as.numeric(names(y))))))) + ylim = c(1, max(unlist(Srare))) + n = as.numeric(names(Srare[[1]][[1]])) + plot(n, Srare[[1]][[1]], type = "n", + xlab = xlab, ylab = "Species richness", + xlim = xlim, ylim = ylim, log = log) + for (i in seq_along(grps)) { + col_grp = col[i] + for (j in seq_along(Srare[[i]])) { + n = as.numeric(names(Srare[[i]][[j]])) + if (n[1] > 0) + lines(n, Srare[[i]][[j]], col = scales::alpha(col_grp, 0.5), + lwd = 1, type = 'l') + } + } + } + legend(leg_loc, legend=grps, col = col, lwd = 2, bty='n') +} #' Plot mob curves #' @@ -1489,7 +1540,7 @@ plot.mob_out = function(mob_out, trt_group, ref_group, same_scale=FALSE, overlap_effects = function(mob_out, trt_group, display='raw', prop=FALSE, rescale='max_effort', common_scale=FALSE, xlabel_indiv=TRUE, ylim=NULL, log='', lty=1, lwd=3, - col=c("#1AB2FF", "#FFBF80", "#7030A0")) { + col=c("#1AB2FF", "#FCD5B5", "#7030A0")) { if (prop & display != 'stacked') stop("Proptional differences can only be used when considering stacked area graphs (i.e., display = 'stacked')") if (length(lty) == 1) @@ -1528,7 +1579,7 @@ overlap_effects = function(mob_out, trt_group, display='raw', prop=FALSE, if (common_scale) dat = subset(dat , effort <= max(dat$effort[dat$type == 'SAD'])) if (is.null(ylim)) { - if (dispaly == 'raw') + if (display == 'raw') ylim = range(dat$effect) else if (prop) ylim = c(0, 1) @@ -1553,13 +1604,14 @@ overlap_effects = function(mob_out, trt_group, display='raw', prop=FALSE, times=length(effort)), effort = rep(effort, each=3), abs_effect = props) - } + ylab = 'Fraction of abs(Diff. in Richness)' + } else + ylab = 'abs(Diff. in Richness)' plotStacked(unique(dat$effort), data.frame(dat$abs_effect[dat$type == 'SAD'], dat$abs_effect[dat$type == 'N'], dat$abs_effect[dat$type == 'agg']), - xlab = 'Number of Samples', - ylab = 'abs(Difference in Richness)', + xlab = 'Number of Samples', ylab = ylab , col = col, border=NA, frame.plot=F, ylim=ylim, log=log) } diff --git a/man/get_delta_stats.Rd b/man/get_delta_stats.Rd index 71f0825..465afc5 100644 --- a/man/get_delta_stats.Rd +++ b/man/get_delta_stats.Rd @@ -47,7 +47,7 @@ the position of the points. If log_scale is TRUE, the points are equally spaced on logarithmic scale. If it is FALSE (default), the points are equally spaced on arithmetic scale.} -\item{min_plot}{minimal number of plots for test 'agg', where plots are +\item{min_plots}{minimal number of plots for test 'agg', where plots are randomized within groups as null test. If it is given a value, all groups with fewer plots than min_plot are removed for this test. If it is NULL (default), all groups are kept. Warnings are issued if 1. there is only one diff --git a/man/plot.mob_out.Rd b/man/plot.mob_out.Rd index 25ccb1a..ec0f92c 100644 --- a/man/plot.mob_out.Rd +++ b/man/plot.mob_out.Rd @@ -5,7 +5,8 @@ \title{Plot mob curves} \usage{ \method{plot}{mob_out}(mob_out, trt_group, ref_group, same_scale = FALSE, - display = c("rarefaction", "delta S", "ddelta S"), par_args = NULL) + log = NULL, display = c("rarefaction", "delta S", "ddelta S"), lwd = 3, + par_args = NULL) } \arguments{ \item{mob_out}{a mob_out class object} @@ -23,6 +24,9 @@ ddelta S plots are scaled identically accross the tested effects} \item{lwd}{a single value for for line width, see \link[graphics]{par}.} \item{par_args}{optional argument that sets graphical parameters to set} + +\item{same_scale}{if TRUE then all three plots have the same range on the +y-axis.} } \value{ plots the effect of the SAD, the number of individuals, and spatial @@ -43,4 +47,4 @@ plot(inv_mob_out, 'invaded', 'uninvaded', display='ddelta S') } \author{ Xiao Xiao and Dan McGlinn -} \ No newline at end of file +} diff --git a/man/plot.mob_stats.Rd b/man/plot.mob_stats.Rd index 8459172..4e05575 100644 --- a/man/plot.mob_stats.Rd +++ b/man/plot.mob_stats.Rd @@ -55,4 +55,4 @@ plot(inv_stats_boot) } \author{ Felix May, Xiao Xiao, and Dan McGlinn -} \ No newline at end of file +} diff --git a/man/plot_SNpie.Rd b/man/plot_SNpie.Rd deleted file mode 100644 index 61e071b..0000000 --- a/man/plot_SNpie.Rd +++ /dev/null @@ -1,29 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/mobr.R -\name{plot_SNpie} -\alias{plot_SNpie} -\title{Create 3d plot of richness, abundance, and probability of interspecific -encounter} -\usage{ -plot_SNpie(mob_in, env_var, col = NA) -} -\arguments{ -\item{mob_in}{a 'mob_in' class object produced by 'make_mob_in'} - -\item{env_var}{a string that specifies the column name in mob_in$env that -specifies the grouping variable.} - -\item{col}{optional vector of colors.} -} -\description{ -Create 3d plot of richness, abundance, and probability of interspecific -encounter -} -\examples{ -\donttest{ -data(inv_comm) -data(inv_plot_attr) -inv_mob_in = make_mob_in(inv_comm, inv_plot_attr) -plot_SNpie(inv_mob_in, 'group') -} -} diff --git a/man/plot_abu.Rd b/man/plot_abu.Rd index 54b1ccf..b2608a2 100644 --- a/man/plot_abu.Rd +++ b/man/plot_abu.Rd @@ -4,8 +4,8 @@ \alias{plot_abu} \title{Plot distributions of species abundance} \usage{ -plot_abu(mob_in, env_var, type = c("sad", "rad"), pooled = FALSE, - col = NA, log = "", leg_loc = "topleft") +plot_abu(mob_in, env_var, ref_group, type = c("sad", "rad"), pooled = FALSE, + col = NULL, lwd = 1, log = "", leg_loc = "topleft") } \arguments{ \item{mob_in}{a 'mob_in' class object produced by 'make_mob_in'} @@ -20,7 +20,14 @@ not} \item{col}{optional vector of colors.} -\item{log}{specify which axes to apply log transformations to.} +\item{lwd}{a vector of line widths, see \code{\link[graphics]{par}}.} + +\item{log}{a character string which contains \code{"x"} if the x axis + is to be logarithmic, \code{"y"} if the y axis is to be logarithmic + and \code{"xy"} or \code{"yx"} if both axes are to be logarithmic.} + +\item{leg_loc}{the location of the legend. Defaults to 'topleft', +see \code{\link[graphics]{legend}}.} } \description{ Plot distributions of species abundance @@ -29,6 +36,6 @@ Plot distributions of species abundance data(inv_comm) data(inv_plot_attr) inv_mob_in = make_mob_in(inv_comm, inv_plot_attr) -plot_abu(inv_mob_in, 'group', 'sad', pooled=F, log='x') -plot_abu(inv_mob_in, 'group', 'rad', pooled=T, log='x') +plot_abu(inv_mob_in, 'group', 'uninvaded', 'sad', pooled=F, log='x') +plot_abu(inv_mob_in, 'group', 'uninvaded', 'rad', pooled=T, log='x') } diff --git a/man/plot_rarefaction.Rd b/man/plot_rarefaction.Rd new file mode 100644 index 0000000..4efc39a --- /dev/null +++ b/man/plot_rarefaction.Rd @@ -0,0 +1,54 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/mobr.R +\name{plot_rarefaction} +\alias{plot_rarefaction} +\title{Plot rarefaction curves for each treatment group} +\usage{ +plot_rarefaction(mob_in, env_var, ref_group, method, pooled = T, col = NULL, + lwd = 1, log = "", leg_loc = "topleft", ...) +} +\arguments{ +\item{mob_in}{a 'mob_in' class object produced by 'make_mob_in'} + +\item{env_var}{a string that specifies the column name in mob_in$env that +specifies the grouping variable.} + +\item{method}{either 'indiv', 'sampl', or 'spat' for individual, sample, or +sample spatially explicit based rarefaction respectively} + +\item{pooled}{boolean specifying if samples should be pooled at the group +level or not. Defaults to TRUE. This argument only applies when +the individual based rarefaction is used (i.e., method = 'indiv')} + +\item{col}{optional vector of colors.} + +\item{lwd}{a vector of line widths, see \code{\link[graphics]{par}}.} + +\item{log}{a character string which contains \code{"x"} if the x axis + is to be logarithmic, \code{"y"} if the y axis is to be logarithmic + and \code{"xy"} or \code{"yx"} if both axes are to be logarithmic.} + +\item{leg_loc}{the location of the legend. Defaults to 'topleft', +see \code{\link[graphics]{legend}}.} + +\item{...}{other arguments to provide to \code{\link[mobr]{rarefaction}}} +} +\description{ +Plot rarefaction curves for each treatment group +} +\examples{ +data(inv_comm) +data(inv_plot_attr) +inv_mob_in = make_mob_in(inv_comm, inv_plot_attr) +# random individual based rarefaction curves +plot_rarefaction(inv_mob_in, 'group', 'uninvaded', 'indiv', + pooled=TRUE, leg_loc='bottomright') +plot_rarefaction(inv_mob_in, 'group', 'uninvaded', 'indiv', + pooled=FALSE, log='x') +# random sample based rarefaction curves +plot_rarefaction(inv_mob_in, 'group', 'uninvaded', 'samp', + log='xy') +# spatial sample based rarefaction curves +plot_rarefaction(inv_mob_in, 'group', 'uninvaded', 'spat', + log='xy', xy_coords = inv_mob_in$spat) +}