% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/sg-covsens-sim.R
\name{sg_covsens_sim}
\alias{sg_covsens_sim}
\title{Covariate sensitivity analysis via simulation}
\usage{
sg_covsens_sim(
  fpath_i = NULL,
  ds_parest = NULL,
  ds_covs = NULL,
  model,
  stimes,
  et,
  est_covmat,
  npop = 5,
  cont_cov_l,
  cat_cov_l,
  quantiles = c(0.1, 0.9),
  outputs = "Cc",
  aggr = c("min", "max", "mean")
)
}
\arguments{
\item{fpath_i}{String or sg-fit object. If the string is given, the path to
\code{.Rdata} or \code{.json} file with sg-fit object is expected.}

\item{ds_parest}{Data.frame. Parameter estimates table with columns
\code{parameter} and \code{value}.
Required when \code{fpath_i} is \code{NULL}; must be provided together
with \code{ds_covs}.  Default is \code{NULL}.}

\item{ds_covs}{data.frame. Subject-level covariate dataset (one row per
subject) containing both continuous and categorical covariate columns.
Required when \code{fpath_i} is \code{NULL}; must be provided together
with \code{ds_parest}.  Default is \code{NULL}.}

\item{model}{A model object passed to \code{sg_sim()}.}

\item{stimes}{numeric vector. Sampling time points for steady-state
simulation (e.g. generated by a cycling function over dosing intervals).}

\item{et}{data.frame. Event (dosing) table.  Must contain at least
columns \code{id}, \code{time}, \code{amt}, \code{evid} and
\code{Regimen}.  Additional columns such as \code{ii}, \code{addl},
\code{dur} and \code{Dose} are used when present.}

\item{est_covmat}{Data.frame. Parameter estimation covariance matrix.  The
first column (\code{X1}) must list parameter names; remaining columns
(named identically) form the symmetric variance–covariance matrix.}

\item{npop}{integer. Number of population-level simulation replicates drawn
from the parameter uncertainty distribution.  Default is \code{5}.}

\item{cont_cov_l}{A named list. Each element defines one continuous covariate
and must itself be a list with components:
\describe{
\item{\code{NAME}}{Character. Column name of the (transformed)
covariate in the dataset (e.g. \code{"LG_AGE"}).}
\item{\code{UTNAME}}{Character or \code{NULL}. Column name of the
untransformed (back-transformed) covariate
(e.g. \code{"AGE"}).  If \code{NULL} or \code{NA}, defaults to
\code{NAME}.}
\item{\code{REF}}{Character or numeric. Reference value for the
covariate.  Use \code{"median"} to derive from data, or a numeric
value.}
\item{\code{NICENAME}}{Character or \code{NULL}. Display label for
plots and tables (e.g. \code{"Age, years"}).}
\item{\code{par_vec}}{Character vector. Model parameter(s) affected by
this covariate (e.g. \code{c("CL")}).}
}}

\item{cat_cov_l}{A named list. Each element defines one categorical covariate
and must itself be a list with components:
\describe{
\item{\code{NAME}}{Character. Column name of the covariate
(e.g. \code{"SEX"}).}
\item{\code{NICENAME}}{Character or \code{NULL}. Display label.}
\item{\code{REF}}{Character or \code{NULL}. Reference category value.
If \code{NULL}, the first factor level (alphabetically) is used.}
\item{\code{par_vec}}{Character vector. Model parameter(s) affected by
this covariate (e.g. \code{c("ka")}).}
}}

\item{quantiles}{A numeric vector of length 2. Lower and upper quantiles of
the continuous covariate distribution to test.
Default is \code{c(0.1, 0.9)}.}

\item{outputs}{character vector. Name(s) of the model output variable(s)
to evaluate (e.g. \code{"Cc"} or \code{c("Cc", "Effect")}).
Default is \code{"Cc"}.}

\item{aggr}{character vector. Exposure aggregation metric(s) applied over
the simulation time grid.
Allowed values: \code{"min"} (Cmin), \code{"max"} (Cmax),
\code{"mean"} (Cavg).  Default is \code{c("min", "max", "mean")}.}
}
\value{
A named list of three elements:
\describe{
\item{\code{$PARSENS}}{data.frame.
Full sensitivity results for model parameters: percent change
statistics (mean, median, percentiles) for each covariate–parameter
combination, with columns \code{NICEN}, \code{VAR}, \code{KEY},
\code{LAB}, \code{Type} and summary statistics
(\code{mean} through \code{P975}).}
\item{\code{$SUMPARSENS}}{data.frame.
Compact summary table with columns \code{Parameter},
\code{Covariate}, \code{Cov. percentile}, \code{Cov. value},
\code{Mean} and \code{90\%CI}.}
\item{\code{$EXPSENS}}{data.frame.
Sensitivity of exposure metrics (Cmin, Cmax, Cavg) to covariates,
structured identically to \code{$PARSENS}.}
}
}
\description{
Evaluate the impact of continuous and categorical covariates on model
parameters and exposure metrics.  For each covariate the function perturbs
its value to selected quantiles (continuous) or observed categories
(categorical) while holding the remaining covariates at their reference
values, simulates from the pharmacometric model under parameter uncertainty,
and summarises the resulting percent change relative to the reference.
}
\details{
Two data-source modes are supported (mutually exclusive):
\itemize{
\item \strong{File mode} — supply \code{fpath_i} (path to a SimuRg JSON /
RData object that contains SUMTAB, CATAB and COTAB).
\item \strong{Table mode} — supply both \code{ds_parest} (parameter
estimates) and \code{ds_covs} (covariate dataset).
}

The analysis proceeds in two stages for each covariate type (continuous and
categorical):
\enumerate{
\item \strong{Parameter sensitivity} — the covariate is set to its
quantile or category value and the model is evaluated at time zero (no
ODE integration) to quantify the direct effect on each parameter.
\item \strong{Exposure sensitivity} — the full time-course is simulated
over \code{stimes} and exposure metrics (\code{aggr}) are computed.
}

Uncertainty is propagated by sampling \code{npop} parameter vectors from a
multivariate normal distribution parameterised by the population estimates
and the estimation covariance matrix (\code{est_covmat}).
}
\examples{
\donttest{
library(dplyr)
library(rxode2)

# --- Covariate definitions ---
cont_cov_l <- list(
  LG_AGE = list(NAME = "LG_AGE", UTNAME = "AGE",
                REF = "median", NICENAME = "Age, years",
                par_vec = c("CL")),
  LG_WEIGHT = list(NAME = "LG_WEIGHT", UTNAME = "WEIGHT",
                   REF = "median", NICENAME = "Weight, kg",
                   par_vec = c("Vd"))
)

cat_cov_l <- list(
  SEX = list(NAME = "SEX", NICENAME = "Sex",
             REF = "0", par_vec = c("ka")),
  CYP2C9 = list(NAME = "CYP2C9", NICENAME = "CYP2C9 genotype",
                REF = NULL, par_vec = c("CL"))
)

# --- Dosing ---
ev_t_input <- tribble(
  ~id, ~time, ~ii, ~amt, ~addl, ~dur, ~evid, ~Regimen,        ~Dose,
  1,   0,     336, 10,   21,    0.5,  1,     "0.3 mg/kg Q2W", 0.3
)
# --- Model ---
model <- RxODE({
  # Doses in mg
  # Time in hours

  ### Parameter values
  # Typical values
  ka_pop = 0.073;
  Vd_pop = 14.8;
  CL_pop = 0.347;

  # Random effects
  omega_ka = 0;
  omega_Vd = 0;
  omega_CL = 0;

  # Covariate effect
  # Continuous
  beta_CL_LG_AGE = 0.49990114;
  beta_Vd_LG_WEIGHT = 0.60529433;

  # Categorical
  beta_CL_CYP2C9_1_2 = -0.339;
  beta_CL_CYP2C9_1_3 = -0.574;
  beta_CL_CYP2C9_2_2 = -1.079;
  beta_CL_CYP2C9_2_3 = -0.745;
  beta_CL_CYP2C9_3_3 = -2.13;

  beta_ka_SEX_1 = -0.12198035;

  # Residual error
  Cc_b = 0;

  # Transformations
  ka_tv = exp(ka_pop);
  Vd_tv = exp(Vd_pop);
  CL_tv = exp(CL_pop);

  CL_multiplier = 1.0;  # Default/reference
  ka_multiplier = 1.0;

  if (SEX == "1") {ka_multiplier = exp(beta_ka_SEX_1)}

  if (CYP2C9 == "1") {
    CL_multiplier = exp(beta_CL_CYP2C9_1_2);
  } else if (CYP2C9 == "2") {
    CL_multiplier = exp(beta_CL_CYP2C9_1_3);
  } else if (CYP2C9 == "3") {
    CL_multiplier = exp(beta_CL_CYP2C9_2_2);
  } else if (CYP2C9 == "4") {
    CL_multiplier = exp(beta_CL_CYP2C9_2_3);
  } else if (CYP2C9 == "5") {
    CL_multiplier = exp(beta_CL_CYP2C9_3_3);
  }

  ka = ka_tv*ka_multiplier*exp(omega_ka);
  Vd = Vd_tv*exp(beta_Vd_LG_WEIGHT * LG_WEIGHT + omega_Vd); #Vd_tv*exp(omega_Vd);
  CL = CL_tv*CL_multiplier*exp(beta_CL_LG_AGE * LG_AGE + omega_CL);


  ### Explicit functions
  Cc = Ac/Vd;

  ### Initial conditions
  Ad(0) = 0;
  Ac(0) = 0;

  ### Differential equations
  d/dt(Ad) = - ka*Ad;
  d/dt(Ac) = ka*Ad - CL*Cc;

  Cc_ResErr = Cc*(1 + Cc_b);
})

# --- Estimation covariance (mock) ---
pnames     <- parest$parameter
npar       <- length(pnames)
set.seed(1)
m_cov      <- matrix(0.02, npar, npar)
diag(m_cov) <- 0.05 + runif(npar, 0, 0.05)
m_cov      <- (m_cov + t(m_cov)) / 2
est_covmat <- as_tibble(cbind(X1 = pnames, as.data.frame(m_cov)))
names(est_covmat)[-1] <- pnames

# --- Simulation times (steady-state cycle 10) ---
ss_cycle <- 10
stimes_ss <- c(
  ss_cycle * 4 * 7 * 24 + c(seq(0, 23.5, 0.5), seq(24, 335, 1)),
  ss_cycle * 4 * 7 * 24 + 2 * 7 * 24 + c(seq(0, 23.5, 0.5), seq(24, 335, 1))
)

# --- Run ---
result <- sg_covsens_sim(
  fpath_i=NULL, ds_parest = parest, ds_covs = ds_covval,
  model = model, stimes = stimes_ss, et = ev_t_input,
  est_covmat = est_covmat, npop = 10,
  cont_cov_l = cont_cov_l, cat_cov_l = cat_cov_l,
  quantiles = c(0.2, 0.8), aggr = c("max"),
  outputs = "Cc"
)
print(result[["PARSENS"]])
print(result[["SUMPARSENS"]])
print(result[["EXPSENS"]])

}

}
\seealso{
\code{\link{sg_sim}}, \code{\link{read_smrg_obj}}
}
