R Under development (unstable) (2025-10-16 r88927 ucrt) -- "Unsuffered Consequences" Copyright (C) 2025 The R Foundation for Statistical Computing Platform: x86_64-w64-mingw32/x64 R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(testthat) > library(lqmix) > > # build a small dataset ---- > set.seed(123) > n_subj = 4 > times = 1:3 > df = expand.grid(id = 1:n_subj, time = times) > df$meas = rnorm(nrow(df)) > df$trt = sample(c(0,1), nrow(df), replace = TRUE) > > > > # test errors in the lqmix function ----- > test_that("errors for missing or wrong data arg", { + expect_error(lqmix(formula = meas ~ trt, randomTC = ~1, group="id", time="time", G=2, data = NULL), + "No input dataset has been given\\.") + expect_error(lqmix(formula = meas ~ trt, randomTC = ~1, group="id", time="time", G=2, data = list()), + "`data' must be a data frame\\.") + }) Test passed 😸 > > test_that("error when start=2 but parInit empty", { + expect_error(lqmix(formula = meas ~ trt, randomTC = ~1, group="id", time="time", G=2, data = df, start=2, parInit = list()), + "No input parameters have been given with start = 2\\.") + }) Test passed 🎊 > > test_that("quantile out of range triggers error", { + expect_error(lqmix(formula = meas ~ trt, randomTC = ~1, group="id", time="time", G=2, data = df, qtl = 0), + "Quantile level out of range") + expect_error(lqmix(formula = meas ~ trt, randomTC = ~1, group="id", time="time", G=2, data = df, qtl = 1), + "Quantile level out of range") + }) Test passed 🥇 > > > test_that("TC branch: errors for missing arguments", { + # randomTC specified but G missing + expect_error( + lqmix(formula = meas ~ trt, randomTC = ~1, + group = "id", time = "time", data = df), + "Argument 'G' must be specified to fit a linear quantile mixture with TC random coefficients\\." + ) + + # G provided but randomTC missing + expect_error( + lqmix(formula = meas ~ trt, randomTV = ~1, m = 2, G = 2, + group = "id", time = "time", data = df), + "Argument 'G' is provided, but no 'randomTC' formula is specified\\. To include TC random ciefficients, define 'randomTC' as well\\." + ) + + # m provided but randomTV missing + expect_error( + lqmix(formula = meas ~ trt, randomTC = ~1, G = 2, m = 2, + group = "id", time = "time", data = df), + "Argument 'm' is provided, but no 'randomTV' formula is specified\\. To include TV random coefficients, define 'randomTV' as well\\." + ) + }) Test passed 🌈 > > > test_that("TV branch: errors for missing arguments", { + # randomTV specified but m missing + expect_error( + lqmix(formula = meas ~ trt, randomTV = ~1, + group = "id", time = "time", data = df), + "Argument 'm' must be specified to fit a linear quantile mixture with TV random coefficients\\." + ) + + # m provided but randomTV missing + expect_error( + lqmix(formula = meas ~ trt, randomTC = ~1, G = 2, m = 2, + group = "id", time = "time", data = df), + "Argument 'm' is provided, but no 'randomTV' formula is specified\\. To include TV random coefficients, define 'randomTV' as well\\." + ) + + # G provided but randomTC missing + expect_error( + lqmix(formula = meas ~ trt, randomTV = ~1, m = 2, G = 2, + group = "id", time = "time", data = df), + "Argument 'G' is provided, but no 'randomTC' formula is specified\\. To include TC random ciefficients, define 'randomTC' as well\\." + ) + }) Test passed 🎊 > > > > test_that("TCTV branch: errors for missing arguments", { + # --- TCTV branch errors --- + # both randomTC and randomTV provided, but G or m missing + expect_error( + lqmix(formula = meas ~ trt, randomTC = ~1, randomTV = ~1, m = NULL, + group = "id", time = "time", data = df), + "Both 'G' and 'm' must be specified to fit a linear quantile mixture with TC and TV random coefficients\\." + ) + }) Test passed 🥳 > > test_that("No random-coefficients model", { + expect_error( + lqmix(formula = meas ~ trt, + group = "id", time = "time", data = df), + "No random-coefficients formulas \\('randomTC' or 'randomTV'\\) have been specified\\. The model corresponds to a standard linear quantile regression without random coefficients\\. Please use the function lqr\\(\\)\\." + ) + }) Test passed 🥇 > > > # ----- test that lqmix retuns proper objects and estimates ---- > > test_that("TC branch calls lqmixTC() and returns an lqmix object.", { + + res = lqmix(formula = meas ~ trt, randomTC = ~1, group="id", time="time", G=2, data = df, qtl=0.5, se=FALSE) + expect_s3_class(res, "lqmix") + expect_named(res, c("betaf","betarTC", "pg", "sigma.e", + "npar", "AIC", "BIC", "qtl", "G", "nsbjs", "nobs", "postTC", "miss", + "model", "mmf", "mmrTC", "y", + "lk","scale","call","formula","randomTC","group","time"), ignore.order = TRUE, ignore.case = TRUE) + expect_equal(res$formula, meas ~ trt) + expect_equal(res$randomTC, ~1) + expect_equal(c(round(res$betarTC,3)), c(-0.490, 0.663)) + expect_null(res$randomTV) + expect_equal(res$group, "id") + expect_equal(res$time, "time") + }) --------|-------|-------|--------|-------------|-------------| model | qtl | G | iter | lk | (lk-lko) | --------|-------|-------|--------|-------------|-------------| TC | 0.5 | 2 | 0 | -16.455 | NA | TC | 0.5 | 2 | 6 | -14.1891 | 7.44091e-07 | --------|-------|-------|--------|-------------|-------------| Test passed 🎊 > > > test_that("TV branch dispatches to lqmixTV and returns lqmix object", { + + res = lqmix(formula = meas ~ trt, randomTV = ~1, group="id", time="time", m=2, data = df, qtl=0.5, se=FALSE) + expect_s3_class(res, "lqmix") + expect_named(res, c("betaf","betarTV", "delta","Gamma", "sigma.e", + "npar", "AIC", "BIC", "qtl", "m", "nsbjs", "nobs", "postTV", "miss", + "model", "mmf", "mmrTV", "y", + "lk","scale","call","formula","randomTV","group","time"), ignore.order = TRUE) + expect_equal(res$randomTV, ~1) + expect_null(res$randomTC) + expect_equal(c(round(res$betarTV,3)), c(-0.490, 0.663)) + expect_equal(res$group, "id") + expect_equal(res$time, "time") + }) --------|-------|-------|--------|-------------|-------------| model | qtl | G | iter | lk | (lk-lko) | --------|-------|-------|--------|-------------|-------------| TV | 0.5 | 2 | 0 | -16.3348 | NA | TV | 0.5 | 2 | 10 | -14.2394 | 0.0109862 | TV | 0.5 | 2 | 20 | -14.194 | 0.00123772 | TV | 0.5 | 2 | 30 | -14.1897 | 0.000138095 | TV | 0.5 | 2 | 40 | -14.1891 | 1.84027e-05 | TV | 0.5 | 2 | 44 | -14.1891 | 8.26667e-06 | --------|-------|-------|--------|-------------|-------------| Test passed 😀 > > > test_that("TCTV branch dispatches to lqmixTCTV and returns lqmix object", { + + res = lqmix(formula = meas ~ trt, randomTC = ~trt, randomTV = ~1, group="id", time="time", G=2, m=2, data = df, qtl=0.5, se=FALSE) + expect_named(res, c("betarTV","betarTC", "pg","delta","Gamma", "sigma.e", + "npar", "AIC", "BIC", "qtl", "m", "G", "nsbjs", "nobs", "postTC", "postTV", "miss", + "model", "mmrTC", "mmrTV", "y", + "lk","scale","call","formula", "randomTC", "randomTV","group","time"), ignore.order = TRUE) + expect_null(res$beta) + expect_null(res$mmf) + expect_s3_class(res, "lqmix") + expect_equal(c(round(res$betarTC,3)), c(-0.289, 1.199)) + expect_equal(res$randomTC, ~trt) + expect_equal(res$randomTV, ~1) + }) --------|-------|-------|-------|--------|-------------|-------------| model | qtl | m | G | iter | lk | (lk-lko) | --------|-------|-------|-------|--------|-------------|-------------| TCTV | 0.5 | 2 | 2 | 0 | -18.6194 | NA | TCTV | 0.5 | 2 | 2 | 10 | -13.6478 | 0.00168698 | TCTV | 0.5 | 2 | 2 | 20 | -13.6355 | 0.000964199 | TCTV | 0.5 | 2 | 2 | 30 | -13.6286 | 0.00048556 | TCTV | 0.5 | 2 | 2 | 40 | -13.6254 | 0.000226023 | TCTV | 0.5 | 2 | 2 | 50 | -13.6238 | 0.000124414 | TCTV | 0.5 | 2 | 2 | 60 | -13.6228 | 7.9931e-05 | TCTV | 0.5 | 2 | 2 | 70 | -13.6221 | 5.5466e-05 | TCTV | 0.5 | 2 | 2 | 80 | -13.6217 | 4.00627e-05 | TCTV | 0.5 | 2 | 2 | 90 | -13.6213 | 2.9709e-05 | TCTV | 0.5 | 2 | 2 | 100 | -13.6211 | 2.24682e-05 | TCTV | 0.5 | 2 | 2 | 110 | -13.6209 | 1.72536e-05 | TCTV | 0.5 | 2 | 2 | 120 | -13.6207 | 1.34099e-05 | TCTV | 0.5 | 2 | 2 | 130 | -13.6206 | 1.05227e-05 | TCTV | 0.5 | 2 | 2 | 133 | -13.6206 | 9.79981e-06 | --------|-------|-------|-------|--------|-------------|-------------| Test passed 😀 > > > > # ----- test that search_lqmix retuns proper objects and estimates ---- > > test_that("search_lqmix: errors for missing Gv and mv", { + expect_error(search_lqmix(formula = y ~ x, data = df), + "No values for both Gv and mv are provided\\.") + }) Test passed 🥳 > > test_that("search_lqmix: errors for unsupported method", { + expect_error(search_lqmix(formula = y ~ x, data = df, Gv = 1, method = "unknown"), + "The method specified for selecting the optimal model is not supported\\.") + }) Test passed 🎊 > > > test_that("search_lqmix: TC branch calls lqmixTC and returns search_lqmix object", { + + res = search_lqmix(formula = meas ~ trt, randomTC = ~1, group = "id", time = "time", + data = df, Gv = 1:2, method = "bic", se = FALSE, nran = 0) + + expect_s3_class(res, "search_lqmix") + expect_named(res, c("optimal","allmodels","lkv","aicv","bicv", + "qtl","Gv","mv","method","call","formula","randomTC","group","time"), + ignore.order = TRUE, ignore.case = TRUE) + expect_equal(res$formula, meas ~ trt) + expect_equal(round(c(res$optimal$betarTC),3), c(-0.490, 0.663)) + expect_equal(res$randomTC, ~1) + expect_null(res$randomTV) + }) Search the optimal linear quantile mixture model ************************************************* --------|-------|--------|-------------| model | qtl | iter | lk | --------|-------|--------|-------------| HOM | 0.5 | 0 | -16.2719 | --------|-------|--------|-------------| --------|-------|-------|--------|-------------|-------------| model | qtl | G | iter | lk | (lk-lko) | --------|-------|-------|--------|-------------|-------------| TC | 0.5 | 2 | 0 | -16.455 | NA | TC | 0.5 | 2 | 6 | -14.1891 | 7.44091e-07 | --------|-------|-------|--------|-------------|-------------| Test passed 😸 > > > test_that("search_lqmix: TV branch calls lqmixTV and returns search_lqmix object", { + + res <- search_lqmix(formula = meas ~ trt, randomTV = ~1, group = "id", time = "time", + data = df, mv = 1:2, method = "bic", se = FALSE, nran = 0) + + expect_s3_class(res, "search_lqmix") + expect_named(res, c("optimal","allmodels","lkv","aicv","bicv", + "qtl","Gv","mv","method","call","formula","randomTV","group","time"), + ignore.order = TRUE, ignore.case = TRUE) + expect_equal(round(c(res$optimal$betarTV),3), c(-0.490, 0.663)) + expect_equal(res$formula, meas ~ trt) + expect_equal(res$randomTV, ~1) + expect_null(res$randomTC) + }) Search the optimal linear quantile mixture model ************************************************* --------|-------|--------|-------------| model | qtl | iter | lk | --------|-------|--------|-------------| HOM | 0.5 | 0 | -16.2719 | --------|-------|--------|-------------| --------|-------|-------|--------|-------------|-------------| model | qtl | G | iter | lk | (lk-lko) | --------|-------|-------|--------|-------------|-------------| TV | 0.5 | 2 | 0 | -16.3348 | NA | TV | 0.5 | 2 | 10 | -14.2394 | 0.0109862 | TV | 0.5 | 2 | 20 | -14.194 | 0.00123772 | TV | 0.5 | 2 | 30 | -14.1897 | 0.000138095 | TV | 0.5 | 2 | 40 | -14.1891 | 1.84027e-05 | TV | 0.5 | 2 | 44 | -14.1891 | 8.26667e-06 | --------|-------|-------|--------|-------------|-------------| Test passed 🌈 > > > test_that("search_lqmix: TCTV branch calls lqmixTCTV and returns search_lqmix object", { + + res <- search_lqmix(formula = meas ~ trt, randomTC = ~trt, randomTV = ~1, + group = "id", time = "time", data = df, Gv = 1:2, mv = 1:2, + method = "bic", se = FALSE, nran = 0) + + expect_s3_class(res, "search_lqmix") + expect_named(res, c("optimal","allmodels","lkv","aicv","bicv", + "qtl","Gv","mv","method","call","formula","randomTC", "randomTV","group","time"), + ignore.order = TRUE, ignore.case = TRUE) + expect_equal(round(c(res$optimal$betarTC),3), c(0.138, 1.292)) + expect_equal(res$randomTC, ~trt) + expect_equal(res$randomTV, ~1) + }) Search the optimal linear quantile mixture model ************************************************* --------|-------|--------|-------------| model | qtl | iter | lk | --------|-------|--------|-------------| HOM | 0.5 | 0 | -16.2719 | --------|-------|--------|-------------| --------|-------|-------|--------|-------------|-------------| model | qtl | G | iter | lk | (lk-lko) | --------|-------|-------|--------|-------------|-------------| TC | 0.5 | 2 | 0 | -14.581 | NA | TC | 0.5 | 2 | 7 | -13.8681 | 3.09715e-06 | --------|-------|-------|--------|-------------|-------------| --------|-------|-------|--------|-------------|-------------| model | qtl | G | iter | lk | (lk-lko) | --------|-------|-------|--------|-------------|-------------| TV | 0.5 | 2 | 0 | -16.3348 | NA | TV | 0.5 | 2 | 10 | -14.2394 | 0.0109862 | TV | 0.5 | 2 | 20 | -14.194 | 0.00123772 | TV | 0.5 | 2 | 30 | -14.1897 | 0.000138095 | TV | 0.5 | 2 | 40 | -14.1891 | 1.84027e-05 | TV | 0.5 | 2 | 44 | -14.1891 | 8.26667e-06 | --------|-------|-------|--------|-------------|-------------| --------|-------|-------|-------|--------|-------------|-------------| model | qtl | m | G | iter | lk | (lk-lko) | --------|-------|-------|-------|--------|-------------|-------------| TCTV | 0.5 | 2 | 2 | 0 | -18.6194 | NA | TCTV | 0.5 | 2 | 2 | 10 | -13.6478 | 0.00168698 | TCTV | 0.5 | 2 | 2 | 20 | -13.6355 | 0.000964199 | TCTV | 0.5 | 2 | 2 | 30 | -13.6286 | 0.00048556 | TCTV | 0.5 | 2 | 2 | 40 | -13.6254 | 0.000226023 | TCTV | 0.5 | 2 | 2 | 50 | -13.6238 | 0.000124414 | TCTV | 0.5 | 2 | 2 | 60 | -13.6228 | 7.9931e-05 | TCTV | 0.5 | 2 | 2 | 70 | -13.6221 | 5.5466e-05 | TCTV | 0.5 | 2 | 2 | 80 | -13.6217 | 4.00627e-05 | TCTV | 0.5 | 2 | 2 | 90 | -13.6213 | 2.9709e-05 | TCTV | 0.5 | 2 | 2 | 100 | -13.6211 | 2.24682e-05 | TCTV | 0.5 | 2 | 2 | 110 | -13.6209 | 1.72536e-05 | TCTV | 0.5 | 2 | 2 | 120 | -13.6207 | 1.34099e-05 | TCTV | 0.5 | 2 | 2 | 130 | -13.6206 | 1.05227e-05 | TCTV | 0.5 | 2 | 2 | 133 | -13.6206 | 9.79981e-06 | --------|-------|-------|-------|--------|-------------|-------------| Test passed 🥇 > > > > > > > proc.time() user system elapsed 6.54 0.54 7.07