## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4.1, dpi = 144 ) library(drmTMB) ## ----------------------------------------------------------------------------- miss_control() ## ----------------------------------------------------------------------------- set.seed(20260531) n <- 40 growth_data <- data.frame( temperature = seq(-1.6, 1.6, length.out = n) ) growth_data$growth <- 0.5 + 0.8 * growth_data$temperature + rnorm(n, sd = 0.25) growth_data$growth[c(6, 17, 32)] <- NA_real_ fit_response <- drmTMB( bf(growth ~ temperature, sigma ~ 1), family = gaussian(), data = growth_data, missing = miss_control(response = "include"), control = drm_control(se = FALSE) ) ## ----------------------------------------------------------------------------- nobs(fit_response) length(fitted(fit_response)) sum(is.na(residuals(fit_response))) ## ----------------------------------------------------------------------------- head(data.frame( original_row = seq_along(fitted(fit_response)), observed_y = !is.na(residuals(fit_response)), fitted = fitted(fit_response), residual = residuals(fit_response) ), 10) ## ----------------------------------------------------------------------------- trait_data <- data.frame( x = seq(-1.4, 1.4, length.out = 36) ) trait_data$activity <- 0.3 + 0.7 * trait_data$x + rnorm(36, sd = 0.25) trait_data$boldness <- -0.1 - 0.4 * trait_data$x + rnorm(36, sd = 0.30) trait_data$activity[c(5, 16, 29)] <- NA_real_ trait_data$boldness[c(8, 16, 31)] <- NA_real_ fit_pair <- drmTMB( bf( mu1 = activity ~ x, mu2 = boldness ~ x, sigma1 = ~1, sigma2 = ~1, rho12 = ~1 ), family = c(gaussian(), gaussian()), data = trait_data, missing = miss_control(response = "include"), control = drm_control(se = FALSE) ) pair_residuals <- residuals(fit_pair) table( activity_observed = !is.na(pair_residuals[, 1]), boldness_observed = !is.na(pair_residuals[, 2]) ) ## ----------------------------------------------------------------------------- set.seed(20260532) n <- 48 predictor_data <- data.frame( moisture = seq(-1.5, 1.5, length.out = n), canopy = cos(seq_len(n) / 5) ) predictor_data$body_mass_full <- 0.2 + 0.7 * predictor_data$moisture - 0.2 * predictor_data$canopy + rnorm(n, sd = 0.08) predictor_data$growth <- 0.6 + 1.1 * predictor_data$body_mass_full - 0.3 * predictor_data$moisture + rnorm(n, sd = 0.20) predictor_data$body_mass <- predictor_data$body_mass_full predictor_data$body_mass[c(7, 19, 34, 43)] <- NA_real_ fit_predictor <- drmTMB( bf(growth ~ moisture + mi(body_mass), sigma ~ 1), family = gaussian(), data = predictor_data, impute = list(body_mass = body_mass ~ moisture + canopy), missing = miss_control(predictor = "model") ) coef(fit_predictor, "mu") imputed(fit_predictor) ## ----------------------------------------------------------------------------- set.seed(20260533) n <- 50 binary_data <- data.frame( z = seq(-1.6, 1.6, length.out = n) ) binary_data$treatment_full <- as.numeric( sin(seq_len(n) * 1.7) + 0.35 * binary_data$z > 0 ) binary_data$growth <- 0.45 + 0.55 * binary_data$z + 1.25 * binary_data$treatment_full + rnorm(n, sd = 0.08) binary_data$treatment <- factor(binary_data$treatment_full, levels = c(0, 1)) binary_data$treatment[c(6, 15, 28, 43)] <- NA fit_binary <- drmTMB( bf(growth ~ z + mi(treatment), sigma ~ 1), family = gaussian(), data = binary_data, impute = list( treatment = impute_model(treatment ~ z, family = binomial()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_binary, "mi_treatment") imputed(fit_binary) ## ----------------------------------------------------------------------------- set.seed(20260543) n <- 64 poisson_binary_data <- data.frame( z = seq(-1.5, 1.8, length.out = n) ) poisson_binary_data$treatment_full <- as.numeric( sin(seq_len(n) * 1.3) + 0.3 * poisson_binary_data$z > 0 ) lambda_count <- exp( 0.25 + 0.45 * poisson_binary_data$z + 0.75 * poisson_binary_data$treatment_full ) poisson_binary_data$count <- pmax( 0, round(lambda_count + sqrt(lambda_count) * cos(seq_len(n) / 4)) ) poisson_binary_data$treatment <- factor( poisson_binary_data$treatment_full, levels = c(0, 1) ) poisson_binary_data$treatment[c(8, 19, 31, 46, 57)] <- NA fit_poisson_binary <- drmTMB( bf(count ~ z + mi(treatment)), family = poisson(), data = poisson_binary_data, impute = list( treatment = impute_model(treatment ~ z, family = binomial()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_poisson_binary, "mu") coef(fit_poisson_binary, "mi_treatment") imputed(fit_poisson_binary) ## ----------------------------------------------------------------------------- fit_nbinom2_binary <- drmTMB( bf(count ~ z + mi(treatment), sigma ~ 1), family = nbinom2(), data = poisson_binary_data, impute = list( treatment = impute_model(treatment ~ z, family = binomial()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_nbinom2_binary, "mu") coef(fit_nbinom2_binary, "mi_treatment") ## ----------------------------------------------------------------------------- beta_binary_data <- poisson_binary_data beta_binary_data$cover <- plogis( -0.2 + 0.5 * beta_binary_data$z + 0.7 * beta_binary_data$treatment_full + 0.15 * cos(seq_len(nrow(beta_binary_data))) ) fit_beta_binary <- drmTMB( bf(cover ~ z + mi(treatment), sigma ~ 1), family = beta(), data = beta_binary_data, impute = list( treatment = impute_model(treatment ~ z, family = binomial()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_beta_binary, "mu") coef(fit_beta_binary, "mi_treatment") ## ----------------------------------------------------------------------------- set.seed(20260535) n <- 60 ordered_data <- data.frame( z = seq(-1.5, 1.5, length.out = n) ) ordered_levels <- c("low", "medium", "high") ordered_data$score_full <- cut( ordered_data$z + sin(seq_len(n) * 1.4), breaks = c(-Inf, -0.45, 0.55, Inf), labels = ordered_levels, ordered_result = TRUE ) ordered_data$growth <- 0.25 + 0.5 * ordered_data$z + 0.45 * as.numeric(ordered_data$score_full) + rnorm(n, sd = 0.18) ordered_data$score <- ordered_data$score_full ordered_data$score[c(8, 18, 36, 51)] <- NA fit_ordered <- drmTMB( bf(growth ~ z + mi(score), sigma ~ 1), family = gaussian(), data = ordered_data, impute = list( score = impute_model(score ~ z, family = cumulative_logit()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_ordered, "mi_score") imputed(fit_ordered) ## ----------------------------------------------------------------------------- set.seed(20260536) n <- 66 categorical_data <- data.frame( z = seq(-1.7, 1.7, length.out = n) ) categorical_score <- sin(seq_len(n) / 4) + 0.45 * categorical_data$z categorical_data$habitat_full <- factor( ifelse( categorical_score < -0.35, "forest", ifelse(categorical_score < 0.55, "grass", "wetland") ), levels = c("forest", "grass", "wetland") ) habitat_effect <- c(forest = -0.35, grass = 0.2, wetland = 0.75) categorical_data$growth <- 0.15 + 0.5 * categorical_data$z + unname(habitat_effect[as.character(categorical_data$habitat_full)]) + rnorm(n, sd = 0.12) categorical_data$habitat <- categorical_data$habitat_full categorical_data$habitat[c(7, 16, 31, 48, 60)] <- NA fit_categorical <- drmTMB( bf(growth ~ z + mi(habitat), sigma ~ 1), family = gaussian(), data = categorical_data, impute = list( habitat = impute_model(habitat ~ z, family = categorical()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_categorical, "mi_habitat") imputed(fit_categorical) ## ----------------------------------------------------------------------------- set.seed(20260537) n <- 72 proportion_data <- data.frame( z = seq(-1.8, 1.8, length.out = n) ) proportion_data$cover_full <- plogis( -0.25 + 0.9 * proportion_data$z + 0.18 * sin(seq_len(n) / 5) ) proportion_data$growth <- 0.35 + 1.25 * proportion_data$cover_full - 0.30 * proportion_data$z + rnorm(n, sd = 0.10) proportion_data$cover <- proportion_data$cover_full proportion_data$cover[c(8, 19, 34, 51, 67)] <- NA_real_ fit_proportion <- drmTMB( bf(growth ~ z + mi(cover), sigma ~ 1), family = gaussian(), data = proportion_data, impute = list( cover = impute_model(cover ~ z, family = beta()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_proportion, "mi_cover") coef(fit_proportion, "sigma_mi_cover") imputed(fit_proportion) ## ----------------------------------------------------------------------------- set.seed(20260541) n <- 78 boundary_prop_data <- data.frame( z = seq(-1.8, 1.8, length.out = n) ) boundary_prop_data$cover_full <- plogis( -0.15 + 0.8 * boundary_prop_data$z + 0.12 * sin(seq_len(n) / 4) ) boundary_prop_data$cover_full[seq(6, n, by = 18)] <- 0 boundary_prop_data$cover_full[seq(13, n, by = 19)] <- 1 boundary_prop_data$growth <- 0.30 + 1.10 * boundary_prop_data$cover_full - 0.25 * boundary_prop_data$z + rnorm(n, sd = 0.10) boundary_prop_data$cover <- boundary_prop_data$cover_full boundary_prop_data$cover[c(8, 21, 39, 58, 73)] <- NA_real_ fit_boundary_proportion <- drmTMB( bf(growth ~ z + mi(cover), sigma ~ 1), family = gaussian(), data = boundary_prop_data, impute = list( cover = impute_model(cover ~ z, family = zero_one_beta()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_boundary_proportion, "mi_cover") coef(fit_boundary_proportion, "sigma_mi_cover") coef(fit_boundary_proportion, "zoi_mi_cover") coef(fit_boundary_proportion, "coi_mi_cover") imputed(fit_boundary_proportion) ## ----------------------------------------------------------------------------- set.seed(20260542) n <- 70 denom_prop_data <- data.frame( z = seq(-1.7, 1.7, length.out = n), trials = rep(8:16, length.out = n) ) p_cover <- plogis(-0.20 + 0.80 * denom_prop_data$z) denom_prop_data$success_full <- qbinom( ppoints(n), size = denom_prop_data$trials, prob = p_cover ) denom_prop_data$cover_full <- denom_prop_data$success_full / denom_prop_data$trials denom_prop_data$growth <- 0.25 + 1.10 * denom_prop_data$cover_full - 0.22 * denom_prop_data$z + rnorm(n, sd = 0.10) denom_prop_data$success <- denom_prop_data$success_full denom_prop_data$cover <- denom_prop_data$cover_full denom_prop_data$success[c(8, 21, 39, 58)] <- NA_real_ denom_prop_data$cover[c(8, 21, 39, 58)] <- NA_real_ fit_denominator_proportion <- drmTMB( bf(growth ~ z + mi(cover), sigma ~ 1), family = gaussian(), data = denom_prop_data, impute = list( cover = impute_model( success ~ z, family = beta_binomial(), trials = trials ) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_denominator_proportion, "mi_cover") coef(fit_denominator_proportion, "sigma_mi_cover") imputed(fit_denominator_proportion) ## ----------------------------------------------------------------------------- set.seed(20260538) n <- 76 count_data <- data.frame( z = seq(-1.6, 1.7, length.out = n) ) lambda_count <- exp(0.35 + 0.55 * count_data$z) count_data$abundance_full <- pmax( 0, round(lambda_count + sqrt(lambda_count) * sin(seq_len(n) / 3)) ) count_data$growth <- 0.20 + 0.42 * count_data$abundance_full - 0.25 * count_data$z + rnorm(n, sd = 0.10) count_data$abundance <- count_data$abundance_full count_data$abundance[c(7, 18, 33, 49, 68)] <- NA_real_ fit_count <- drmTMB( bf(growth ~ z + mi(abundance), sigma ~ 1), family = gaussian(), data = count_data, impute = list( abundance = impute_model(abundance ~ z, family = poisson()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_count, "mi_abundance") imputed(fit_count) ## ----------------------------------------------------------------------------- fit_count_nb <- drmTMB( bf(growth ~ z + mi(abundance), sigma ~ 1), family = gaussian(), data = count_data, impute = list( abundance = impute_model(abundance ~ z, family = nbinom2()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_count_nb, "mi_abundance") coef(fit_count_nb, "sigma_mi_abundance") imputed(fit_count_nb) ## ----------------------------------------------------------------------------- positive_count_data <- count_data positive_count_data$abundance_full <- count_data$abundance_full + 1 positive_count_data$abundance <- positive_count_data$abundance_full positive_count_data$abundance[c(7, 18, 33, 49, 68)] <- NA_real_ positive_count_data$growth <- 0.20 + 0.42 * positive_count_data$abundance_full - 0.25 * positive_count_data$z + rnorm(nrow(positive_count_data), sd = 0.10) fit_count_trunc_nb <- drmTMB( bf(growth ~ z + mi(abundance), sigma ~ 1), family = gaussian(), data = positive_count_data, impute = list( abundance = impute_model(abundance ~ z, family = truncated_nbinom2()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_count_trunc_nb, "mi_abundance") coef(fit_count_trunc_nb, "sigma_mi_abundance") imputed(fit_count_trunc_nb) ## ----------------------------------------------------------------------------- set.seed(20260539) n <- 76 positive_data <- data.frame( z = seq(-1.6, 1.6, length.out = n) ) positive_data$biomass_full <- exp( 0.15 + 0.55 * positive_data$z + 0.10 * sin(seq_len(n) / 4) ) positive_data$growth <- 0.40 + 0.85 * positive_data$biomass_full - 0.25 * positive_data$z + rnorm(n, sd = 0.10) positive_data$biomass <- positive_data$biomass_full positive_data$biomass[c(7, 18, 33, 49, 65)] <- NA_real_ fit_positive <- drmTMB( bf(growth ~ z + mi(biomass), sigma ~ 1), family = gaussian(), data = positive_data, impute = list( biomass = impute_model(biomass ~ z, family = lognormal()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_positive, "mi_biomass") coef(fit_positive, "sigma_mi_biomass") imputed(fit_positive) ## ----------------------------------------------------------------------------- fit_positive_gamma <- drmTMB( bf(growth ~ z + mi(biomass), sigma ~ 1), family = gaussian(), data = positive_data, impute = list( biomass = impute_model(biomass ~ z, family = Gamma(link = "log")) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_positive_gamma, "mi_biomass") coef(fit_positive_gamma, "sigma_mi_biomass") imputed(fit_positive_gamma) ## ----------------------------------------------------------------------------- set.seed(20260540) n <- 82 semi_data <- data.frame( z = seq(-1.7, 1.8, length.out = n) ) semi_data$biomass_full <- ifelse( seq_len(n) %% 6 %in% c(0, 1), 0, exp(0.10 + 0.45 * semi_data$z) * (1 + 0.16 * sin(seq_len(n) / 4)) ) semi_data$growth <- 0.25 + 0.62 * semi_data$biomass_full - 0.18 * semi_data$z + rnorm(n, sd = 0.10) semi_data$biomass <- semi_data$biomass_full semi_data$biomass[c(7, 18, 31, 44, 58, 76)] <- NA_real_ fit_tweedie_predictor <- drmTMB( bf(growth ~ z + mi(biomass), sigma ~ 1), family = gaussian(), data = semi_data, impute = list( biomass = impute_model(biomass ~ z, family = tweedie()) ), missing = miss_control(predictor = "model"), control = drm_control(se = FALSE) ) coef(fit_tweedie_predictor, "mi_biomass") coef(fit_tweedie_predictor, "sigma_mi_biomass") imputed(fit_tweedie_predictor)