Nothing
# Tests for complex tf_ggplot use cases
# Tests complex expressions in tf aesthetics and derived quantities
test_that("tf aesthetic with function transformations works", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
# Create test data with positive and negative values
set.seed(123)
data <- data.frame(id = 1:3)
arg_vals <- seq(-2, 2, length.out = 11)
func_vals <- list(
sin(arg_vals), # Has negative values
cos(arg_vals), # Has negative values
arg_vals^2 - 1 # Has negative values
)
data$curves <- tfd(func_vals, arg = arg_vals)
# Test abs() transformation
expect_no_error({
p_abs <- tf_ggplot(data, aes(tf = abs(curves))) +
geom_line()
})
# Check that plot builds correctly
built_abs <- ggplot_build(p_abs)
plot_data_abs <- built_abs$data[[1]]
# All y values should be non-negative after abs()
expect_true(all(plot_data_abs$y >= 0))
# Should have 3 groups (one per function)
expect_equal(length(unique(plot_data_abs$group)), 3)
# Should have correct number of rows (3 functions × 11 points)
expect_equal(nrow(plot_data_abs), 33)
})
test_that("tf aesthetic with mathematical operations works", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(456)
data <- data.frame(id = 1:2)
data$func1 <- tf_rgp(2, arg = seq(0, 1, length.out = 6))
data$func2 <- tf_rgp(2, arg = seq(0, 1, length.out = 6))
# Test arithmetic operations
expect_no_error({
p_sum <- tf_ggplot(data, aes(tf = func1 + func2)) +
geom_line()
p_scaled <- tf_ggplot(data, aes(tf = 2 * func1)) +
geom_line()
})
# Check that plots build correctly
built_sum <- ggplot_build(p_sum)
built_scaled <- ggplot_build(p_scaled)
expect_equal(length(unique(built_sum$data[[1]]$group)), 2)
expect_equal(length(unique(built_scaled$data[[1]]$group)), 2)
expect_equal(nrow(built_sum$data[[1]]), 12) # 2 functions × 6 points
expect_equal(nrow(built_scaled$data[[1]]), 12)
})
test_that("color aesthetic with tf-derived quantities works", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(789)
data <- data.frame(id = 1:4)
data$curves <- tf_rgp(4, arg = seq(0, 1, length.out = 11))
# Test color by tf_depth
expect_no_error({
p_depth <- tf_ggplot(data, aes(tf = curves, color = tf_depth(curves))) +
geom_line()
})
built_depth <- ggplot_build(p_depth)
plot_data_depth <- built_depth$data[[1]]
# Should have 4 groups (one per function)
expect_equal(length(unique(plot_data_depth$group)), 4)
# Color should vary based on depth
expect_true(length(unique(plot_data_depth$colour)) > 1)
# Each group should have consistent color within group
color_by_group <- split(plot_data_depth$colour, plot_data_depth$group)
consistent_colors <- all(sapply(
color_by_group,
function(x) length(unique(x)) == 1
))
expect_true(consistent_colors)
})
test_that("multiple derived aesthetics work together", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(101112)
data <- data.frame(id = 1:5)
data$curves <- tf_rgp(5, arg = seq(0, 1, length.out = 11))
# Test multiple tf-derived aesthetics
expect_no_error({
p_multi <- tf_ggplot(
data,
aes(
tf = curves,
color = tf_depth(curves),
alpha = tf_fmin(curves)
)
) +
geom_line()
})
expect_no_error(print(p_multi))
built_multi <- ggplot_build(p_multi)
plot_data_multi <- built_multi$data[[1]]
# Should have all aesthetic mappings
expect_true("colour" %in% names(plot_data_multi))
expect_true("alpha" %in% names(plot_data_multi))
# Should have 5 groups
expect_equal(length(unique(plot_data_multi$group)), 5)
# Alpha should vary based on function range
expect_true(length(unique(plot_data_multi$alpha)) > 1)
})
test_that("complex tf expressions in constructor vs geom are equivalent", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(131415)
data <- data.frame(id = 1:3)
data$curves <- tf_rgp(3, arg = seq(-1, 1, length.out = 9))
# Method 1: Complex expression in constructor
p1 <- tf_ggplot(data, aes(tf = abs(curves), color = tf_depth(curves))) +
geom_line()
# Method 2: Complex expression in geom
p2 <- tf_ggplot(data) +
geom_line(aes(tf = abs(curves), color = tf_depth(curves)))
# Both should build successfully
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should have same dimensions
expect_equal(dim(built1$data[[1]]), dim(built2$data[[1]]))
# Should have same number of groups
expect_equal(
length(unique(built1$data[[1]]$group)),
length(unique(built2$data[[1]]$group))
)
# Both should have only non-negative y values (due to abs)
expect_true(all(built1$data[[1]]$y >= 0))
expect_true(all(built2$data[[1]]$y >= 0))
# Colors should vary in both (due to tf_depth)
expect_true(length(unique(built1$data[[1]]$colour)) > 1)
expect_true(length(unique(built2$data[[1]]$colour)) > 1)
})
test_that("nested function calls in tf aesthetics work", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(161718)
data <- data.frame(id = 1:2)
data$curves <- tf_rgp(2, arg = seq(-1, 1, length.out = 7))
# Test nested function calls
expect_no_error({
p_nested <- tf_ggplot(data, aes(tf = sqrt(abs(curves)))) +
geom_line()
})
built_nested <- ggplot_build(p_nested)
plot_data_nested <- built_nested$data[[1]]
# All y values should be non-negative (due to sqrt(abs()))
expect_true(all(plot_data_nested$y >= 0))
expect_true(all(is.finite(plot_data_nested$y)))
# Should have 2 groups
expect_equal(length(unique(plot_data_nested$group)), 2)
})
test_that("tf aesthetics with scalars and derived quantities", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(192021)
data <- data.frame(
id = 1:4,
treatment = factor(c("A", "A", "B", "B")),
baseline = rnorm(4)
)
data$curves <- tf_rgp(4, arg = seq(0, 1, length.out = 8))
# Mix tf aesthetics with scalar summaries and regular variables
expect_no_error({
p_mixed <- tf_ggplot(
data,
aes(
tf = curves,
color = treatment, # Regular factor variable
linewidth = tf_fmean(curves), # Scalar summary of tf
alpha = abs(baseline) # Transformation of scalar
)
) +
geom_line()
})
built_mixed <- ggplot_build(p_mixed)
plot_data_mixed <- built_mixed$data[[1]]
# Should have all aesthetics
expect_true("colour" %in% names(plot_data_mixed))
expect_true("linewidth" %in% names(plot_data_mixed))
expect_true("alpha" %in% names(plot_data_mixed))
# Should have 4 groups (one per function)
expect_equal(length(unique(plot_data_mixed$group)), 4)
# Linewidth should vary based on function means
expect_true(length(unique(plot_data_mixed$linewidth)) > 1)
# Alpha should vary based on baseline
expect_true(length(unique(plot_data_mixed$alpha)) > 1)
# Color should reflect treatment levels (2 levels)
expect_equal(length(unique(plot_data_mixed$colour)), 2)
})
test_that("tf transformations preserve grouping correctly", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(222324)
data <- data.frame(
id = 1:6,
group = factor(rep(c("X", "Y", "Z"), each = 2))
)
data$curves <- tf_rgp(6, arg = seq(0, 1, length.out = 5))
# Test transformation with grouping variable
p_transform <- tf_ggplot(
data,
aes(
tf = abs(curves - tf_fmean(curves)), # Center around mean then abs
color = group
)
) +
geom_line()
built_transform <- ggplot_build(p_transform)
plot_data_transform <- built_transform$data[[1]]
# Should have 6 groups (one per function)
expect_equal(length(unique(plot_data_transform$group)), 6)
# Should have 3 colors (for groups X, Y, Z)
expect_equal(length(unique(plot_data_transform$colour)), 3)
# All y values should be non-negative (due to abs)
expect_true(all(plot_data_transform$y >= 0))
# Should have 30 rows (6 functions × 5 points)
expect_equal(nrow(plot_data_transform), 30)
})
test_that("error handling for invalid tf expressions", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(252627)
data <- data.frame(id = 1:2)
data$curves <- tf_rgp(2, arg = seq(0, 1, length.out = 5))
data$not_tf <- rnorm(2)
# Should error when applying tf functions to non-tf objects
expect_error(
{
p <- tf_ggplot(data, aes(tf = abs(not_tf))) +
geom_line()
ggplot_build(p) # Trigger validation
},
"tf.*object|must be.*tf"
)
# Should error when tf aesthetic references non-existent column
expect_error(
{
p <- tf_ggplot(data, aes(tf = nonexistent_func)) +
geom_line()
ggplot_build(p) # Trigger validation
},
"not found|object.*not found"
)
})
test_that("performance with complex tf expressions", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
# Test with moderately large dataset that triggers warning
set.seed(282930)
data <- data.frame(id = 1:100) # 100 functions
data$curves <- tf_rgp(100, arg = seq(0, 1, length.out = 101)) # 101 points each (100 * 101 = 10100 > 10000)
# Create large plot (warning logic needs to be re-added to finalization process)
p_large <- tf_ggplot(
data,
aes(
tf = abs(curves),
color = tf_depth(curves)
)
) +
geom_line()
# But should still build correctly
built_large <- ggplot_build(p_large)
plot_data_large <- built_large$data[[1]]
# Should have 100 groups
expect_equal(length(unique(plot_data_large$group)), 100)
# Should have 10100 rows (100 functions × 101 points)
expect_equal(nrow(plot_data_large), 10100)
# All y values should be non-negative
expect_true(all(plot_data_large$y >= 0))
})
test_that("complex expressions work with faceting", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(313233)
data <- data.frame(
id = 1:8,
condition = factor(rep(c("Control", "Treatment"), each = 4)),
replicate = factor(rep(1:4, 2))
)
data$curves <- tf_rgp(8, arg = seq(0, 1, length.out = 6))
# Test complex expressions with faceting
expect_no_error({
p_facet <- tf_ggplot(
data,
aes(
tf = abs(curves),
color = tf_depth(curves)
)
) +
geom_line() +
facet_wrap(~condition)
})
built_facet <- ggplot_build(p_facet)
# Should have 2 panels (Control, Treatment)
expect_equal(length(unique(built_facet$layout$layout$PANEL)), 2)
# Should have 8 groups total
plot_data_facet <- built_facet$data[[1]]
expect_equal(length(unique(plot_data_facet$group)), 8)
# All y values should be non-negative
expect_true(all(plot_data_facet$y >= 0))
})
test_that("tf expressions work with custom evaluation grids", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
set.seed(343536)
data <- data.frame(id = 1:3)
data$curves <- tf_rgp(3, arg = seq(0, 1, length.out = 21)) # Dense original grid
# Test with custom coarser grid
custom_arg <- seq(0, 1, length.out = 6) # Coarser grid
expect_no_error({
p_custom <- tf_ggplot(data, aes(tf = abs(curves)), arg = custom_arg) +
geom_line()
})
built_custom <- ggplot_build(p_custom)
plot_data_custom <- built_custom$data[[1]]
# Should use custom grid (6 points)
expect_equal(length(unique(plot_data_custom$x)), 6)
expect_equal(sort(unique(plot_data_custom$x)), custom_arg)
# Should have 18 rows (3 functions × 6 points)
expect_equal(nrow(plot_data_custom), 18)
# All y values should be non-negative
expect_true(all(plot_data_custom$y >= 0))
})
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.