tests/mytests.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_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_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_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_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_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_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 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")
})


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")
})


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)
})



# ----- 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_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_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)
})


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)
})


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)
})

Try the lqmix package in your browser

Any scripts or data that you put into this service are public.

lqmix documentation built on Nov. 5, 2025, 7:15 p.m.