### vegan-tests: unit tests for vegan functions ### This file contains unit tests for vegan functions. This file is ### run in R CMD check and its results are compared against previously ### saved results in vegan-tests.Rout.save. If you change tests, you ### must generate new vegan-tests.Rout.save in this directory. ### The current plan is that tests/ are not included in the CRAN ### release, but only in the development versin of vegan in R-Forge. ### The tests here are not intended for human reading. The tests need ### not be ecological or biologically meaningful, but they are only ### intended for testing strange arguments, protect against ### regressions and test correctness of results. ### The tests are in a single file and you should clean work space ### after the unit test. You should set random number seed (if needed) ### for comparison against vegan-tests.Rout.save, and you should ### remove the seed after the unit test. If possible, avoid very long ### lasting tests. ###<--- BEGIN TESTS ---> suppressPackageStartupMessages(require(vegan)) ###<--- BEGIN anova.cca test ---> ### anova.cca tests: should work with (1) subset, (2) missing values, ### (3) with functions of variables poly(A1,2), (4) variables in data ### frame attached or in data=, or (5) in working environment set.seed(4711) data(dune) data(dune.env) df <- dune.env df$Management[c(1,5)] <- NA ## formula fla <- as.formula("dune ~ Management + poly(A1, 2) + spno") ### variable in the .GlobalEnv spno <- specnumber(dune) ### data= argument ## cca/rda m <- cca(fla, data=df, na.action=na.exclude, subset = Use != "Pasture" & spno > 7) anova(m, permutations=99) anova(m, by="term", permutations=99) # failed before 2.5-0 anova(m, by="margin", permutations=99) # works since 2.5-0 anova(m, by="axis", permutations=99) ## adonis adonis2(fla, data = dune.env, by = "terms") ## capscale p <- capscale(fla, data=df, na.action=na.exclude, subset = Use != "Pasture" & spno > 7) anova(p, permutations=99) anova(p, by="term", permutations=99) # failed before 2.5-0 anova(p, by="margin", permutations=99) # works since 2.5-0 anova(p, by="axis", permutations=99) ## see that capscale can be updated and also works with 'dist' input dis <- vegdist(dune) p <- update(p, dis ~ .) anova(p, permutations=99) anova(p, by="term", permutations=99) # failed before 2.5-0 anova(p, by="margin", permutations=99) # works since 2.5-0 anova(p, by="axis", permutations=99) ### attach()ed data frame instead of data= attach(df) q <- cca(fla, na.action = na.omit, subset = Use != "Pasture" & spno > 7) anova(q, permutations=99) ## commented tests below fail in vegan 2.1-40 because number of ## observations changes anova(q, by="term", permutations=99) # failed before 2.5-0 anova(q, by="margin", permutations=99) # works since 2.5-0 anova(q, by="axis", permutations=99) ### Check that constrained ordination functions can be embedded. ### The data.frame 'df' is still attach()ed. foo <- function(bar, Y, X, ...) { bar <- match.fun(bar) bar(Y ~ X, ...) } foo("cca", dune, Management, na.action = na.omit) foo("rda", dune, Management, na.action = na.omit) foo("capscale", dune, Management, dist="jaccard", na.action = na.omit) foo("capscale", vegdist(dune), Management, na.action = na.omit) foo("capscale", dune, Management, na.action = na.omit) # fails in 2.2-1 ## adonis must be done with detached 'df' or it will be used instead ## of with(dune.env, ...) detach(df) with(dune.env, foo("adonis2", dune, Management, by = "terms")) ## the test case reported in github issue #285 by @ktmbiome var <- "Moisture" adonis2(dune ~ dune.env[, var], by = "terms") rm(var) ### ### Check that statistics match in partial constrained ordination m <- cca(dune ~ A1 + Moisture + Condition(Management), dune.env, subset = A1 > 3) tab <- anova(m, by = "axis", permutations = 99) m tab all.equal(tab[,2], c(m$CCA$eig, m$CA$tot.chi), check.attributes=FALSE) tab[nrow(tab),1] == m$CA$rank ## clean-up rm(df, spno, fla, m, p, q, tab, dis, foo, .Random.seed) ### <--- END anova.cca test ---> ### Sven Neulinger reported failures in ### partial analysis which (mostly) were fixed in r2087. Below his test. set.seed(4711) X <- matrix(rnorm(30*6), 30, 6) A <- factor(rep(rep(c("a","b"), each=3),5)) B <- factor(rep(c("a","b","c"), 10)) ## Sven Neulinger's tests failed still in 2.2-1, now due to look-up ## order: function stats::C was found before matrix 'C'. The test was ## OK when non-function name was used ('CC'). C <- factor(rep(c(1:5), each=6)) ## partial db-RDA cap.model.cond <- capscale(X ~ A + B + Condition(C)) anova(cap.model.cond, by="axis", strata=C) # -> error pre r2287 anova(cap.model.cond, by="terms", strata=C) # -> error pre r2287 ## db-RDA without conditional factor cap.model <- capscale(X ~ A + B) anova(cap.model, by="axis", strata=C) # -> no error anova(cap.model, by="terms", strata=C) # -> no error # partial RDA rda.model.cond <- rda(X ~ A + B + Condition(C)) anova(rda.model.cond, by="axis", strata=C) # -> no error anova(rda.model.cond, by="terms", strata=C) # -> error pre r2287 # RDA without conditional factor rda.model <- rda(X ~ A + B) anova(rda.model, by="axis", strata=C) # -> no error anova(rda.model, by="terms", strata=C) # -> no error ## clean.up rm(X, A, B, C, cap.model.cond, cap.model, rda.model.cond, rda.model) ### end Sven Neulinger's tests ### Benedicte Bachelot informed us that several anova.cca* functions ### failed if community data name was the same as a function name: the ### function name was found first, and used instead ofa data. This ### seems to be related to the same problem that Sven Neulinger ### communicated, and his examples still faile if Condition or strata ### are function names. However, the following examples that failed ### should work now: set.seed(4711) cca <- dune m <- cca(cca ~ ., dune.env) anova(m, by="term") m <- capscale(cca ~ ., dune.env) anova(m, by="term") rm(m, cca) ### end Benedicte Bachelot tests ### Richard Telford tweeted this example on 23/2/2015. Fails in 2.2-1, ### but should work now. Also issue #100 in github.com/vegandevs/vegan. set.seed(4711) data(dune, dune.env) foo <- function(x, env) { m <- rda(x ~ Manure + A1, data = env) anova(m, by = "margin") } out <- lapply(dune, foo, env = dune.env) out$Poatriv rm(foo, out) ### end Richard Telford test ### github issue #291 reported that anova(mod, by="margin") gave wrong ### results in vegan 2.5-2 when 'mod' had only one constraining ### variable. In such corner case, all the following models should be ### equal set.seed(1046) z <- runif(20) p <- shuffleSet(20, 99) mod <- rda(dune ~ z) (a0 <- anova(mod, permutations=p)) (at <- anova(mod, permutations=p, by="term")) (am <- anova(mod, permutations=p, by="margin")) (aa <- anova(mod, permutations=p, by="axis")) (p1 <- permutest(mod, permutations=p, by="onedf")) all.equal(permustats(a0)$permutations, permustats(at)$permutations) all.equal(permustats(a0)$permutations, permustats(am)$permutations) all.equal(permustats(a0)$permutations, permustats(aa)$permutations) all.equal(permustats(a0)$permutations, permustats(p1)$permutations) rm(z,p,mod,a0,at,am,aa,p1) ### nestednodf: test case by Daniel Spitale in a comment to News on ### the release of vegan 1.17-6 in vegan.r-forge.r-project.org. x <- c(1,0,1,1,1,1,1,1,0,0,0,1,1,1,0,1,1,0,0,0,1,1,0,0,0) m1 <- matrix(x, nrow=5, ncol=5, byrow=FALSE)# as in Fig 2 Almeida-Neto et al 2008. (nodf1 <- nestednodf(m1, order = FALSE, weighted = FALSE)) ## Now the same matrix but with abundance data x <- c(5,0,2,1,1,4,1,1,0,0,0,7,1,1,0,3,1,0,0,0,9,1,0,0,0) m <- matrix(x, nrow=5, ncol=5, byrow=FALSE) (nodfq <- nestednodf(m, order = FALSE, weighted = FALSE)) identical(nodf1, nodfq) rm(x, m, m1, nodfq, nodf1) ### end nestednodf ### envfit & plot.envfit: latter failed if na.action resulted in only ### observation with a given factor level was removed. plot.envfit would ### fail with error about too long subscript ### fixed case where data presented to envfit also has extraneous levels data(dune) data(dune.env) ## add a new level to one of the factors levels(dune.env$Management) <- c(levels(dune.env$Management), "foo") ## fit nMDS and envfit set.seed(1) mod <- metaMDS(dune, trace = 0) ef <- envfit(mod, dune.env, permutations = 99) plot(mod) plot(ef, p.max = 0.1) rm(mod, ef) ### end envfit & plot.envfit ### protest (& Procrustes analysis): Stability of the permutations and ### other results. data(mite) mod <- rda(mite) x <- scores(mod, display = "si", choices=1:6) set.seed(4711) xp <- x[sample(nrow(x)),] pro <- protest(x, xp, permutations = how(nperm = 99)) pro pro$t rm(x, xp, pro) ### end protest ### Check that functions related to predict.rda work correctly for all ### constrained ordination methods. ### simulate.rda/cca/capscale: based on predict.* and the following ### should get back the data data(dune, dune.env) ind <- seq_len(nrow(dune)) target <- as.matrix(dune) ## rda mod <- rda(dune ~ Condition(Moisture) + Management + A1, dune.env) dat <- simulate(mod, indx = ind) all.equal(dat, target, check.attributes = FALSE) ## cca mod <- cca(dune ~ Condition(Moisture) + Management + A1, dune.env) dat <- simulate(mod, indx = ind) all.equal(dat, target, check.attributes = FALSE) ## capscale: Euclidean distances -- non-Euclidean distances have an ## imaginary component and will not give back the data. d <- dist(dune) mod <- capscale(d ~ Condition(Moisture) + Management + A1, dune.env) dat <- simulate(mod, indx = ind) all.equal(dat, d, check.attributes = FALSE) ## clean up rm(ind, target, mod, dat, d) ### end simulate.* ### test metaMDS works with long expression for comm ### originally reported to GLS by Richard Telford data(varespec) set.seed(1) mod <- metaMDS(subset(varespec, select = colSums(varespec) > 0, subset = rowSums(varespec) > 0), trace=0) mod rm(mod) ### The above should run without error & last lines tests changes to the ### printed output ## dbrda tests ## the following three should be all equal data(varespec, varechem) (mr <- rda(varespec ~ Al + P + Condition(pH), varechem)) (md <- dbrda(varespec ~ Al + P + Condition(pH), varechem)) (mc <- capscale(varespec ~ Al + P + Condition(pH), varechem)) ## the following two should be zero (within 1e-15) p <- shuffleSet(nrow(varespec), 999) all(abs(permustats(anova(mr, permutations=p))$permutations - permustats(anova(md, permutations=p))$permutations) < sqrt(.Machine$double.eps)) all(abs(permustats(anova(mr, permutations=p))$permutations - permustats(anova(mc, permutations=p))$permutations) < sqrt(.Machine$double.eps)) ## eigenvals returns a list now (>= 2.5-0) data(varespec, varechem) mod <- cca(varespec ~ Al + P + Condition(pH), varechem) ev <- summary(eigenvals(mod)) stopifnot(inherits(ev, "matrix")) stopifnot(!is.list(ev)) ev