Nothing
context("demography_ctfs")
library(dplyr)
library(purrr)
expect_ref <- function(object, file) {
testthat::expect_known_output(object, file, print = TRUE, update = FALSE)
}
pick10sp <- function(.data) dplyr::filter(.data, sp %in% unique(.data$sp)[1:10])
pluck_n <- function(.x, n) lapply(.x, function(x) x[1:n])
tiny1 <- fgeo.x::tree5
tiny2 <- fgeo.x::tree6
test_that("mortlity_ctfs warns if censues are stem not tree tables", {
skip_if_not_installed("fgeo.data")
census1 <- fgeo.data::luquillo_stem5_random
census2 <- fgeo.data::luquillo_stem6_random
expect_warning(
mortality_ctfs(census1, census2),
"census.*should have a single row per tree per census."
)
census1 <- fgeo.data::luquillo_tree5_random
census2 <- fgeo.data::luquillo_tree6_random
expect_warning(
mortality_ctfs(census1, census2),
NA
)
})
test_that("output is equal if aggregated via `split2` or `interaction()`", {
# Toy groups
tiny1$g1 <- sample(c("a", "b"), nrow(tiny1), replace = TRUE)
tiny1$g2 <- sample(1:2, nrow(tiny1), replace = TRUE)
# Suppress "This warning is displayed once per session."
spl <- suppressWarnings(
recruitment_ctfs(tiny1, tiny2, split1 = tiny1$g1, split2 = tiny1$g2)
)
int <- recruitment_ctfs(tiny1, tiny2, split1 = interaction(tiny1$g1, tiny1$g2))
expect_equal(
map(spl, as.vector),
map(int, as.vector)
)
})
test_that("output is equal if aggregated via `split2` or `interaction()`", {
skip("FIXME: Real groups don't produce the same output")
spl <- recruitment_ctfs(
tiny1, tiny2,
split1 = tiny1$sp, split2 = tiny1$quadrat
)
int <- recruitment_ctfs(
tiny1, tiny2,
split1 = interaction(tiny1$sp, tiny1$quadrat)
)
expect_equal(
map(map(spl, as.vector), head),
map(map(int, as.vector), head)
)
})
test_that("objects created with split2 have split2 attribute", {
out <- recruitment_ctfs(
tiny1, tiny2,
split1 = tiny1$sp, split2 = tiny1$quadrat
)
expect_true(attr(out, "split2"))
})
test_that("without split2, doesn't have attribute split2", {
out <- recruitment_ctfs(tiny1, tiny2)
expect_null(attr(out, "split2"))
})
test_that("using `mindbh` prints a message after extracting desired `mindbh`", {
expect_message(
recruitment_ctfs(
pick10sp(fgeo.x::tree5), pick10sp(fgeo.x::tree6),
mindbh = 100
),
"Using dbh.*and above"
)
})
test_that("growth_ctfs() outputs differently with different `method`s", {
i <- growth_ctfs(tiny1, tiny2, method = "I")
e <- growth_ctfs(tiny1, tiny2, method = "E")
expect_false(identical(i, e))
})
describe("recruitment_ctfs(), mortality_ctfs(), and growth_ctfs()", {
it("output S3 objects of class demography_ctfs", {
out1 <- recruitment_ctfs(tiny1, tiny2, quiet = TRUE)
expect_is(out1, "demography_ctfs")
out1 <- mortality_ctfs(tiny1, tiny2, quiet = TRUE)
expect_is(out1, "demography_ctfs")
out1 <- growth_ctfs(tiny1, tiny2, quiet = TRUE)
expect_is(out1, "demography_ctfs")
out1 <- recruitment_ctfs(
tiny1, tiny2,
split1 = tiny1$sp, quiet = TRUE
)
expect_is(out1, "demography_ctfs")
out1 <- mortality_ctfs(
tiny1, tiny2,
split1 = tiny1$sp, quiet = TRUE
)
expect_is(out1, "demography_ctfs")
out1 <- growth_ctfs(
tiny1, tiny2,
split1 = tiny1$sp, quiet = TRUE
)
expect_is(out1, "demography_ctfs")
})
it("output equivalent to ctfs analogs (different class)", {
skip_if_not_installed("ctfs")
out1 <- recruitment_ctfs(
tiny1, tiny2,
split1 = tiny1$sp, quiet = TRUE
)
expect_is(out1, "demography_ctfs")
out2 <- ctfs::recruitment(tiny1, tiny2, split1 = tiny1$sp)
expect_equivalent(out1, out2)
out1 <- mortality_ctfs(
tiny1, tiny2,
split1 = tiny1$sp, quiet = TRUE
)
out2 <- ctfs::mortality(tiny1, tiny2, split1 = tiny1$sp)
expect_equivalent(out1, out2)
# Bug in ctfs::growth(); fixed in growth_ctfs().
# Works
expect_error(
growth_ctfs(tiny1, tiny2, split1 = tiny1$sp, quiet = TRUE), NA
)
# Fails
expect_error(ctfs::growth(tiny1, tiny2, split1 = tiny1$sp))
})
it("outputs an OK data structure", {
r_luq_t <- recruitment_ctfs(tiny1, tiny2)
expect_ref(r_luq_t, "ref-recruitment_ctfs_luq_tree")
expect_type(r_luq_t, "list")
expect_is(r_luq_t[[1]], "numeric")
expect_length(r_luq_t, 8)
expect_false(any(is.na(r_luq_t)))
m_luq_t <- mortality_ctfs(tiny1, tiny2)
expect_ref(m_luq_t, "ref-mortality_ctfs_luq_tree")
expect_type(m_luq_t, "list")
expect_is(m_luq_t[[1]], "numeric")
expect_length(m_luq_t, 9)
expect_false(any(is.na(m_luq_t)))
g_luq_t <- growth_ctfs(tiny1, tiny2)
expect_ref(g_luq_t, "ref-growth_ctfs_luq_tree")
expect_type(m_luq_t, "list")
expect_is(g_luq_t[[1]], "numeric")
expect_length(g_luq_t, 7)
expect_false(any(is.na(g_luq_t)))
})
it("errs if crucial variables are missing", {
expect_error(recruitment_ctfs(rename(tiny1, bad = dbh), tiny2), "Ensure")
expect_error(recruitment_ctfs(rename(tiny1, bad = hom), tiny2), "Ensure")
expect_error(recruitment_ctfs(rename(tiny1, bad = status), tiny2), "Ensure")
expect_error(recruitment_ctfs(rename(tiny1, bad = date), tiny2), "Ensure")
expect_error(recruitment_ctfs(tiny1, rename(tiny2, bad = dbh)), "Ensure")
expect_error(recruitment_ctfs(tiny1, rename(tiny2, bad = hom)), "Ensure")
expect_error(recruitment_ctfs(tiny1, rename(tiny2, bad = status)), "Ensure")
expect_error(recruitment_ctfs(tiny1, rename(tiny2, bad = date)), "Ensure")
expect_error(mortality_ctfs(rename(tiny1, bad = dbh), tiny2), "Ensure")
expect_error(mortality_ctfs(rename(tiny1, bad = hom), tiny2), "Ensure")
expect_error(mortality_ctfs(rename(tiny1, bad = status), tiny2), "Ensure")
expect_error(mortality_ctfs(rename(tiny1, bad = date), tiny2), "Ensure")
expect_error(mortality_ctfs(tiny1, rename(tiny2, bad = dbh)), "Ensure")
expect_error(mortality_ctfs(tiny1, rename(tiny2, bad = hom)), "Ensure")
expect_error(mortality_ctfs(tiny1, rename(tiny2, bad = status)), "Ensure")
expect_error(mortality_ctfs(tiny1, rename(tiny2, bad = date)), "Ensure")
expect_error(growth_ctfs(rename(tiny1, bad = hom), tiny2), "Ensure")
expect_error(growth_ctfs(rename(tiny1, bad = dbh), tiny2), "Ensure")
expect_error(growth_ctfs(rename(tiny1, bad = status), tiny2), "Ensure")
expect_error(growth_ctfs(rename(tiny1, bad = date), tiny2), "Ensure")
expect_error(growth_ctfs(rename(tiny1, bad = stemID), tiny2), "Ensure")
expect_error(growth_ctfs(tiny1, rename(tiny2, bad = dbh)), "Ensure")
expect_error(growth_ctfs(tiny1, rename(tiny2, bad = hom)), "Ensure")
expect_error(growth_ctfs(tiny1, rename(tiny2, bad = status)), "Ensure")
expect_error(growth_ctfs(tiny1, rename(tiny2, bad = date)), "Ensure")
# Not in recruitment_ctfs() or mortality_ctfs()
expect_error(growth_ctfs(tiny1, rename(tiny2, bad = stemID)), "Ensure")
})
it("errs with informative message if censuses are missing", {
expect_error(recruitment_ctfs(), "is missing, with no default")
expect_error(mortality_ctfs(), "is missing, with no default")
expect_error(growth_ctfs(), "is missing, with no default")
})
it("informs that `alivecode` is deprecated, but only once", {
expect_message(
recruitment_ctfs(tiny1, tiny2, alivecode = "A"),
"is deprecated"
)
output <- capture.output(
recruitment_ctfs(tiny1, tiny2, alivecode = "A"),
type = "message"
)
expect_false(any(grepl("alivecode.*deprecated", output)))
# Remain quiet with other demography functions
expect_message(mortality_ctfs(tiny1, tiny2, alivecode = "A"))
# Not applicable for growth_ctfs()
expect_error(growth_ctfs(tiny1, tiny2, alivecode = "A"), "unused argument")
})
it("is sensitive to `alivecode`", {
outA <- recruitment_ctfs(tiny1, tiny2, alivecode = "A")
outD <- recruitment_ctfs(tiny1, tiny2, alivecode = "D")
expect_warning(
outBAD <- recruitment_ctfs(tiny1, tiny2, alivecode = "BAD"),
"`alivecode` matches no value of `status`"
)
expect_false(identical(outA, outD))
expect_true(all(is.na(outBAD)))
outA <- mortality_ctfs(tiny1, tiny2, alivecode = "A")
outD <- mortality_ctfs(tiny1, tiny2, alivecode = "D")
expect_warning(
outBAD <- mortality_ctfs(tiny1, tiny2, alivecode = "BAD"),
"`alivecode` matches no value of `status`"
)
expect_false(identical(outA, outD))
infinite <- is.infinite(unlist(outBAD))
na <- is.na(unlist(outBAD))
expect_true(any(infinite) || any(na))
# Not applicable for growth_ctfs()
})
it("informs dbh range if quiet = FALSE", {
expect_message(recruitment_ctfs(tiny1, tiny2), "Detected dbh ranges")
expect_silent(recruitment_ctfs(tiny1, tiny2, quiet = TRUE))
expect_message(mortality_ctfs(tiny1, tiny2), "Detected dbh ranges")
expect_silent(mortality_ctfs(tiny1, tiny2, quiet = TRUE))
expect_message(growth_ctfs(tiny1, tiny2), "Detected dbh ranges")
expect_silent(growth_ctfs(tiny1, tiny2, quiet = TRUE))
})
it("warns if time difference is cero", {
expect_warning(recruitment_ctfs(tiny1, tiny1), "Time difference is cero")
expect_warning(mortality_ctfs(tiny1, tiny1), "Time difference is cero")
expect_warning(growth_ctfs(tiny1, tiny1), "Time difference is cero")
})
it("errs if all dates are missing", {
tiny1na <- tiny1
tiny2na <- tiny2
tiny1na$date <- NA
tiny2na$date <- NA
msg <- "Can't use `date`; all values are all missing."
expect_error(growth_ctfs(tiny1na, tiny1na), msg)
expect_error(mortality_ctfs(tiny1na, tiny1na), msg)
expect_error(recruitment_ctfs(tiny1na, tiny1na), msg)
})
it("defaults to mindbh = 0", {
out <- recruitment_ctfs(tiny1, tiny2)
out0 <- recruitment_ctfs(tiny1, tiny2, mindbh = 0)
expect_equal(out, out0)
# Not applicable to mortality_ctfs()
out <- growth_ctfs(tiny1, tiny2)
out0 <- growth_ctfs(tiny1, tiny2, mindbh = 0)
expect_equal(out, out0)
})
it("is sensitive to changing dbh", {
out0 <- recruitment_ctfs(tiny1, tiny2, mindbh = 0)
out100 <- recruitment_ctfs(tiny1, tiny2, mindbh = 100)
expect_false(identical(out0, out100))
# Not applicable to mortalit()
out0 <- growth_ctfs(tiny1, tiny2, mindbh = 0)
out100 <- growth_ctfs(tiny1, tiny2, mindbh = 100)
expect_false(identical(out0, out100))
})
it("works with `split1`", {
out1 <- recruitment_ctfs(tiny1, tiny2, split1 = tiny1$sp)
expect_ref(out1, "ref-recruitment_ctfs_luq_tree_split1")
# Output has the expected structure
expect_type(out1, "list")
expect_is(out1[[1]], "numeric")
expect_length(out1, 8)
expect_false(any(is.na(out1)))
# Spliting by sp of census 1 or census 2 is the same
out2 <- recruitment_ctfs(tiny1, tiny2, split1 = tiny2$sp)
expect_true(identical(out1, out2))
# and the result is different than not splitting at all
out <- recruitment_ctfs(tiny1, tiny2)
expect_false(identical(out, out2))
out1 <- mortality_ctfs(tiny1, tiny2, split1 = tiny1$sp)
expect_ref(out1, "ref-mortality_ctfs_luq_tree_split1")
# Output has the expected structure
expect_type(out1, "list")
expect_is(out1[[1]], "numeric")
expect_length(out1, 9)
expect_false(any(is.na(out1)))
# Spliting by sp of census 1 or census 2 is the same
out2 <- mortality_ctfs(tiny1, tiny2, split1 = tiny2$sp)
expect_true(identical(out1, out2))
# and the result is different than not splitting at all
out <- mortality_ctfs(tiny1, tiny2)
expect_false(identical(out, out2))
out1 <- growth_ctfs(tiny1, tiny2, split1 = tiny1$sp)
expect_ref(out1, "ref-growth_ctfs_luq_tree_split1")
# Output has the expected structure
expect_type(out1, "list")
expect_is(out1[[1]], "numeric")
expect_length(out1, 7)
expect_false(any(is.na(out1)))
# Spliting by sp of census 1 or census 2 is the same
out2 <- growth_ctfs(tiny1, tiny2, split1 = tiny2$sp)
expect_true(identical(out1, out2))
# and the result is different than not splitting at all
out <- growth_ctfs(tiny1, tiny2)
expect_false(identical(out, out2))
})
it("works with two splitting criteria", {
out <-
recruitment_ctfs(tiny1, tiny2, split1 = tiny1$sp, split2 = tiny1$quadrat)
expect_ref(pluck_n(out, 100), "ref-recruitment_ctfs_luq_tree_split2")
# Returns a list
expect_type(out, "list")
# but each element is no longer numeric but matrix
expect_is(out[[1]], "matrix")
out <-
mortality_ctfs(tiny1, tiny2, split1 = tiny1$sp, split2 = tiny1$quadrat)
expect_ref(pluck_n(out, 100), "ref-mortality_ctfs_luq_tree_split2")
# Returns a list
expect_type(out, "list")
# but each element is no longer numeric but matrix
expect_is(out[[1]], "matrix")
out <-
growth_ctfs(tiny1, tiny2, split1 = tiny1$sp, split2 = tiny1$quadrat)
expect_ref(pluck_n(out, 100), "ref-growth_ctfs_luq_tree_split2")
# Returns a list
expect_type(out, "list")
# but each element is no longer numeric but matrix
expect_is(out[[1]], "matrix")
})
it("works with stem tables", {
stem5 <- fgeo.x::stem5
stem6 <- fgeo.x::stem6
out <- recruitment_ctfs(stem5, stem6)
expect_ref(out, "ref-recruitment_ctfs_luq_stem")
expect_type(out, "list")
expect_is(out[[1]], "numeric")
expect_length(out, 8)
expect_false(any(is.na(out)))
out <- mortality_ctfs(stem5, stem6)
expect_ref(out, "ref-mortality_ctfs_luq_stem")
expect_type(out, "list")
expect_is(out[[1]], "numeric")
expect_length(out, 9)
expect_false(any(is.na(out)))
out <- growth_ctfs(stem5, stem6)
expect_ref(out, "ref-growth_ctfs_luq_stem")
expect_type(out, "list")
expect_is(out[[1]], "numeric")
expect_length(out, 7)
expect_false(any(is.na(out)))
})
it("works with data from bci", {
skip_if_not_installed("bciex")
stem5 <- pick10sp(bciex::bci12s5mini)
stem6 <- pick10sp(bciex::bci12s6mini)
out <- expect_warning(
recruitment_ctfs(stem5, stem6),
"census.*should have a single row per tree per census."
)
expect_ref(out, "ref-recruitment_ctfs_bci_stem")
expect_type(out, "list")
expect_is(out[[1]], "numeric")
expect_length(out, 8)
expect_false(any(is.na(out)))
out <- expect_warning(
mortality_ctfs(stem5, stem6),
"census.*should have a single row per tree per census."
)
expect_ref(out, "ref-mortality_ctfs_bci_stem")
expect_type(out, "list")
expect_is(out[[1]], "numeric")
expect_length(out, 9)
expect_false(any(is.na(out)))
out <- expect_warning(
growth_ctfs(stem5, stem6),
"census.*should have a single row per tree per census."
)
expect_ref(out, "ref-growth_ctfs_bci_stem")
expect_type(out, "list")
expect_is(out[[1]], "numeric")
expect_length(out, 7)
expect_false(any(is.na(out)))
tree5 <- pick10sp(bciex::bci12t5mini)
tree6 <- pick10sp(bciex::bci12t6mini)
out <- recruitment_ctfs(tree5, tree6)
expect_ref(out, "ref-recruitment_ctfs_bci_tree")
expect_type(out, "list")
expect_is(out[[1]], "numeric")
expect_length(out, 8)
expect_false(any(is.na(out)))
out <- mortality_ctfs(tree5, tree6)
expect_ref(out, "ref-mortality_ctfs_bci_tree")
expect_type(out, "list")
expect_is(out[[1]], "numeric")
expect_length(out, 9)
expect_false(any(is.na(out)))
out <- growth_ctfs(tree5, tree6)
expect_ref(out, "ref-growth_ctfs_bci_tree")
expect_type(out, "list")
expect_is(out[[1]], "numeric")
expect_length(out, 7)
expect_false(any(is.na(out)))
})
})
test_that("growth() is sensitive to `roundown`", {
expect_error(out1 <- growth_ctfs(tiny1, tiny2, rounddown = TRUE), NA)
expect_error(out2 <- growth_ctfs(tiny1, tiny2, rounddown = FALSE), NA)
expect_false(identical(out1, out2))
})
test_that("growth() can handle NULL `census2$codes`", {
# It's unclear why this is not available for census2
expect_error(growth_ctfs(tiny1, tiny2[setdiff(names(tiny2), "codes")]), NA)
})
# Helpers -----------------------------------------------------------------
test_that("mortality.calculation is type unstable which should be avoided", {
.scalar <- 1
expect_is(mortality.calculation(.scalar, .scalar, 1), "data.frame")
.matrix <- matrix(1)
expect_is(mortality.calculation(.matrix, .matrix, 1), "list")
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.