library(dplyr)
library(tidyr)
library(testthat)
set.seed(123)
mu <- c(1, 2, 3)
sigma <- rbind(c(3, 0.5, 0.3), c(0.5, 4, 0.5), c(0.3, 0.5, 5))
baseline_mean <- mu[1]
n <- 20
n_visits <- length(mu)
outcome <- c(replicate(n, sample_mvnorm(mu, sigma)))
ids <- as.factor(rep(paste0("id_", seq.int(n)), each = n_visits))
visits <- as.factor(rep(seq.int(n_visits) - 1, n))
test_data_basics <- function(res, n_visits, n) {
expect_true(is.data.frame(res))
expect_true(all(sapply(res[, c("id", "group", "visit")], is.factor)))
expect_true(all(sapply(res[, ! colnames(res) %in% c("id", "group", "visit")], is.numeric)))
expect_equal(nrow(res), n_visits * n)
expect_equal(nlevels(res$visit), n_visits)
expect_length(unique(res$id), n)
expect_true(
all(
sapply(
res[, c("ind_ice1", "dropout_ice1", "ind_ice2")],
function(x) all(x %in% c(0, 1))
)
)
)
expect_true(all(!is.na(res$outcome_noICE)))
outcome_baseline <- unique(res$outcome_bl)
expect_equal(res$outcome_noICE[seq(from = 1, to = n_visits * n, by = n_visits)], outcome_baseline)
expect_equal(res$outcome[seq(from = 1, to = n_visits * n, by = n_visits)], outcome_baseline)
}
test_that("set_simul_pars", {
pars <- set_simul_pars(
mu = mu,
sigma = sigma,
n = n
)
expect_equal(list(pars$mu, pars$sigma, pars$n), list(mu, sigma, n))
expect_true(
all(c(pars$prob_ice1, pars$prob_post_ice1_dropout, pars$prob_ice2, pars$prob_miss) == 0)
)
expect_true(
pars$or_outcome_ice1 == 1
)
expect_true(validate(pars))
expect_equal(class(pars), "simul_pars")
pars$prob_ice1 <- rep(0.5, n_visits - 1)
expect_true(validate(pars))
pars$prob_ice2 <- NULL
expect_error(validate(pars))
pars$prob_ice2 <- 0.5
pars$prob_dropout <- 2
expect_error(validate(pars))
pars$prob_dropout <- NULL
pars$prob_ice2 <- 2
expect_error(
validate(pars),
regexp = "`prob_ice2`"
)
pars$prob_ice2 <- 0.5
pars$sigma[1, 1] <- NA
expect_error(validate(pars))
expect_error(set_simul_pars(mu = mu))
})
test_that("simulate_dropout", {
prob_dropout <- 0
res <- simulate_dropout(prob_dropout, ids)
expect_equal(res, rep(0, length(ids)))
prob_dropout <- 1
res <- simulate_dropout(prob_dropout, ids)
expect_equal(res, rep(c(0, 1, 1), n))
prob_dropout <- 0.5
res <- simulate_dropout(prob_dropout, ids)
expect_true(all(res %in% c(0, 1)))
expect_length(res, length(ids))
prob_dropout <- 1
subset <- rep(0, length(ids))
res <- simulate_dropout(prob_dropout, ids, subset)
expect_equal(res, rep(0, length(ids)))
subset <- rep(c(0, 0, 1), n)
res <- simulate_dropout(prob_dropout, ids, subset)
expect_length(res, length(ids))
expect_equal(res[subset == 0], subset[subset == 0])
expect_true(all(res[subset == 1] == 1))
subset <- rep(c(1, 1, 1), n)
res <- simulate_dropout(prob_dropout, ids, subset)
expect_equal(res, rep(c(0, 1, 1), n))
prob_dropout <- 0
subset <- rep(0, length(ids))
res <- simulate_dropout(prob_dropout, ids, subset)
expect_equal(res, rep(0, length(ids)))
subset <- rep(c(0, 0, 1), n)
res <- simulate_dropout(prob_dropout, ids, subset)
expect_equal(res, rep(0, length(ids)))
subset <- rep(c(1, 1, 1), n)
res <- simulate_dropout(prob_dropout, ids, subset)
expect_equal(res, rep(0, length(ids)))
})
test_that("simulate_ice", {
pars <- set_simul_pars(mu, sigma, n)
res <- simulate_ice(outcome, visits, ids, pars$prob_ice1, pars$or_outcome_ice1, baseline_mean)
expect_equal(res, rep(0, length(ids)))
pars$prob_ice1 <- 1
res <- simulate_ice(outcome, visits, ids, pars$prob_ice1, pars$or_outcome_ice1, baseline_mean)
expect_equal(res, rep(c(0, 1, 1), n))
pars$prob_ice1 <- rep(1, n_visits - 1)
res <- simulate_ice(outcome, visits, ids, pars$prob_ice1, pars$or_outcome_ice1, baseline_mean)
expect_equal(res, rep(c(0, 1, 1), n))
pars$prob_ice1 <- 0.1
pars$or_outcome_ice1 <- 3
res <- simulate_ice(outcome, visits, ids, pars$prob_ice1, pars$or_outcome_ice1, baseline_mean)
expect_length(res, length(ids))
expect_true(all(res %in% c(0, 1)))
expect_true(all(res[seq(from = 1, to = length(ids), by = n_visits)] == 0))
})
test_that("adjust_trajectories_single", {
outcome <- outcome[1:3]
distr_pars_group <- list(mu = mu, sigma = sigma)
strategy_fun <- getStrategies()$CIR
# no missing values
res <- adjust_trajectories_single(distr_pars_group, outcome, strategy_fun, distr_pars_ref = NULL)
expect_equal(res, outcome)
distr_pars_ref <- distr_pars_group
distr_pars_ref$sigma[1, 1] <- 1
distr_pars_ref$mu <- c(3, 6, 9)
res <- adjust_trajectories_single(distr_pars_group, outcome, strategy_fun, distr_pars_ref)
expect_equal(res, outcome)
# missing values
outcome[2:3] <- NA
res <- adjust_trajectories_single(distr_pars_group, outcome, strategy_fun, distr_pars_ref)
expect_true(all(!is.na(res)))
expect_equal(res[1], outcome[1])
})
test_that("adjust_trajectories", {
ind_ice <- unlist(
tapply(
rep(0, length(ids)),
ids,
function(x) {
p <- runif(1)
if (p <= 0.33) {
x[2:3] <- 1
} else if (p <= 0.66) {
x[3] <- 1
}
return(x)
}
),
use.names = FALSE
)
ids <- factor(ids, levels = unique(ids))
distr_pars_group <- list(mu = mu, sigma = sigma)
strategy_fun <- getStrategies()$JR
res <- adjust_trajectories(
distr_pars_group,
outcome,
ids,
ind_ice = rep(0, length(ids)),
strategy_fun, distr_pars_ref = NULL
)
expect_equal(res, outcome)
distr_pars_ref <- distr_pars_group
distr_pars_ref$sigma[1, 1] <- 1
distr_pars_ref$mu <- c(3, 6, 9)
res <- adjust_trajectories(
distr_pars_group,
outcome,
ids,
ind_ice,
strategy_fun,
distr_pars_ref
)
expect_length(res, length(ids))
expect_true(all(!is.na(res)))
expect_false(identical(res, outcome))
outcome[2] <- NA
expect_error(
adjust_trajectories(
distr_pars_group,
outcome,
ids,
ind_ice,
strategy_fun,
distr_pars_ref
)
)
})
test_that("generate_data_single", {
pars_group <- set_simul_pars(
mu = mu,
sigma = sigma,
n = n
)
strategy_fun <- getStrategies()$CR
# no ICEs
res <- generate_data_single(pars_group, strategy_fun, distr_pars_ref = NULL)
test_data_basics(res, n_visits, n)
expect_true(all(!is.na(res)))
expect_true(identical(res$outcome_noICE, res$outcome))
expect_true(all(c(res$ind_ice1, res$dropout_ice1, res$ind_ice2) == 0))
# only ICE1
pars_group$prob_ice1 <- 1
res <- generate_data_single(pars_group, strategy_fun, distr_pars_ref = NULL)
test_data_basics(res, n_visits, n)
expect_equal(res$ind_ice1, rep(c(0, 1, 1), n))
expect_false(identical(res$outcome_noICE, res$outcome))
# add dropout
pars_group$prob_post_ice1_dropout <- 1
res <- generate_data_single(pars_group, strategy_fun, distr_pars_ref = NULL)
test_data_basics(res, n_visits, n)
expect_equal(res$dropout_ice1, rep(c(0, 1, 1), n))
expect_true(all(is.na(res$outcome[-seq(from = 1, to = n_visits * n, by = n_visits)])))
# only ice2
pars_group$prob_ice1 <- 0
pars_group$prob_post_ice1_dropout <- 0
pars_group$prob_ice2 <- 1
res <- generate_data_single(pars_group, strategy_fun, distr_pars_ref = NULL)
test_data_basics(res, n_visits, n)
expect_equal(res$ind_ice2, rep(c(0, 1, 1), n))
expect_true(all(is.na(res$outcome[-seq(from = 1, to = n_visits * n, by = n_visits)])))
# both ice1 and ice2 have prob 1 -> expect only ice1
pars_group$prob_ice1 <- 1
pars_group$prob_ice2 <- 1
res <- generate_data_single(pars_group, strategy_fun, distr_pars_ref = NULL)
test_data_basics(res, n_visits, n)
expect_equal(res$ind_ice2, rep(c(0, 0, 0), n))
expect_equal(res$ind_ice1, rep(c(0, 1, 1), n))
expect_true(all(!is.na(res$outcome)))
pars_group$prob_post_ice1_dropout <- 1
res <- generate_data_single(pars_group, strategy_fun, distr_pars_ref = NULL)
test_data_basics(res, n_visits, n)
expect_equal(res$ind_ice2, rep(c(0, 0, 0), n))
expect_equal(res$ind_ice1, rep(c(0, 1, 1), n))
expect_true(all(is.na(res$outcome[-seq(from = 1, to = n_visits * n, by = n_visits)])))
# prob of both ICEs different than 0 or 1
pars_group$prob_ice1 <- 0.7
pars_group$prob_ice2 <- 0.7
res <- generate_data_single(pars_group, strategy_fun, distr_pars_ref = NULL)
test_data_basics(res, n_visits, n)
expect_true(all(res$ind_ice2 * res$ind_ice1 == 0)) # they cannot both happen
expect_true(all(is.na(res$outcome[(pars_group$prob_ice1 == 1 &
pars_group$prob_post_ice1_dropout == 1) |
pars_group$prob_ice2 == 1])))
})
test_that("simulate_data", {
pars_t <- set_simul_pars(
mu = mu,
sigma = sigma,
n = n
)
pars_c <- pars_t
pars_c$mu <- c(3, 6, 9)
pars_c$sigma[3, 3] <- 10
post_ice1_traj <- "JR"
# no ICEs
res <- simulate_data(pars_c, pars_t, post_ice1_traj)
test_data_basics(res, n_visits, 2 * n)
# ICE1
pars_c$prob_ice1 <- pars_t$prob_ice1 <- c(0.4, 0.5)
pars_c$or_outcome_ice1 <- pars_t$or_outcome_ice1 <- 3
pars_c$prob_post_ice1_dropout <- pars_t$prob_post_ice1_dropout <- 0.5
post_ice1_traj <- "CIR"
set.seed(123)
res <- simulate_data(pars_c, pars_t, post_ice1_traj)
test_data_basics(res, n_visits, 2 * n)
# custom function
myfun <- function(pars_group, pars_ref, index_mar) return(strategy_CIR(pars_group, pars_ref, index_mar))
post_ice1_traj <- "myfun"
set.seed(123)
res_cir <- simulate_data(pars_c, pars_t, post_ice1_traj, strategies = getStrategies(myfun = myfun))
test_data_basics(res, n_visits, 2 * n)
expect_equal(res, res_cir) # custom function is just CIR
pars_c <- pars_t <- set_simul_pars(
mu = mu,
sigma = sigma,
n = n,
prob_miss = 1
)
post_ice1_traj <- "JR"
res <- simulate_data(pars_c, pars_t, post_ice1_traj)
expect_true(all(is.na(res$outcome[-seq(from = 1, to = n_visits * 2 * n, by = n_visits)])))
pars_c <- pars_t <- set_simul_pars(
mu = mu,
sigma = sigma,
n = n,
prob_ice2 = 1
)
res <- simulate_data(pars_c, pars_t, post_ice1_traj)
expect_true(all(is.na(res$outcome[-seq(from = 1, to = n_visits * 2 * n, by = n_visits)])))
class(pars_c) <- NULL
expect_error(simulate_data(pars_c, pars_t, post_ice1_traj))
})
test_that("generic tests to ensure simulate_data is working as expected", {
expect_around <- function(x, e, margin = 0.05) {
expect_true(
all(c(
x <= e * (1 + margin),
x >= e * (1 - margin)
))
)
}
set.seed(1241)
simpar_c_sigma <- list(
sd = c(5, 4, 2),
cor = c(0.1, 0.2, 0.3)
)
simpar_c <- set_simul_pars(
mu = c(10, 10, 10),
sigma = as_vcov(simpar_c_sigma$sd, simpar_c_sigma$cor),
n = 9000,
prob_ice1 = c(0.25),
or_outcome_ice1 = 1,
prob_post_ice1_dropout = 0,
prob_ice2 = 0,
prob_miss = 0.2
)
simpar_t_sigma <- list(
sd = c(1, 2, 3),
cor = c(0.3, 0.4, 0.5)
)
simpar_t <- set_simul_pars(
mu = c(10, 30, 60),
sigma = as_vcov(simpar_t_sigma$sd, simpar_t_sigma$cor),
n = 7000,
prob_ice1 = c(0.75, 0),
or_outcome_ice1 = 1,
prob_post_ice1_dropout = 0,
prob_ice2 = 0,
prob_miss = 0
)
dat <- simulate_data(
pars_c = simpar_c,
pars_t = simpar_t,
post_ice1_traj = "JR"
) %>%
as_tibble()
count <- dat %>%
group_by(group) %>%
tally() %>%
pull(n)
expect_equal(
count,
c(simpar_c$n, simpar_t$n) * 3
)
control_nrow <- dat %>%
filter(group == "Control") %>%
filter(!is.na(outcome)) %>%
filter(outcome_noICE != outcome) %>%
nrow()
expect_equal(
control_nrow,
0
)
stat_c <- dat %>%
filter(group == "Control") %>%
group_by(visit) %>%
summarise(
m = mean(outcome, na.rm = TRUE),
v = var(outcome, na.rm = TRUE),
nd = mean(ind_ice1),
nm = mean(is.na(outcome))
)
stat_t <- dat %>%
filter(group == "Intervention") %>%
group_by(visit) %>%
summarise(
m = mean(outcome),
v = var(outcome_noICE),
nd = mean(ind_ice1)
)
pt <- c(0, simpar_t$prob_ice1)
cum_pt <- 1 - cumprod(1 - pt)
e_mean <- (simpar_t$mu * (1 - cum_pt)) + (simpar_c$mu * cum_pt)
expect_around(stat_t$m, e_mean)
expect_around(stat_t$v, diag(simpar_t$sigma))
expect_around(stat_c$m, simpar_c$mu)
expect_around(stat_c$v, diag(simpar_c$sigma))
expect_around(
stat_c$nm,
c(0, rep(simpar_c$prob_miss, length(simpar_c$mu) - 1))
)
pc <- c(0, rep(simpar_c$prob_ice1, length(simpar_c$mu) - 1))
cum_pc <- 1 - cumprod(1 - pc)
expect_around(stat_c$nd, cum_pc)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.