Nothing
context("plsc core and inference")
library(multivarious)
make_signal_blocks <- function(n = 60L, pX = 6L, pY = 5L, d = 2L, noise = 0.05) {
set.seed(123)
Vx <- qr.Q(qr(matrix(rnorm(pX * d), pX, d)))
Vy <- qr.Q(qr(matrix(rnorm(pY * d), pY, d)))
F <- matrix(rnorm(n * d), n, d)
X <- F %*% t(Vx) + noise * matrix(rnorm(n * pX), n, pX)
Y <- F %*% t(Vy) + noise * matrix(rnorm(n * pY), n, pY)
list(X = X, Y = Y, Vx = Vx, Vy = Vy, F = F)
}
make_null_blocks <- function(n = 60L, pX = 6L, pY = 5L) {
set.seed(999)
X <- matrix(rnorm(n * pX), n, pX)
Y <- matrix(rnorm(n * pY), n, pY) # independent
list(X = X, Y = Y)
}
test_that("plsc returns expected shapes and metadata", {
dat <- make_signal_blocks()
fit <- plsc(dat$X, dat$Y, ncomp = 3)
expect_s3_class(fit, c("plsc", "cross_projector", "projector"))
expect_equal(shape(fit, "X"), c(ncol(dat$X), 3))
expect_equal(shape(fit, "Y"), c(ncol(dat$Y), 3))
expect_true(length(fit$singvals) == 3)
expect_true(abs(sum(fit$explained_cov) - 1) < 1e-8)
# scores accessor works
expect_equal(scores(fit, "X"), fit$sx)
expect_equal(scores(fit, "Y"), fit$sy)
})
test_that("perm_test.plsc detects true LVs and stops on nulls", {
dat <- make_signal_blocks(noise = 0.1)
fit <- plsc(dat$X, dat$Y, ncomp = 3)
set.seed(2024)
ptest <- perm_test(fit, dat$X, dat$Y, nperm = 199, comps = 3, parallel = FALSE)
expect_s3_class(ptest, "perm_test_plsc")
expect_lt(ptest$component_results$pval[1], 0.05)
expect_lt(ptest$component_results$pval[2], 0.05)
expect_gt(ptest$component_results$pval[3], 0.05)
expect_equal(ptest$n_significant, 2)
})
test_that("perm_test.plsc controls type I error under independence", {
dat <- make_null_blocks()
fit <- plsc(dat$X, dat$Y, ncomp = 2)
set.seed(42)
ptest <- perm_test(fit, dat$X, dat$Y, nperm = 199, comps = 2, parallel = FALSE)
expect_gt(ptest$component_results$pval[1], 0.05)
})
test_that("perm_test.plsc returns well-formed permutation matrix and sequential count", {
dat <- make_signal_blocks(noise = 0.15, d = 1L)
fit <- plsc(dat$X, dat$Y, ncomp = 2)
set.seed(111)
ptest <- perm_test(fit, dat$X, dat$Y, nperm = 99, comps = 2, alpha = 0.2)
# perm_values has nperm rows and comps columns
expect_equal(dim(ptest$perm_values), c(99, 2))
# all successful permutations counted
expect_equal(ptest$nperm, rep(99, 2))
# n_significant cannot exceed first non-significant component
if (ptest$component_results$pval[2] > 0.2) {
expect_equal(ptest$n_significant, 1)
}
})
test_that("bootstrap.plsc dispatch works and stabilizes signal loadings", {
dat <- make_signal_blocks(noise = 0.05, pX = 4L, pY = 4L, d = 1L)
fit <- plsc(dat$X, dat$Y, ncomp = 1)
set.seed(7)
bres <- bootstrap(fit, nboot = 40, X = dat$X, Y = dat$Y, comps = 1, parallel = FALSE)
expect_s3_class(bres, "bootstrap_plsc_result")
# Signal variables (rows 1:2) should have larger |z| than noise rows (3:4)
zsig <- colMeans(abs(bres$z_vx[1:2, , drop = FALSE]))
znoise <- colMeans(abs(bres$z_vx[3:4, , drop = FALSE]))
expect_gt(zsig, znoise + 1)
})
test_that("bootstrap.plsc sign-alignment keeps loadings oriented and reproducible", {
dat <- make_signal_blocks(noise = 0.02, pX = 5L, pY = 5L, d = 1L)
fit <- plsc(dat$X, dat$Y, ncomp = 1)
set.seed(99)
b1 <- bootstrap(fit, nboot = 25, X = dat$X, Y = dat$Y, comps = 1, parallel = FALSE)
set.seed(99)
b2 <- bootstrap(fit, nboot = 25, X = dat$X, Y = dat$Y, comps = 1, parallel = FALSE)
# reproducible under seed
expect_equal(b1$z_vx, b2$z_vx)
# bootstrap means align in sign with fitted loadings
corr_sign <- sign(crossprod(b1$E_vx, coef(fit, "X")[, 1, drop = FALSE]))
expect_true(all(corr_sign >= 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.