skip_on_cran() skip_if_not_installed("SVEMnet") test_that("svem_random_table_multi validates schemas and predicts", { set.seed(7) n <- 40 X1 <- runif(n); X2 <- runif(n) A <- runif(n); B <- runif(n); C <- pmax(0, 1 - A - B) F <- factor(sample(c("lo","hi"), n, TRUE)) y <- 1 + 2*X1 - X2 + 3*A + 1.5*B + 0.5*C + (F=="hi") + rnorm(n, 0, 0.3) z <- 0.5 + 0.8*X1 + 0.4*X2 + rnorm(n, 0, 0.2) d <- data.frame(y, z, X1, X2, A, B, C, F) f1 <- SVEMnet::SVEMnet(y ~ X1 + X2 + A + B + C + F, d, nBoot = 30, glmnet_alpha = 1) f2 <- SVEMnet::SVEMnet(z ~ X1 + X2 + A + B + C + F, d, nBoot = 30, glmnet_alpha = 1) res <- SVEMnet::svem_random_table_multi(list(f1, f2), n = 50) expect_true(is.list(res)) expect_true(all(c("data","pred","all") %in% names(res))) expect_true(all(c("X1","X2","A","B","C","F") %in% names(res$data))) # --- UPDATED: allow old names (y/z or y.pred/z.pred) OR new *_pred names --- pred_names <- names(res$pred) has_old_plain <- all(c("y", "z") %in% pred_names) has_old_dot <- all(c("y.pred", "z.pred") %in% pred_names) has_new_suf <- all(c("y_pred", "z_pred") %in% pred_names) expect_true(has_old_plain || has_old_dot || has_new_suf) expect_equal(nrow(res$data), 50) expect_equal(nrow(res$pred), 50) expect_equal(nrow(res$all), 50) }) test_that("svem_random_table_multi respects blocking for numeric and categorical", { set.seed(2) df_block <- data.frame( y1 = rnorm(40), y2 = rnorm(40), X1 = runif(40), X2 = runif(40), Operator = factor(sample(paste0("Op", 1:3), 40, TRUE)), AmbientTmp = rnorm(40, mean = 22, sd = 2) ) spec_block <- SVEMnet::bigexp_terms( y1 ~ X1 + X2, data = df_block, factorial_order = 2, polynomial_order = 2, blocking = c("Operator", "AmbientTmp") ) fit_b1 <- SVEMnet::SVEMnet( spec_block, df_block, response = "y1", nBoot = 20, glmnet_alpha = 1 ) fit_b2 <- SVEMnet::SVEMnet( spec_block, df_block, response = "y2", nBoot = 20, glmnet_alpha = 1 ) res <- SVEMnet::svem_random_table_multi(list(fit_b1, fit_b2), n = 200) expect_true(is.list(res)) expect_true(all(c("data","pred","all") %in% names(res))) ## Blocking variables are present expect_true(all(c("Operator", "AmbientTmp") %in% names(res$data))) ## Operator (factor) is held fixed at a single level expect_equal(length(unique(res$data$Operator)), 1L) ## AmbientTmp (numeric) is held fixed at a single value (up to tiny numerical noise) expect_true(diff(range(res$data$AmbientTmp)) < 1e-8) ## Row counts align expect_equal(nrow(res$data), 200) expect_equal(nrow(res$pred), 200) expect_equal(nrow(res$all), 200) ## Prediction column names: allow old and new conventions pred_names <- names(res$pred) has_old_plain <- all(c("y1", "y2") %in% pred_names) has_old_dot <- all(c("y1.pred", "y2.pred") %in% pred_names) has_new_suf <- all(c("y1_pred", "y2_pred") %in% pred_names) expect_true(has_old_plain || has_old_dot || has_new_suf) })