mkdat <- function(nsim = 2) { d <- do.call(rbind, lapply(seq_len(nsim), function(i) data.frame(sim = paste0("T", i), Date = as.Date("2016-01-01") + 0:120, water = if (i %% 2) "AWD" else "CF", wagt = seq(0, 10000, length.out = 121) * i, pond = rep(c(0, 50), length.out = 121), stringsAsFactors = FALSE))) attr(d, "units") <- c(wagt = "kg/ha", pond = "mm") d } test_that("as_long carries treatment columns through the pivot", { l <- as_long(mkdat(), vars = c("wagt", "pond"), keep = "water") expect_true("water" %in% names(l)) expect_equal(sort(unique(l$variable)), c("pond", "wagt")) }) test_that("secondary axis rescales without changing the drawn range", { l <- as_long(mkdat(1), vars = c("wagt", "pond")) p <- plot_series(l, vars = c("wagt", "pond"), secondary = "pond") b <- ggplot2::ggplot_build(p) expect_false(is.null(b$plot$scales$get_scales("y")$sec_name)) # rescaled secondary must sit inside the primary range, not off the panel yr <- range(b$data[[1]]$y, finite = TRUE) expect_true(yr[2] <= max(l$value[l$variable == "wagt"]) * 1.001) }) test_that("a single panel becomes one panel per treatment when faceted", { l <- as_long(mkdat(4), vars = "wagt", keep = "water") expect_equal(nlevels(ggplot2::ggplot_build( suppressMessages(plot_series(l, vars = "wagt")))$data[[1]]$PANEL), 1L) expect_equal(nlevels(ggplot2::ggplot_build( plot_series(l, vars = "wagt", facet_by = "sim"))$data[[1]]$PANEL), 4L) expect_equal(nlevels(ggplot2::ggplot_build( plot_series(l, vars = "wagt", facet_by = "water"))$data[[1]]$PANEL), 2L) }) test_that("stacked layout gives one row per variable", { l <- as_long(mkdat(1), vars = c("wagt", "pond")) p <- plot_series(l, vars = c("wagt", "pond"), layout = "stacked") expect_equal(nlevels(ggplot2::ggplot_build(p)$data[[1]]$PANEL), 2L) }) test_that("overlaying several treatments in one colour is announced", { l <- as_long(mkdat(3), vars = "wagt") expect_message(plot_series(l, vars = "wagt"), "treatments overlaid") expect_silent(plot_series(l, vars = "wagt", facet_by = "sim")) }) test_that("observed SD is rescaled as a length, not a position", { l <- as_long(mkdat(1), vars = c("wagt", "pond")) ob <- data.frame(Date = as.Date("2016-03-01"), variable = "pond", value = 50, obs_sd = 5, stringsAsFactors = FALSE) p <- plot_series(l, vars = c("wagt", "pond"), secondary = "pond", obs = ob) eb <- Filter(function(x) inherits(x$geom, "GeomErrorbar"), p$layers)[[1]]$data # 5 mm on a 0-50 secondary mapped to a 0-10000 primary is 10% of the span expect_equal(eb$obs_sd, 5 * 10000 / 50, tolerance = 1e-6) }) test_that("missing variables are refused rather than silently dropped", { l <- as_long(mkdat(1), vars = "wagt") expect_error(plot_series(l, vars = "nonexistent"), "None of") }) obsdat <- function(vars = "wagt", sims = "T1") { do.call(rbind, lapply(sims, function(s) do.call(rbind, lapply(vars, function(v) data.frame(sim = s, Date = as.Date("2016-03-01") + c(0, 30), variable = v, value = c(1000, 3000), obs_sd = c(80, 150), stringsAsFactors = FALSE))))) } test_that("variables without observed data are reported, not fatal", { l <- as_long(mkdat(1), vars = c("wagt", "pond")) expect_message(plot_series(l, vars = c("wagt", "pond"), obs = obsdat("wagt")), "No observed data for: pond") p <- suppressMessages( plot_series(l, vars = c("wagt", "pond"), obs = obsdat("wagt"))) pt <- Filter(function(x) inherits(x$geom, "GeomPoint"), p$layers)[[1]] expect_equal(nrow(pt$data), 2L) expect_equal(as.character(unique(pt$data$variable)), "wagt") }) test_that("the observed legend lists only variables that have observations", { l <- as_long(mkdat(1), vars = c("wagt", "pond")) p <- suppressMessages(plot_series(l, vars = c("wagt", "pond"), secondary = "pond", obs = obsdat("wagt"))) pt <- Filter(function(x) inherits(x$geom, "GeomPoint"), p$layers)[[1]] expect_equal(nlevels(pt$data$.series), 1L) }) test_that("observed points reach their panel when the facet column is derivable", { l <- as_long(mkdat(2), vars = "wagt", keep = "water") ob <- obsdat("wagt", c("T1", "T2")) # has sim, but no water column p <- suppressMessages(plot_series(l, vars = "wagt", facet_by = "water", obs = ob)) pt <- Filter(function(x) inherits(x$geom, "GeomPoint"), p$layers)[[1]] expect_true("water" %in% names(pt$data)) expect_equal(nrow(pt$data), 4L) expect_equal(sort(unique(as.character(pt$data$water))), c("AWD", "CF")) }) test_that("unplaceable observed records are dropped with a message", { l <- as_long(mkdat(2), vars = "wagt", keep = "water") ob <- obsdat("wagt", "T99") # matches no simulation msgs <- character(0) withCallingHandlers( plot_series(l, vars = "wagt", facet_by = "water", obs = ob), message = function(m) { msgs <<- c(msgs, conditionMessage(m)); invokeRestart("muffleMessage") }) expect_true(any(grepl("could not be placed", msgs))) }) test_that("error bars follow each variable to its own axis and panel", { l <- as_long(mkdat(1), vars = c("wagt", "pond")) ob <- rbind(obsdat("wagt"), obsdat("pond")) p <- plot_series(l, vars = c("wagt", "pond"), secondary = "pond", obs = ob) eb <- Filter(function(x) inherits(x$geom, "GeomErrorbar"), p$layers)[[1]]$data expect_equal(nrow(eb), 4L) # the pond SD is rescaled, the wagt SD is not expect_equal(eb$obs_sd[eb$variable == "wagt"], c(80, 150)) expect_false(isTRUE(all.equal(eb$obs_sd[eb$variable == "pond"], c(80, 150)))) }) test_that("unplottable observed records are dropped with a message, not a warning", { sim <- data.frame(sim = "T1", Date = as.Date("2016-01-01") + 0:120, variable = "wagt", value = seq(0, 10000, length.out = 121), unit = "kg/ha", stringsAsFactors = FALSE) obs <- data.frame(sim = "T1", Date = as.Date(c("2016-02-01", "2016-03-01")), variable = "wagt", value = c(2000, NA), stringsAsFactors = FALSE) msgs <- character(0) p <- withCallingHandlers(plot_series(sim, vars = "wagt", obs = obs), message = function(m) { msgs <<- c(msgs, conditionMessage(m)); invokeRestart("muffleMessage") }) expect_true(any(grepl("omitted", msgs))) pt <- Filter(function(x) inherits(x$geom, "GeomPoint"), p$layers)[[1]] expect_equal(nrow(pt$data), 1L) expect_silent(ggplot2::ggplot_build(p)) }) test_that("plot_ts drops unplottable observed records too", { sim <- data.frame(Date = as.Date("2016-01-01") + 0:100, value = 1:101) obs <- data.frame(Date = as.Date(c("2016-02-01", "2016-03-01")), value = c(32, NA)) p <- suppressMessages(plot_ts(sim, obs = obs)) expect_silent(ggplot2::ggplot_build(p)) })