data("iris") dat <<- iris # simple ------------------------------------------------------------------ test_that("standardize_parameters (simple)", { r <- as.numeric(cor.test(dat$Sepal.Length, dat$Petal.Length)$estimate) model <- lm(Sepal.Length ~ Petal.Length, data = dat) es <- standardize_parameters(model) expect_equal(es[2, 2], r, tolerance = 0.01) expect_error(standardize_parameters(model, robust = TRUE), NA) }) # Robust ------------------------------------------------------------------ test_that("Robust post hoc", { model <- lm(mpg ~ hp, weights = gear, data = mtcars) expect_error(standardize_parameters(model, method = "basic", robust = TRUE), NA) expect_error(standardize_parameters(model, method = "basic", robust = TRUE, two_sd = TRUE), NA) model <- lm(mpg ~ hp, data = mtcars) expect_error(standardize_parameters(model, method = "basic", robust = TRUE), NA) expect_error(standardize_parameters(model, method = "basic", robust = TRUE, two_sd = TRUE), NA) }) # Labels ------------------------------------------------------------------ test_that("Preserve labels", { fit <- lm(Sepal.Length ~ Species, data = iris) out <- standardize_parameters(fit) expect_snapshot(print(out)) }) # model_parameters ------------------------------- test_that("standardize_parameters (model_parameters)", { skip_on_cran() model <<- lm(mpg ~ cyl + am, data = mtcars) mp <<- model_parameters(model, effects = "fixed") s1 <- standardize_parameters(model, method = "basic") s2 <- standardize_parameters(mp, method = "basic") expect_equal(s1$Parameter, s2$Parameter, tolerance = 1e-4) expect_equal(s1$Std_Coefficient, s2$Std_Coefficient, tolerance = 1e-4) expect_equal(s1$CI_low, s2$CI_low, tolerance = 1e-4) expect_equal(s1$CI_high, s2$CI_high, tolerance = 1e-4) mp_exp <<- model_parameters(model, exponentiate = TRUE, effects = "fixed") se1 <- standardize_parameters(model, method = "basic", exponentiate = TRUE) se2 <- standardize_parameters(mp_exp, method = "basic", exponentiate = TRUE) expect_equal(se1$Parameter, se2$Parameter, tolerance = 1e-4) expect_equal(se1$Std_Coefficient, se2$Std_Coefficient, tolerance = 1e-4) expect_equal(se1$CI_low, se2$CI_low, tolerance = 1e-4) expect_equal(se1$CI_high, se2$CI_high, tolerance = 1e-4) }) # bootstrap_model --------------------------------------------------------- test_that("standardize_parameters (bootstrap_model)", { skip_on_cran() skip_if_not_installed("boot") m <- lm(mpg ~ factor(cyl) + hp, mtcars) set.seed(1) bm_draws <- bootstrap_model(m, iterations = 599) set.seed(1) bm_tab <- bootstrap_parameters(m, iterations = 599) out_true <- standardize_parameters(m, method = "basic") out_boot1 <- standardize_parameters(bm_draws, method = "basic") out_boot2 <- standardize_parameters(bm_tab, method = "basic") expect_equal(out_boot1$Std_Coefficient, out_true$Std_Coefficient, tolerance = 0.05 ) expect_equal(out_boot1, out_boot2, ignore_attr = TRUE) expect_error(standardize_parameters(bm_draws, method = "refit")) expect_error(standardize_parameters(bm_tab, method = "refit")) }) # lm with ci ----------------------------------- test_that("standardize_parameters (lm with ci)", { data("iris") model <- lm(Sepal.Length ~ Species + Petal.Width, data = iris) expect_equal( standardize_parameters(model, method = "refit")$Std_Coefficient, c(0.044, -0.072, -0.060, 0.844), tolerance = 0.01 ) expect_equal( standardize_parameters(model, method = "posthoc")$Std_Coefficient, c(0, -0.072, -0.060, 0.844), tolerance = 0.01 ) expect_equal( standardize_parameters(model, method = "smart")$Std_Coefficient, c(0, -0.170, -0.142, 0.844), tolerance = 0.01 ) z_basic <- standardize_parameters(model, method = "basic") expect_equal( z_basic$Std_Coefficient, c(0, -0.034, -0.028, 0.844), tolerance = 0.01 ) ## CI expect_equal( z_basic$CI_low, c(0, -0.294, -0.433, 0.491), tolerance = 0.01 ) expect_equal( z_basic$CI_high, c(0, 0.225, 0.375, 1.196), tolerance = 0.01 ) z_basic.0.80 <- standardize_parameters(model, ci = 0.8, method = "basic") expect_equal( z_basic.0.80$CI_low, c(0, -0.203, -0.292, 0.614), tolerance = 0.01 ) expect_equal( z_basic.0.80$CI_high, c(0, 0.135, 0.234, 1.073), tolerance = 0.01 ) data("mtcars") m0 <- lm(mpg ~ cyl + factor(am), mtcars) expect_equal( standardize_parameters(m0, method = "refit")[[2]][-1], standardize_parameters(m0, method = "smart")[[2]][-1], tolerance = 0.01 ) expect_equal( standardize_parameters(m0, method = "refit", two_sd = TRUE)[[2]][-1], standardize_parameters(m0, method = "smart", two_sd = TRUE)[[2]][-1], tolerance = 0.01 ) }) # aov --------------------------------------------------------------------- test_that("standardize_parameters (aov)", { dat2 <- iris dat2$Cat1 <- rep_len(c("A", "B"), nrow(dat2)) dat3 <<- dat2 m_aov <- aov(Sepal.Length ~ Species * Cat1, data = dat3) m_lm <- lm(Sepal.Length ~ Species * Cat1, data = dat3) expect_equal(standardize_parameters(m_aov), standardize_parameters(m_lm), ignore_attr = TRUE ) }) # with function interactions" ------------------- test_that("standardize_parameters (with functions / interactions)", { skip_on_cran() X <- scale(rnorm(100), TRUE, FALSE) Z <- scale(rnorm(100), TRUE, FALSE) Y <- scale(Z + X * Z + rnorm(100), TRUE, FALSE) m1 <- lm(Y ~ X * Z) m2 <- lm(Y ~ X * scale(Z)) m3 <- lm(Y ~ scale(X) * Z) m4 <- lm(Y ~ scale(X) * scale(Z)) expect_equal( standardize_parameters(m1, method = "basic")$Std_Coefficient, standardize_parameters(m2, method = "basic")$Std_Coefficient, ignore_attr = TRUE ) expect_equal( standardize_parameters(m1, method = "basic")$Std_Coefficient, standardize_parameters(m3, method = "basic")$Std_Coefficient, ignore_attr = TRUE ) # expect_equal( # standardize_parameters(m1, method = "basic")$Std_Coefficient, # standardize_parameters(m4, method = "basic")$Std_Coefficient # ) # transformed resp or pred should not affect mtcars$cyl_exp <- exp(mtcars$cyl) mtcars$mpg_sqrt <- sqrt(mtcars$mpg) m1 <- lm(exp(cyl) ~ am + sqrt(mpg), mtcars) m2 <- lm(cyl_exp ~ am + mpg_sqrt, mtcars) expect_message({ stdX <- standardize_parameters(m1, method = "refit") }) expect_false(isTRUE(all.equal( stdX[[2]], standardize_parameters(m2, method = "refit")[[2]] ))) expect_equal( standardize_parameters(m1, method = "basic")[[2]], standardize_parameters(m2, method = "basic")[[2]], ignore_attr = TRUE ) # posthoc / smart don't support data transformation expect_message(standardize_parameters(m1, method = "smart")) expect_message(standardize_parameters(m1, method = "posthoc")) }) # exponentiate ------------------------------------------------------------ test_that("standardize_parameters (exponentiate)", { mod_b <- glm(am ~ mpg + cyl + hp, data = mtcars, family = poisson() ) mod_refit <- standardize_parameters(mod_b, method = "refit", exponentiate = TRUE) expect_equal( mod_refit[[2]][-1], standardize_parameters(mod_b, method = "basic", exponentiate = TRUE)[[2]][-1], ignore_attr = TRUE ) expect_equal( mod_refit[[2]][-1], standardize_parameters(mod_b, method = "posthoc", exponentiate = TRUE)[[2]][-1], ignore_attr = TRUE ) expect_equal( mod_refit[[2]][-1], exp(standardize_parameters(mod_b, method = "basic")[[2]])[-1], ignore_attr = TRUE ) mod_b <- glm(am ~ mpg + cyl, data = mtcars, family = binomial() ) mod_refit <- standardize_parameters(mod_b, method = "refit", exponentiate = TRUE) expect_equal( mod_refit[[2]][-1], standardize_parameters(mod_b, method = "basic", exponentiate = TRUE)[[2]][-1], ignore_attr = TRUE ) expect_equal( mod_refit[[2]][-1], standardize_parameters(mod_b, method = "posthoc", exponentiate = TRUE)[[2]][-1], ignore_attr = TRUE ) expect_equal( mod_refit[[2]][-1], exp(standardize_parameters(mod_b, method = "basic")[[2]])[-1], tolerance = 1e-5 ) mod_b <- glm(am ~ mpg + cyl + hp, data = mtcars, family = stats::gaussian() ) mod_refit <- standardize_parameters(mod_b, method = "refit", exponentiate = TRUE) expect_equal( mod_refit[[2]][-1], standardize_parameters(mod_b, method = "basic", exponentiate = TRUE)[[2]][-1], tolerance = 1e-5 ) expect_equal( mod_refit[[2]][-1], standardize_parameters(mod_b, method = "posthoc", exponentiate = TRUE)[[2]][-1], tolerance = 1e-5 ) expect_equal( mod_refit[[2]][-1], exp(standardize_parameters(mod_b, method = "basic")[[2]])[-1], tolerance = 1e-5 ) }) # Bayes ---------------------------------------- test_that("standardize_parameters (Bayes)", { skip_on_cran() skip_if_not_installed("rstanarm") set.seed(1234) suppressWarnings({ model <- rstanarm::stan_glm(Sepal.Length ~ Species + Petal.Width, data = iris, iter = 500, refresh = 0 ) }) set.seed(1234) expect_equal( suppressWarnings(standardize_parameters(model, method = "refit")$Std_Median[1:4]), c(0.03787, -0.06088, -0.04807, 0.84067), tolerance = 0.1 ) set.seed(1234) expect_equal( suppressWarnings(standardize_parameters(model, method = "posthoc")$Std_Median[1:4]), c(0, -0.0586, -0.05258, 0.83883), tolerance = 0.01 ) posts <- standardize_posteriors(model, method = "posthoc") expect_identical(dim(posts), c(1000L, 4L)) expect_s3_class(posts, "data.frame") }) # Pseudo - GLMM -------------------------------- test_that("standardize_parameters (Pseudo - GLMM)", { skip_if_not_installed("datawizard", minimum_version = "0.12.0") skip_on_cran() skip_if_not_installed("lme4") set.seed(1) dat <- data.frame( X = rnorm(1000), Z = rnorm(1000), C = sample(letters[1:3], size = 1000, replace = TRUE), ID = sort(rep_len(letters, 1000)) ) dat <- transform(dat, Y = X + Z + rnorm(1000)) dat <- cbind(dat, datawizard::demean(dat, c("X", "Z"), "ID")) m <- lme4::lmer(Y ~ scale(X_within) * X_between + C + (scale(X_within) | ID), data = dat ) ## No robust methods... (yet) expect_message(standardize_parameters(m, method = "pseudo", robust = TRUE, verbose = FALSE), regexp = "robust") ## Correctly identify within and between terms dev_resp <- standardize_info(m, include_pseudo = TRUE)$Deviation_Response_Pseudo expect_identical(insight::n_unique(dev_resp[c(2, 4, 5, 6)]), 1L) expect_true(dev_resp[2] != dev_resp[3]) ## Calc b <- lme4::fixef(m)[-1] mm <- model.matrix(m)[, -1] SD_x <- numeric(ncol(mm)) SD_x[c(1, 3, 4, 5)] <- apply(mm[, c(1, 3, 4, 5)], 2, sd) SD_x[2] <- sd(tapply(mm[, 2], dat$ID, mean)) m0 <- lme4::lmer(Y ~ 1 + (1 | ID), data = dat) m0v <- insight::get_variance(m0) SD_y <- sqrt(c(m0v$var.residual, m0v$var.intercept)) SD_y <- SD_y[c(1, 2, 1, 1, 1)] expect_equal( data.frame(Deviation_Response_Pseudo = c(SD_y[2], SD_y), Deviation_Pseudo = c(0, SD_x)), standardize_info(m, include_pseudo = TRUE)[, c("Deviation_Response_Pseudo", "Deviation_Pseudo")], tolerance = 1e-5 ) expect_equal( standardize_parameters(m, method = "pseudo")$Std_Coefficient[-1], unname(b * SD_x / SD_y), tolerance = 1e-5 ) ## scaling should not affect m1 <- lme4::lmer(Y ~ X_within + X_between + C + (X_within | ID), data = dat ) m2 <- lme4::lmer(scale(Y) ~ X_within + X_between + C + (X_within | ID), data = dat ) m3 <- lme4::lmer(Y ~ scale(X_within) + X_between + C + (scale(X_within) | ID), data = dat ) m4 <- lme4::lmer(Y ~ X_within + scale(X_between) + C + (X_within | ID), data = dat ) std1 <- standardize_parameters(m1, method = "pseudo") expect_equal(std1$Std_Coefficient, standardize_parameters(m2, method = "pseudo")$Std_Coefficient, tolerance = 0.001 ) expect_equal(std1$Std_Coefficient, standardize_parameters(m3, method = "pseudo")$Std_Coefficient, tolerance = 0.001 ) expect_equal(std1$Std_Coefficient, standardize_parameters(m4, method = "pseudo")$Std_Coefficient, tolerance = 0.001 ) ## Give warning for within that is also between mW <- lme4::lmer(Y ~ X_between + Z_within + C + (1 | ID), dat) mM <- lme4::lmer(Y ~ X + Z + C + (1 | ID), dat) expect_warning(standardize_parameters(mW, method = "pseudo"), regexp = NA) expect_message(standardize_parameters(mM, method = "pseudo"), regexp = "within-group") }) # ZI models --------------------------------------------------------------- test_that("standardize_parameters (pscl)", { skip_on_cran() skip_if_not_installed("pscl") data("bioChemists", package = "pscl") m <- pscl::zeroinfl(art ~ fem + mar + kid5 + ment | kid5 + phd, data = bioChemists) mp <- model_parameters(m, effects = "fixed") sm1 <- standardize_parameters(m, method = "refit") expect_message({ sm2 <- standardize_parameters(m, method = "posthoc") }) suppressMessages({ sm3 <- standardize_parameters(m, method = "basic") sm4 <- standardize_parameters(m, method = "smart") }) # post hoc does it right (bar intercept) expect_equal(sm1$Std_Coefficient[-c(1, 6)], sm2$Std_Coefficient[-c(1, 6)], tolerance = 0.01 ) # basic / smart miss the ZI expect_equal(mp$Coefficient[6:8], sm3$Std_Coefficient[6:8], tolerance = 0.01 ) expect_equal(mp$Coefficient[7:8], sm4$Std_Coefficient[7:8], tolerance = 0.1 ) # get count numerics al right expect_equal(sm1$Std_Coefficient[4:5], sm3$Std_Coefficient[4:5], tolerance = 0.01 ) expect_equal(sm1$Std_Coefficient[4:5], sm4$Std_Coefficient[4:5], tolerance = 0.01 ) }) test_that("include_response | (g)lm", { # lm --- data(iris) iris$Sepal.Length <- iris$Sepal.Length * 5 m <- lm(Sepal.Length ~ Petal.Length + Petal.Width, data = iris) m_z <- datawizard::standardize(m, include_response = FALSE) par_z0 <- standardize_parameters(m, method = "basic") par_z1 <- standardize_parameters(m, include_response = FALSE) par_z2 <- standardize_parameters(m, method = "basic", include_response = FALSE) expect_equal(coef(m_z), par_z1$Std_Coefficient, ignore_attr = TRUE) expect_equal(par_z1$Std_Coefficient[-1], par_z2$Std_Coefficient[-1], tolerance = 1e-5) expect_equal(par_z0$Std_Coefficient * sd(iris$Sepal.Length), par_z2$Std_Coefficient, tolerance = 1e-5) # glm --- m <- glm(am ~ mpg, mtcars, family = binomial()) expect_equal( standardize_parameters(m), standardize_parameters(m, include_response = FALSE), ignore_attr = TRUE ) }) test_that("include_response | parameters", { data(iris) iris$Sepal.Length <- iris$Sepal.Length * 5 m <<- lm(Sepal.Length ~ Petal.Length + Petal.Width, data = iris) # parameters --- pars <- model_parameters(m, effects = "fixed") pars_z0 <- standardize_parameters(pars, method = "basic") pars_z1 <- standardize_parameters(pars, method = "basic", include_response = FALSE) expect_equal(pars_z0$Std_Coefficient[-1] * sd(iris$Sepal.Length), pars_z1$Std_Coefficient[-1], tolerance = 1e-5) # boot --- skip_if_not_installed("boot") pars <- bootstrap_parameters(m) pars_z0 <- standardize_parameters(pars, method = "basic") pars_z1 <- standardize_parameters(pars, method = "basic", include_response = FALSE) expect_equal(pars_z0$Std_Coefficient[-1] * sd(iris$Sepal.Length), pars_z1$Std_Coefficient[-1], tolerance = 1e-5) }) test_that("include_response | bayes", { skip_if_not_installed("rstanarm") skip_on_cran() data(iris) iris$Sepal.Length <- iris$Sepal.Length * 5 m <- rstanarm::stan_glm(Sepal.Length ~ Petal.Length + Petal.Width, data = iris, refresh = 0) expect_warning({ m_z <- datawizard::standardize(m, include_response = FALSE) }) expect_warning({ par_z1 <- standardize_posteriors(m, include_response = FALSE) }) par_z0 <- standardize_posteriors(m, method = "basic") par_z2 <- standardize_posteriors(m, method = "basic", include_response = FALSE) expect_equal(sapply(insight::get_parameters(m_z), mean), sapply(par_z1, mean), tolerance = 0.1) expect_equal(sapply(par_z1, mean)[-1], sapply(par_z2, mean)[-1], tolerance = 0.1) expect_equal(sapply(par_z0, mean) * sd(iris$Sepal.Length), sapply(par_z2, mean), tolerance = 0.1) })