# tidyvpc with nlmixr2

# Introduction

`tidyvpc` and `nlmixr2` can work together seamlessly. The information below will provide step-by-step methods for using `tidyvpc` to create visual predictive checks (VPCs) for `nlmixr2` models.

# Setup

## R setup

First, you must load both libraries.

    suppressPackageStartupMessages(library(tidyvpc, quietly = TRUE))
    library(nlmixr2, quietly = TRUE)
    library(magrittr)

## Model fitting

Second, we will fit a simple model to use as an example. For more information on using `nlmixr2` for model fitting, see the nlmixr2 website.

    one_compartment <- function() {
      ini({
        tka <- log(1.57); label("Ka")
        tcl <- log(2.72); label("Cl")
        tv <- log(31.5); label("V")
        eta_ka ~ 0.6
        eta_cl ~ 0.3
        eta_v ~ 0.1
        add_sd <- 0.7
      })
      # and a model block with the error specification and model specification
      model({
        ka <- exp(tka + eta_ka)
        cl <- exp(tcl + eta_cl)
        v <- exp(tv + eta_v)
        d/dt(depot) <- -ka * depot
        d/dt(center) <- ka * depot - cl / v * center
        cp <- center / v
        cp ~ add(add_sd)
      })
    }

    data_model <- theo_sd
    data_model$WTSTRATA <- ifelse(data_model$WT < median(data_model$WT), "Low weight", "High weight")

    fit <- nlmixr2(one_compartment, data_model, est="saem", saemControl(print=0))
    #> → loading into symengine environment...
    #> → pruning branches (`if`/`else`) of saem model...
    #> ✔ done
    #> → finding duplicate expressions in saem model...
    #> [====|====|====|====|====|====|====|====|====|====] 0:00:00
    #> → optimizing duplicate expressions in saem model...
    #> [====|====|====|====|====|====|====|====|====|====] 0:00:00
    #> ✔ done
    #> using C compiler: 'gcc.exe (x86_64-posix-seh, Built by strawberryperl.com project) 7.1.0'
    #> rxode2 2.0.14 using 4 threads (see ?getRxThreads)
    #>   no cache: create with `rxCreateCache()`
    #> Calculating covariance matrix
    #> → loading into symengine environment...
    #> → pruning branches (`if`/`else`) of saem model...
    #> ✔ done
    #> → finding duplicate expressions in saem predOnly model 0...
    #> → finding duplicate expressions in saem predOnly model 1...
    #> → optimizing duplicate expressions in saem predOnly model 1...
    #> → finding duplicate expressions in saem predOnly model 2...
    #> ✔ done
    #> using C compiler: 'gcc.exe (x86_64-posix-seh, Built by strawberryperl.com project) 7.1.0'
    #> → Calculating residuals/tables
    #> ✔ done
    #> → compress origData in nlmixr2 object, save 7288
    #> → compress phiM in nlmixr2 object, save 64048
    #> → compress parHist in nlmixr2 object, save 9760
    #> → compress saem0 in nlmixr2 object, save 28912

## VPC preparation

`nlmixr2` provides a method for simulating multiple studies to prepare for a VPC. Use the `keep` argument to add columns from the source data to the simulated output (e.g. to use it for stratification of the VPC).

    fit_vpcsim <- vpcSim(object = fit, keep = "WTSTRATA")
    #> using C compiler: 'gcc.exe (x86_64-posix-seh, Built by strawberryperl.com project) 7.1.0'

Following the `vpcSim()` call, the remainder of the steps use `tidyvpc` to generate the vpc.

## Generate a standard VPC

The `x` and `y` arguments to `observed()` are the columns from your original dataset. The `x` and `y` arguments to `simulated()` will almost always be `time` and `sim` based on the outut from `vpcSim()`.

    obs_data <- data_model[data_model$EVID == 0,]

    vpc <-
      observed(obs_data, x=TIME, y=DV) %>%
      simulated(fit_vpcsim, x=time, y=sim) %>%
      stratify(~ WTSTRATA) %>%
      binning(bin = "jenks") %>%
      vpcstats()

    plot(vpc)

## Prediction-corrected VPC

For a pred-corrected VPC, you need the population predicted value in the observed data. That is straight-forward to add with `nlmixr2` by adding the predictions to all rows with `EVID == 0`.

    # Add PRED to observed data
    data_pred <- data_model[data_model$EVID == 0, ]
    data_pred$PRED <- fit$PRED

    vpc_predcorr <-
      observed(data_pred, x=TIME, y=DV) %>%
      simulated(fit_vpcsim, x=time, y=sim) %>%
      stratify(~ WTSTRATA) %>%
      binning(bin = "jenks") %>%
      predcorrect(pred=PRED) %>%
      vpcstats()

    plot(vpc_predcorr)