%\VignetteIndexEntry{Simulation of multistate models with multiple timescales: simLexis}

\documentclass[a4paper,dvipsnames,twoside,12pt]{report}

\newcommand{\Title}{Simulation of\\ multistate models with\\ multiple
  timescales:\\ \texttt{simLexis} in the \texttt{Epi} package}
\newcommand{\Tit}{Multistate models with multiple timescales}
\newcommand{\Version}{Version 2.5}
\newcommand{\Dates}{\today}
\newcommand{\Where}{SDCC}
\newcommand{\Homepage}{\url{http://BendixCarstensen.com/Epi/simLexis.pdf}}
\newcommand{\Faculty}{\begin{tabular}{rl}
Bendix Carstensen
  & Steno Diabetes Center Copenhagen, Gentofte, Denmark\\
  & {\small \& Department of Biostatistics,
               University of Copenhagen} \\
  & \texttt{b@bxc.dk}\\
  & \url{http://BendixCarstensen.com} \\[1em]
                      \end{tabular}}

\input{topreport}
\renewcommand{\rwpre}{./simLexis}

\chapter{Using \texttt{simLexis}}

\section{Introduction}

This vignette explains the machinery behind simulation of life
histories through multistate models implemented in
\texttt{simLexis}. In \texttt{simLexis} transition rates are allowed
to depend on multiple time scales, including timescales defined as
time since entry to a particular state (duration). This therefore also
covers the case where time \emph{at} entry into a state is an
explanatory variable for the rates, since time at entry is merely time
minus duration. Thus, the set-up here goes beyond Markov- and
semi-Markov-models, and brings simulation based estimation of
state-occupancy probabilities into the realm of realistic multistate
models.

The basic idea is to simulate a new \texttt{Lexis} object
\cite{Plummer.2011,Carstensen.2011a} as defined in the \texttt{Epi}
package for \R, based on 1) a multistate model defined by its states
and the transition rates between them and 2) an initial population of
individuals.

Thus the output will be a \texttt{Lexis} object describing the
transitions of a predefined set of persons through a multistate
model. Therefore, if persons are defined to be identical at start,
then calculation of the probability of being in a particular state at
a given time boils down to a simple enumeration of the fraction of the
persons in the particular state at the given time. Bar of course the
(binomial) simulation error, but this can be brought down by
simulation a sufficiently large number of persons.

An observed \texttt{Lexis} object with follow-up of persons through a
number of states will normally be the basis for estimation of
transition rates between states, and thus will contain all information
about covariates determining the occurrence rates, in particular the
\emph{timescales} \cite{Iacobelli.2013}. Hence, the natural input to
simulation from an estimated multistate model will typically be an
object of the same structure as the originally observed. Since
transitions and times are what is simulated, any values of
\texttt{lex.Xst} and \texttt{lex.dur} in the input object will of
course be ignored.

This first chapter of this vignette shows by an example how to use the
function \texttt{simLexis} and display the results. The second
chapter discusses in more detail how the simulation machinery is
implemented and is not needed for the practical use of \texttt{simLexis}.

\section{\texttt{simLexis} in practice}

This section is largely a commented walk-trough of the example from
the help-page of \texttt{simLexis}, with a larger number of simulated
persons in order to minimize the pure simulation variation.

When we want to simulate transition times through a multistate model
where transition rates may depend on time since entry to the current
or a previous state, it is essential that we have a machinery to keep
track of the transition time on \emph{all} time scales, as well as a
mechanism that can initiate a new time scale to 0 when a transition
occurs to a state where we shall use time since entry as determinant
of exit rates from that state. This is provided by \texttt{simLexis}.

\subsection{Input for the simulation}

Input for simulation of a single trajectory through a multistate model
requires a representation of the \emph{current status} of a person;
the starting conditions. The object that we supply to the simulation
function must contain information about all covariates and all
timescales upon which transitions depend, and in particular which
one(s) of the timescales that are defined as time since entry into a
particular state. Hence, starting conditions should be represented as
a \texttt{Lexis} object (where \texttt{lex.dur} and \texttt{lex.Xst}
are ignored, since there is no follow-up yet), where the time scale
information is in the attributes \texttt{time.scales} and
\texttt{time.since} respectively. 

Note that \texttt{time.scales} attribute is a vector of names of
variables in the \texttt{Lexis} object, so all of these variables
should be present even if they are not used in the models for the
transitions, and they should be set to 0; if they are not in the
initial dataset, \texttt{simLexis} will crash, if they are
\texttt{NA}, the \texttt{simLexis} will produce an object with 0 rows.

Thus there are two main arguments to a function to simulate from a
multistate model:
\begin{enumerate}
\item A \texttt{Lexis} object representing the initial states and
  covariates of the population to be simulated. This has to have the
  same structure as the original \texttt{Lexis} object representing
  the multistate model from which transition rates in the model were
  estimated. As noted above, the values for \texttt{lex.Xst} and
  \texttt{lex.dur} are not required (since these are the quantities
  that will be simulated).
\item A transition object, representing the transition intensities
  between states, which should be a list of lists of intensity
  representations. As an intensity representation we mean a function
  that for a given \texttt{Lexis} object can be used to produce
  estimates of the transition intensities at a set of supplied time
  points.

  The names of the elements of the transition object (which are lists)
  will be names of the \emph{transient} states, that is the states
  \emph{from} which a transition can occur. The names of the elements
  of each of these lists are the names of states \emph{to} which
  transitions can occur (which may be either transient or absorbing
  states).

  Hence, if the transition object is called \texttt{Tr} then
  \verb+TR$A$B+ (or \verb+Tr[["A"]][["B"]]+) will represent the
  transition intensity from state \texttt{A} to the state \texttt{B}.

  The entries in the transition object can be either \texttt{glm}
  objects (either with \texttt{poisson} or \texttt{poisreg} family),
  representing Poisson models for the transitions, \texttt{coxph}
  objects representing an intensity model along one time scale, or
  simply a function that takes a \texttt{Lexis} object as input and
  returns an estimated intensity for each row.

\end{enumerate}

In addition to these two input items, there will be a couple of tuning
parameters.

The output of the function will simply be a \texttt{Lexis} object with
simulated transitions between states. This will be the basis for
deriving sensible statistics from the \texttt{Lexis} object --- see
next section.

\section{Setting up a \texttt{Lexis} object}

As an example we will use the \texttt{DMlate} dataset from the
\texttt{Epi} package; it is a dataset simulated to resemble a random
sample of 10,000 patients from the Danish National Diabetes Register.

We start by loading the \texttt{Epi} package:
\begin{Schunk}
\begin{Sinput}
> options( width=90 )
> library( Epi )
> print( sessionInfo(), l=F )
\end{Sinput}
\begin{Soutput}
R version 3.6.3 (2020-02-29)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.6 LTS

Matrix products: default
BLAS:   /usr/lib/openblas-base/libopenblas.so.0
LAPACK: /usr/lib/lapack/liblapack.so.3.0

attached base packages:
[1] utils     datasets  graphics  grDevices stats     methods   base     

other attached packages:
[1] Epi_2.43

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.3        magrittr_1.5      splines_3.6.3     MASS_7.3-53      
 [5] tidyselect_0.2.5  lattice_0.20-41   R6_2.4.1          rlang_0.4.4      
 [9] plyr_1.8.5        dplyr_0.8.4       cmprsk_2.2-7      tools_3.6.3      
[13] parallel_3.6.3    grid_3.6.3        data.table_1.12.0 nlme_3.1-149     
[17] mgcv_1.8-33       survival_3.2-7    assertthat_0.2.1  tibble_2.1.3     
[21] etm_1.0.4         numDeriv_2016.8-1 crayon_1.3.4      Matrix_1.2-18    
[25] purrr_0.3.0       glue_1.3.1        compiler_3.6.3    pillar_1.4.3     
[29] zoo_1.8-4         pkgconfig_2.0.3  
\end{Soutput}
\end{Schunk}
First we load the diabetes data and set up a simple illness-death
model:
\begin{Schunk}
\begin{Sinput}
> data(DMlate)
> dml <- Lexis( entry = list(Per=dodm, Age=dodm-dobth, DMdur=0 ),
+                exit = list(Per=dox),
+         exit.status = factor(!is.na(dodth),labels=c("DM","Dead")),
+                data = DMlate )
\end{Sinput}
\begin{Soutput}
NOTE: entry.status has been set to "DM" for all.
NOTE: Dropping  4  rows with duration of follow up < tol
\end{Soutput}
\end{Schunk}
This is just data for a simple survival model with states \texttt{DM} and
\texttt{Dead}. Now we cut the follow-up at insulin start, which for the
majority of patients (T2D) is a clinical indicator of deterioration of
disease regulation. We therefore also introduce a new timescale, and
split the non-precursor states, so that we can address the question of
ever having been on insulin:
\begin{Schunk}
\begin{Sinput}
> dmi <- cutLexis( dml, cut = dml$doins,
+                       pre = "DM",
+                 new.state = "Ins",
+                 new.scale = "t.Ins",
+              split.states = TRUE )
> summary( dmi, timeScales=T )
\end{Sinput}
\begin{Soutput}
Transitions:
     To
From    DM  Ins Dead Dead(Ins)  Records:  Events: Risk time:  Persons:
  DM  6157 1694 2048         0      9899     3742   45885.49      9899
  Ins    0 1340    0       451      1791      451    8387.77      1791
  Sum 6157 3034 2048       451     11690     4193   54273.27      9996

Timescales:
  Per   Age DMdur t.Ins 
   ""    ""    "" "Ins" 
\end{Soutput}
\end{Schunk}
Note that we show the time scales in the \texttt{Lexis} object, and
that it is indicated that the time scale \texttt{t.Ins} is defined as
time since entry into stat state \texttt{Ins.}

We can show how many person-years we have and show the number of
transitions and transition rates (per 1000), using the
\texttt{boxes.Lexis} function to display the states and the number of
transitions between them:
\begin{Schunk}
\begin{Sinput}
> boxes( dmi, boxpos = list(x=c(20,20,80,80),
+                         y=c(80,20,80,20)),
+             scale.R = 1000, show.BE = TRUE )
\end{Sinput}
\end{Schunk}
\insfig{boxes}{0.8}{Data overview for the \textrm{\tt dmi}
  dataset. Numbers in the boxes are person-years and the number of
  persons who begin, resp. end their follow-up in each state, and
  numbers on the arrows are no. of transitions and rates (transition
  intensities) per 1000 PY.}

\section{Analysis of rates}

In the \texttt{Lexis} object (which is just a data frame) each person
is represented by one record for each transient state occupied,
thus in this case either 1 or 2 records; those who have a recorded
time both without and with insulin have two records.

In order to be able to fit Poisson models with occurrence rates varying
by the different time-scales, we split the follow-up in 3-month intervals
for modeling:
\begin{Schunk}
\begin{Sinput}
> Si <- splitLexis( dmi, seq(0,20,1/4), "DMdur" )
> summary( Si )
\end{Sinput}
\begin{Soutput}
Transitions:
     To
From      DM   Ins Dead Dead(Ins)  Records:  Events: Risk time:  Persons:
  DM  184986  1694 2048         0    188728     3742   45885.49      9899
  Ins      0 34707    0       451     35158      451    8387.77      1791
  Sum 184986 36401 2048       451    223886     4193   54273.27      9996
\end{Soutput}
\begin{Sinput}
> print( subset( Si, lex.id==97 )[,1:10], digits=6 )
\end{Sinput}
\begin{Soutput}
     lex.id     Per     Age   DMdur     t.Ins   lex.dur lex.Cst   lex.Xst sex   dobth
2142     97 1997.55 58.9268 0.00000        NA 0.2500000      DM        DM   F 1938.62
2143     97 1997.80 59.1768 0.25000        NA 0.2500000      DM        DM   F 1938.62
2144     97 1998.05 59.4268 0.50000        NA 0.2500000      DM        DM   F 1938.62
2145     97 1998.30 59.6768 0.75000        NA 0.2500000      DM        DM   F 1938.62
2146     97 1998.55 59.9268 1.00000        NA 0.2500000      DM        DM   F 1938.62
2147     97 1998.80 60.1768 1.25000        NA 0.2500000      DM        DM   F 1938.62
2148     97 1999.05 60.4268 1.50000        NA 0.2500000      DM        DM   F 1938.62
2149     97 1999.30 60.6768 1.75000        NA 0.2500000      DM        DM   F 1938.62
2150     97 1999.55 60.9268 2.00000        NA 0.1793292      DM       Ins   F 1938.62
2151     97 1999.72 61.1061 2.17933 0.0000000 0.0706708     Ins       Ins   F 1938.62
2152     97 1999.80 61.1768 2.25000 0.0706708 0.2500000     Ins       Ins   F 1938.62
2153     97 2000.05 61.4268 2.50000 0.3206708 0.2500000     Ins       Ins   F 1938.62
2154     97 2000.30 61.6768 2.75000 0.5706708 0.2500000     Ins       Ins   F 1938.62
2155     97 2000.55 61.9268 3.00000 0.8206708 0.0116359     Ins Dead(Ins)   F 1938.62
\end{Soutput}
\end{Schunk}
Note that when we split the follow-up, each person's follow up now
consists of many records, each with the \emph{current} values of the
timescales at the start of the interval represented by the record. In
the modeling we shall assume that the rates are constant within each
6-month interval, but the \emph{size} of these rates we model as
smooth functions of the time scales (that is the values at the
beginning of each interval).

The approach often used in epidemiology where one parameter is
attached to each interval of time (or age) is not feasible when more
than one time scale is used, because intervals are not classified the
same way on all timescales.

We shall use natural splines (restricted cubic splines) for the
analysis of rates, and hence we must allocate knots for the
splines. This is done for each of the time-scales, and separately for
the transition out of states \texttt{DM} and \texttt{Ins}. For age, we
place the knots so that the number of events is the same between each
pair of knots, but only half of this beyond each of the boundary
knots, whereas for the timescales \texttt{DMdur} and \texttt{tIns}
where we have observation from a well-defined 0, we put knots at 0 and
place the remaining knots so that the number of events is the same
between each pair of knots as well as outside the boundary knots.
\begin{Schunk}
\begin{Sinput}
> nk <- 5
> ( ai.kn <- with( subset(Si,lex.Xst=="Ins" & lex.Cst!=lex.Xst ),
+                  quantile( Age+lex.dur  , probs=(1:nk-0.5)/nk ) ) )
\end{Sinput}
\begin{Soutput}
     10%      30%      50%      70%      90% 
23.23751 48.82218 58.63244 67.79028 78.88542 
\end{Soutput}
\begin{Sinput}
> ( ad.kn <- with( subset(Si,lex.Xst=="Dead"),
+                  quantile( Age+lex.dur  , probs=(1:nk-0.5)/nk ) ) )
\end{Sinput}
\begin{Soutput}
     10%      30%      50%      70%      90% 
61.91951 72.52731 78.43121 83.32348 90.15195 
\end{Soutput}
\begin{Sinput}
> ( di.kn <- with( subset(Si,lex.Xst=="Ins" & lex.Cst!=lex.Xst ),
+                  c(0,quantile( DMdur+lex.dur, probs=(1:(nk-1))/nk ) )) )
\end{Sinput}
\begin{Soutput}
                  20%        40%        60%        80% 
0.00000000 0.06570842 0.45448323 3.28761123 6.63764545 
\end{Soutput}
\begin{Sinput}
> ( dd.kn <- with( subset(Si,lex.Xst=="Dead"),
+                  c(0,quantile( DMdur+lex.dur, probs=(1:(nk-1))/nk ) )) )
\end{Sinput}
\begin{Soutput}
                20%       40%       60%       80% 
0.0000000 0.7687885 2.1327858 4.0465435 6.5232033 
\end{Soutput}
\begin{Sinput}
> ( ti.kn <- with( subset(Si,lex.Xst=="Dead(Ins)"),
+                  c(0,quantile( t.Ins+lex.dur, probs=(1:(nk-1))/nk ) )) )
\end{Sinput}
\begin{Soutput}
                20%       40%       60%       80% 
0.0000000 0.3093771 1.1307324 2.5489391 4.9117043 
\end{Soutput}
\end{Schunk}
Note that when we tease out the event records for transition to
\emph{transient} states (in this case \texttt{Ins}, that is
\verb|lex.Xst=="Ins"|), we should add \verb|lex.Cst!=lex.Xst|, to
include only transition records and avoiding including records of
sojourn time in the transient state.
 
We then fit Poisson models to transition rates, using the wrapper
\texttt{Ns} from the \texttt{Epi} package to simplify the
specification of the rates:
\begin{Schunk}
\begin{Sinput}
> library( splines )
> DM.Ins <- glm( (lex.Xst=="Ins") ~ Ns( Age  , knots=ai.kn ) +
+                                   Ns( DMdur, knots=di.kn ) +
+                                   I(Per-2000) + sex,
+                family=poisson, offset=log(lex.dur),
+                data = subset(Si,lex.Cst=="DM") )
> ci.exp( DM.Ins )
\end{Sinput}
\begin{Soutput}
                           exp(Est.)       2.5%      97.5%
(Intercept)               1.37516629 1.21414923 1.55753699
Ns(Age, knots = ai.kn)1   0.23411761 0.19185266 0.28569349
Ns(Age, knots = ai.kn)2   0.23166177 0.19576557 0.27414000
Ns(Age, knots = ai.kn)3   0.02835009 0.02284379 0.03518363
Ns(Age, knots = ai.kn)4   0.38067392 0.32945713 0.43985278
Ns(DMdur, knots = di.kn)1 0.04462626 0.03373451 0.05903459
Ns(DMdur, knots = di.kn)2 0.22388988 0.19028663 0.26342723
Ns(DMdur, knots = di.kn)3 0.03379141 0.02574708 0.04434907
Ns(DMdur, knots = di.kn)4 0.47100646 0.40783317 0.54396529
I(Per - 2000)             0.97381513 0.96082049 0.98698552
sexF                      0.73757407 0.66886782 0.81333785
\end{Soutput}
\begin{Sinput}
> class( DM.Ins )
\end{Sinput}
\begin{Soutput}
[1] "glm" "lm" 
\end{Soutput}
\end{Schunk}
We can also fit this model with a slightly simpler syntax using the
\texttt{glm.Lexis} function:
\begin{Schunk}
\begin{Sinput}
> DM.Ins <- glm.Lexis( Si, from = "DM", to = "Ins",
+                       formula = ~ Ns( Age  , knots=ai.kn ) +
+                                   Ns( DMdur, knots=di.kn ) +
+                                   I(Per-2000) + sex )
\end{Sinput}
\begin{Soutput}
stats::glm Poisson analysis of Lexis object Si with log link:
Rates for the transition: DM->Ins
\end{Soutput}
\begin{Sinput}
> ci.exp( DM.Ins )
\end{Sinput}
\begin{Soutput}
                           exp(Est.)       2.5%      97.5%
(Intercept)               1.37516630 1.21415038 1.55753552
Ns(Age, knots = ai.kn)1   0.23411761 0.19185214 0.28569426
Ns(Age, knots = ai.kn)2   0.23166177 0.19576473 0.27414118
Ns(Age, knots = ai.kn)3   0.02835009 0.02284374 0.03518371
Ns(Age, knots = ai.kn)4   0.38067392 0.32945601 0.43985427
Ns(DMdur, knots = di.kn)1 0.04462625 0.03373347 0.05903639
Ns(DMdur, knots = di.kn)2 0.22388988 0.19028599 0.26342813
Ns(DMdur, knots = di.kn)3 0.03379141 0.02574705 0.04434912
Ns(DMdur, knots = di.kn)4 0.47100646 0.40783201 0.54396683
I(Per - 2000)             0.97381513 0.96082027 0.98698574
sexF                      0.73757407 0.66886641 0.81333956
\end{Soutput}
\begin{Sinput}
> class( DM.Ins )
\end{Sinput}
\begin{Soutput}
[1] "glm.lex" "glm"     "lm"     
\end{Soutput}
\end{Schunk}
So we have a slightly simpler syntax, and we get an informative
message of which transition(s) we are modeling. However we do not have
\texttt{update} method for these objects.
\begin{Schunk}
\begin{Sinput}
> DM.Dead <- glm.Lexis( Si, from = "DM", to = "Dead",
+                        formula = ~ Ns( Age  , knots=ad.kn ) +
+                                    Ns( DMdur, knots=dd.kn ) +
+                                    I(Per-2000) + sex )
\end{Sinput}
\begin{Soutput}
stats::glm Poisson analysis of Lexis object Si with log link:
Rates for the transition: DM->Dead
\end{Soutput}
\begin{Sinput}
> Ins.Dead <- glm.Lexis( Si, from = "Ins",
+                         formula = ~ Ns( Age  , knots=ad.kn ) +
+                                     Ns( DMdur, knots=dd.kn ) +
+                                     Ns( t.Ins, knots=ti.kn ) +
+                                     I(Per-2000) + sex )
\end{Sinput}
\begin{Soutput}
stats::glm Poisson analysis of Lexis object Si with log link:
Rates for the transition: Ins->Dead(Ins)
\end{Soutput}
\end{Schunk}
Note the similarity of the code used to fit the three models, is is
mainly redefining the response variable (\texttt{to} state) and the subset
of the data used (\texttt{from} state). Also note that the last model need
no specification of \texttt{to}, the default is to model all
transitions from the \texttt{from} state, and his case there is only
one.

\section{The mortality rates}

This section discusses in some detail how to extract ad display the
mortality rates from the models fitted. But it is not necessary for
understanding how to use \texttt{simLexis} in practice.

\subsection{Proportionality of mortality rates}

Note that we have fitted separate models for the three transitions,
there is no assumption of proportionality between the mortality rates
from \texttt{DM} and \texttt{Ins}.

However, there is nothing that prevents us from testing this
assumption; we can just fit a model for the mortality rates in the
entire data frame \texttt{Si}, and compare the deviance from this with
the sum of the deviances from the separate models using the \texttt{glm.Lexis}
function:  
\begin{Schunk}
\begin{Sinput}
> All.Dead <- glm.Lexis( Si, to = c("Dead(Ins)","Dead"),
+                       formula = ~ Ns( Age  , knots=ad.kn ) +
+                                   Ns( DMdur, knots=dd.kn ) +
+                                   lex.Cst +
+                                   I(Per-2000) + sex )
\end{Sinput}
\begin{Soutput}
stats::glm Poisson analysis of Lexis object Si with log link:
Rates for transitions: Ins->Dead(Ins), DM->Dead
\end{Soutput}
\begin{Sinput}
> round( ci.exp( All.Dead ), 3 )
\end{Sinput}
\begin{Soutput}
                          exp(Est.)   2.5%  97.5%
(Intercept)                   0.057  0.049  0.065
Ns(Age, knots = ad.kn)1       4.101  3.462  4.858
Ns(Age, knots = ad.kn)2       4.661  4.064  5.346
Ns(Age, knots = ad.kn)3      15.434 13.548 17.583
Ns(Age, knots = ad.kn)4       7.509  6.695  8.421
Ns(DMdur, knots = dd.kn)1     0.466  0.384  0.565
Ns(DMdur, knots = dd.kn)2     0.642  0.563  0.731
Ns(DMdur, knots = dd.kn)3     0.229  0.165  0.318
Ns(DMdur, knots = dd.kn)4     0.796  0.713  0.888
lex.CstIns                    2.168  1.947  2.415
I(Per - 2000)                 0.965  0.954  0.977
sexF                          0.665  0.614  0.721
\end{Soutput}
\end{Schunk}
Incidentally we could have dispensed with the \texttt{to=} argument
too, because the default is to take \texttt{to} to be all absorbing
states in the model.

From the parameter values we would in a simple setting just claim that
start of insulin-treatment was associated with a slightly more than
doubling of mortality.

The model \texttt{All.dead} assumes that the age- and DM-duration
effects on mortality in the \texttt{DM} and \texttt{Ins} states are the same,
and moreover that there is no effect of insulin duration, but merely a
mortality that is larger by a multiplicative constant not depending on
insulin duration. The model \texttt{DM.Dead} has 8 parameters to
describe the dependency on age and DM duration, the model
\texttt{Ins.Dead} has 12 for the same plus the insulin duration (a
natural spline with $k$ knots gives $k-1$ parameters, and we chose
$k=5$ above).

We can compare the fit of the simple proportional hazards model with
the fit of the separate models for the two mortality rates, by adding
up the deviances and d.f. from these:
\begin{Schunk}
\begin{Sinput}
> what <- c("null.deviance","df.null","deviance","df.residual")
> ( rD <- unlist(  DM.Dead[what] ) )
\end{Sinput}
\begin{Soutput}
null.deviance       df.null      deviance   df.residual 
     22535.77     188727.00      20412.81     188717.00 
\end{Soutput}
\begin{Sinput}
> ( rI <- unlist( Ins.Dead[what] ) )
\end{Sinput}
\begin{Soutput}
null.deviance       df.null      deviance   df.residual 
     4867.127     35157.000      4211.735     35143.000 
\end{Soutput}
\begin{Sinput}
> ( rA <- unlist( All.Dead[what] ) )
\end{Sinput}
\begin{Soutput}
null.deviance       df.null      deviance   df.residual 
     27415.21     223885.00      24705.70     223874.00 
\end{Soutput}
\begin{Sinput}
> round( c( dd <- rA-(rI+rD), "pVal"=1-pchisq(dd[3],dd[4]+1) ), 3 )
\end{Sinput}
\begin{Soutput}
null.deviance       df.null      deviance   df.residual pVal.deviance 
       12.314         1.000        81.154        14.000         0.000 
\end{Soutput}
\end{Schunk}
Thus we see there is a substantial non-proportionality of mortality
rates from the two states; but a test provides no clue whatsoever to
the particular \emph{shape} of the non-proportionality.

To this end, we shall explore the predicted mortalities under the two
models quantitatively in more detail. Note that the reason that there
is a difference in the null deviances (and a difference of 1 in the
null d.f.) is that the null deviance of \texttt{All.Dead} refer to a
model with a single intercept, that is a model with constant and
\emph{identical} mortality rates from the states \texttt{DM} and \texttt{Ins},
whereas the null models for \texttt{DM.Dead} and \texttt{Ins.Dead}
have constant but \emph{different} mortality rates from the states
\texttt{DM} and \texttt{Ins}.  This is however irrelevant for the comparison of
the \emph{residual} deviances.

\subsection{How the mortality rates look}

If we want to see how the mortality rates are modelled in
\texttt{DM.Dead} and \texttt{Ins.Dead} in relation to
\texttt{All.Dead}, we make a prediction of rates for say men diagnosed
in different ages and going on insulin at different times after
this. So we consider men diagnosed in ages 40, 50, 60 and 70, and who
either never enter insulin treatment or do it 0, 2 or 5 years after
diagnosis of DM.

To this end we create a prediction data frame where we have
observation times from diagnosis and 12 years on (longer would not
make sense as this is the extent of the data).

But we start by setting up an array to hold the predicted mortality
rates, classified by diabetes duration, age at diabetes onset, time of
insulin onset, and of course type of model. What we want to do is to
plot the age-specific mortality rates for persons not on insulin, and
for persons starting insulin at different times after DM. The
mortality curves start at the age where the person gets diabetes and
continues 12 years; for persons on insulin they start at the age when
they initiate insulin.
\begin{Schunk}
\begin{Sinput}
> pr.rates <- NArray( list( DMdur = seq(0,12,0.1),
+                           DMage = 4:7*10,
+                           r.Ins = c(NA,0,2,5),
+                           model = c("DM/Ins","All"),
+                            what = c("rate","lo","hi") ) )
> str( pr.rates )
\end{Sinput}
\begin{Soutput}
 logi [1:121, 1:4, 1:4, 1:2, 1:3] NA NA NA NA NA NA ...
 - attr(*, "dimnames")=List of 5
  ..$ DMdur: chr [1:121] "0" "0.1" "0.2" "0.3" ...
  ..$ DMage: chr [1:4] "40" "50" "60" "70"
  ..$ r.Ins: chr [1:4] NA "0" "2" "5"
  ..$ model: chr [1:2] "DM/Ins" "All"
  ..$ what : chr [1:3] "rate" "lo" "hi"
\end{Soutput}
\end{Schunk}
For convenience the \texttt{Epi} package contains a function that computes
predicted (log-)rates with c.i. --- it is merely a wrapper for
\texttt{predict.glm}.

So we set up the prediction data frame and modify it in loops over
ages at onset and insulin onset in order to collect the predicted
rates in different scenarios:
\begin{Schunk}
\begin{Sinput}
> nd <- data.frame( DMdur = as.numeric( dimnames(pr.rates)[[1]] ),
+                 lex.Cst = factor( 1, levels=1:4,
+                                   labels=levels(Si$lex.Cst) ),
+                     sex = factor( 1, levels=1:2, labels=c("M","F")) )
\end{Sinput}
\end{Schunk}
Note that we did \emph{not} insert \texttt{lex.dur} as covariate in
the prediction frame. This would be required if we used the
\texttt{poisson} family with the \texttt{glm}, but the wrapper
\texttt{glm.Lexis} uses the \texttt{poisreg} family, so
\texttt{lex.dur} is ignored and predictions always comes in the
(inverse) units of \texttt{lex.dur}. So we get rates per 1 person-year
in the predictions.
\begin{Schunk}
\begin{Sinput}
> for( ia in dimnames(pr.rates)[[2]] )
+    {
+ dnew <- transform( nd, Age = as.numeric(ia)+DMdur,
+                        Per = 1998+DMdur )
+ pr.rates[,ia,1,"DM/Ins",] <- ci.pred(  DM.Dead, newdata = dnew )
+ pr.rates[,ia,1,"All"   ,] <- ci.pred( All.Dead, newdata = dnew )
+ for( ii in dimnames(pr.rates)[[3]][-1] )
+    {
+ dnew = transform( dnew, lex.Cst = factor( 2, levels=1:4,
+                                           labels=levels(Si$lex.Cst) ),
+                           t.Ins = ifelse( (DMdur-as.numeric(ii)) >= 0,
+                                            DMdur-as.numeric(ii), NA ) )
+ pr.rates[,ia, ii ,"DM/Ins",] <- ci.pred( Ins.Dead, newdata = dnew )
+ pr.rates[,ia, ii ,"All"   ,] <- ci.pred( All.Dead, newdata = dnew )
+     }
+     }
\end{Sinput}
\end{Schunk}
So for each age at DM onset we make a plot of the mortality as
function of current age both for those with no insulin treatment and
those that start insulin treatment 0, 2 and 5 years after diabetes
diagnosis, thus 4 curves (with c.i.). These curves are replicated with
a different color for the simplified model.
\begin{Schunk}
\begin{Sinput}
> par( mar=c(3,3,1,1), mgp=c(3,1,0)/1.6, las=1 )
> plot( NA, xlim=c(40,82), ylim=c(5,300), bty="n",
+       log="y", xlab="Age", ylab="Mortality rate per 1000 PY" )
> abline( v=seq(40,80,5), h=outer(1:9,10^(0:2),"*"), col=gray(0.8) )
> for( aa in 4:7*10 ) for( ii in 1:4 )
+    matshade( aa+as.numeric(dimnames(pr.rates)[[1]]),
+              cbind( pr.rates[,paste(aa),ii,"DM/Ins",],
+                     pr.rates[,paste(aa),ii,"All"   ,] )*1000,
+              type="l", lty=1, lwd=2,
+              col=c("red","limegreen") )
\end{Sinput}
\end{Schunk}
\insfig{mort-int}{0.9}{Estimated mortality rates for male diabetes
  patients with no insulin (lower sets of curves) and insulin (upper
  curves), with DM onset in age 40, 50, 60 and 70. The red curves are
  from the models with separate age effects for persons with and
  without insulin, and a separate effect of insulin duration. The
  green curves are from the model with common age-effects and only a
  time-dependent effect of insulin, assuming no effect of insulin
  duration (the classical time-dependent variable approach). Hence the
  upper green curve is common for any time of insulin inception.}

From figure \ref{fig:mort-int} we see that there is a substantial
insulin-duration effect which is not accommodated by the simple model
with only one time-dependent variable to describe the insulin
effect. Note that the simple model (green curves) for those on insulin
does not depend in insulin duration, and hence the mortality curves
for those on insulin are just parallel to the mortality curves for
those not on insulin, regardless of diabetes duration (or age) at the
time of insulin initiation. This is the proportional hazards
assumption.  Thus the effect of insulin initiation is under-estimated
for short duration of insulin and over-estimated for long duration of
insulin.

This is the major discrepancy between the two models, and
illustrates the importance of being able to accommodate different time
scales, but there is also a declining overall insulin effect by age which
is not accommodated by the proportional hazards approach.

Finally, this plot illustrates an important feature in reporting
models with multiple timescales; all timescales must be represented in
the predicted rates, only reporting the effect of one timescale,
conditional on a fixed value of other timescales is misleading since
all timescales by definition advance at the same pace. For example,
the age-effect for a fixed value of insulin duration really is a
misnomer since it does not correspond to any real person's follow-up,
but to the mortality of persons in different ages but with the same
duration of insulin use.

\section{Input to the \texttt{simLexis} function}

We want to estimate the cumulative probability of being in each of the
4 states, so that we can assess the fraction of diabetes pateints that
go on insulin

In order to simulate from the multistate model with the estimated
transition rates, and get the follow-up of a hypothetical cohort, we
must supply \emph{both} the transition rates and the structure of the
model \emph{as well as} the initial cohort status to
\texttt{simLexis}.

\subsection{The transition object}

We first put the models into an object representing the transitions;
note this is a list of lists, the latter having \texttt{glm} objects
as elements:
\begin{Schunk}
\begin{Sinput}
> Tr <- list( "DM" = list( "Ins"       = DM.Ins,
+                          "Dead"      = DM.Dead  ),
+            "Ins" = list( "Dead(Ins)" = Ins.Dead ) )
\end{Sinput}
\end{Schunk}
Now we have the description of the rates and of the structure of the
model. The \texttt{Tr} object defines the states and models for all
transitions between them; the object \verb|Tr$A$B| is the model
for the transition intensity from state \texttt{A} to state
\texttt{B}.

\subsection{The initial cohort}

We now define an initial \texttt{Lexis} object of persons with all
relevant covariates defined. Note that we use \texttt{NULL} as row
indicator in the \texttt{Lexis} object we used for modeling; this
conserves the \texttt{time.scale} and \texttt{time.since} attributes
which are needed for the simulation:
\begin{Schunk}
\begin{Sinput}
> str( ini <- Si[NULL,1:9] )
\end{Sinput}
\begin{Soutput}
Classes ‘Lexis’ and 'data.frame':	0 obs. of  9 variables:
 $ lex.id : int 
 $ Per    : num 
 $ Age    : num 
 $ DMdur  : num 
 $ t.Ins  : num 
 $ lex.dur: num 
 $ lex.Cst: Factor w/ 4 levels "DM","Ins","Dead",..: 
 $ lex.Xst: Factor w/ 4 levels "DM","Ins","Dead",..: 
 $ sex    : Factor w/ 2 levels "M","F": 
 - attr(*, "time.scales")= chr  "Per" "Age" "DMdur" "t.Ins"
 - attr(*, "time.since")= chr  "" "" "" "Ins"
 - attr(*, "breaks")=List of 4
  ..$ Per  : NULL
  ..$ Age  : NULL
  ..$ DMdur: num  0 0.25 0.5 0.75 1 1.25 1.5 1.75 2 2.25 ...
  ..$ t.Ins: NULL
\end{Soutput}
\end{Schunk}
We now have an empty \texttt{Lexis} object with attributes reflecting
the timescales in the multistate model we want to simulate from. But
we must enter some data to represent the initial state of the persons
whose follow-up we want to simulate through the model; so fill in data
for one man and one woman:
\begin{Schunk}
\begin{Sinput}
> ini[1:2,"lex.id"] <- 1:2
> ini[1:2,"lex.Cst"] <- "DM"
> ini[1:2,"Per"] <- 1995
> ini[1:2,"Age"] <- 60
> ini[1:2,"DMdur"] <- 5
> ini[1:2,"sex"] <- c("M","F")
> ini
\end{Sinput}
\begin{Soutput}
  lex.id  Per Age DMdur t.Ins lex.dur lex.Cst lex.Xst sex
1      1 1995  60     5    NA      NA      DM    <NA>   M
2      2 1995  60     5    NA      NA      DM    <NA>   F
\end{Soutput}
\end{Schunk}
So the persons starts in age 60 in 1995 with 5 years of diabetes
duration. Note that the \texttt{t.Ins} is \texttt{NA}, because this is
a timescale that first comes alive if a transtion to \texttt{Ins} is
simulated.

\section{Simulation of the follow-up}

Now we simulate life-courses of a 1000 of each of these persons using
the estimated model. The \texttt{t.range} argument gives the times
range where the integrated intensities (cumulative rates) are
evaluated and where linear interpolation is used when simulating
transition times. Note that this must be given in the same units as
\texttt{lex.dur} in the \texttt{Lexis} object used for fitting the
models for the transitions. It is not a parameter that can be easily
determined from the \texttt{TR} object, hence it must be supplied by
the user.
\begin{Schunk}
\begin{Sinput}
> set.seed( 52381764 )
> Nsim <- 5000
> system.time( simL <- simLexis( Tr,
+                               ini,
+                           t.range = 12,
+                                 N = Nsim ) )
\end{Sinput}
\begin{Soutput}
   user  system elapsed 
 18.788   1.130  18.914 
\end{Soutput}
\end{Schunk}
The result is a \texttt{Lexis} object --- a data frame representing
the simulated follow-up of 10000 persons (5000
identical men and 5000 identical women) according to the rates
we estimated from the original dataset.
\begin{Schunk}
\begin{Sinput}
> summary( simL, by="sex" )
\end{Sinput}
\begin{Soutput}
$M
     
Transitions:
     To
From    DM  Ins Dead Dead(Ins)  Records:  Events: Risk time:  Persons:
  DM  1438 2048 1514         0      5000     3562   36620.95      5000
  Ins    0 1363    0       685      2048      685   10935.47      2048
  Sum 1438 3411 1514       685      7048     4247   47556.41      5000

$F
     
Transitions:
     To
From    DM  Ins Dead Dead(Ins)  Records:  Events: Risk time:  Persons:
  DM  2186 1689 1125         0      5000     2814   42181.63      5000
  Ins    0 1321    0       368      1689      368    9535.20      1689
  Sum 2186 3010 1125       368      6689     3182   51716.83      5000
\end{Soutput}
\end{Schunk}

\subsection{Using other models for simulation}

\subsubsection{Proportional hazards Poisson model}

We fitted a proportional mortality model \texttt{All.Dead} (which fitted
worse than the other two), this is a model for \emph{both} the
transition from \texttt{DM} to \texttt{Death} \emph{and} from \texttt{Ins} to
\texttt{Dead(Ins)}, assuming that they are proportional. But it can easily
be used in the simulation set-up, because the state is embedded in the
model via the term \texttt{lex.Cst}, which is updated during the simulation.

Simulation using this instead just requires that we supply a different
transition object:
\begin{Schunk}
\begin{Sinput}
> Tr.p <- list( "DM" = list( "Ins"       = DM.Ins,
+                            "Dead"      = All.Dead  ),
+              "Ins" = list( "Dead(Ins)" = All.Dead ) )
> system.time( simP <- simLexis( Tr.p,
+                                 ini,
+                             t.range = 12,
+                                   N = Nsim ) )
\end{Sinput}
\begin{Soutput}
   user  system elapsed 
 17.604   0.988  17.625 
\end{Soutput}
\begin{Sinput}
> summary( simP, by="sex" )
\end{Sinput}
\begin{Soutput}
$M
     
Transitions:
     To
From    DM  Ins Dead Dead(Ins)  Records:  Events: Risk time:  Persons:
  DM  1633 1984 1383         0      5000     3367   37674.18      5000
  Ins    0 1135    0       849      1984      849    9807.38      1984
  Sum 1633 3119 1383       849      6984     4216   47481.56      5000

$F
     
Transitions:
     To
From    DM  Ins Dead Dead(Ins)  Records:  Events: Risk time:  Persons:
  DM  2285 1695 1020         0      5000     2715   42892.52      5000
  Ins    0 1191    0       504      1695      504    8833.70      1695
  Sum 2285 2886 1020       504      6695     3219   51726.21      5000
\end{Soutput}
\end{Schunk}

\subsubsection{Proportional hazards Cox model}

A third possibility would be to replace the two-time scale
proportional mortality model by a one-time-scale Cox-model, using
diabetes duration as time scale, and age at diagnosis of DM as (fixed)
covariate:
\begin{Schunk}
\begin{Sinput}
> library( survival )
> Cox.Dead <- coxph( Surv( DMdur, DMdur+lex.dur,
+                          lex.Xst %in% c("Dead(Ins)","Dead")) ~
+                    Ns( Age-DMdur, knots=ad.kn ) +
+                    I(lex.Cst=="Ins") +
+                    I(Per-2000) + sex,
+                data = Si )
> round( ci.exp( Cox.Dead ), 3 )
\end{Sinput}
\begin{Soutput}
                                exp(Est.)   2.5%  97.5%
Ns(Age - DMdur, knots = ad.kn)1     4.172  3.535  4.923
Ns(Age - DMdur, knots = ad.kn)2     4.502  3.824  5.301
Ns(Age - DMdur, knots = ad.kn)3    16.077 14.087 18.348
Ns(Age - DMdur, knots = ad.kn)4     7.479  6.501  8.605
I(lex.Cst == "Ins")TRUE             2.170  1.948  2.418
I(Per - 2000)                       0.965  0.954  0.977
sexF                                0.667  0.616  0.723
\end{Soutput}
\end{Schunk}
Note that in order for this model to be usable for simulation, it is
necessary that we use the components of the \texttt{Lexis} object to
specify the survival. Each record in the data frame \texttt{Si}
represents follow up from \texttt{DMdur} to \texttt{DMdur+lex.dur}, so
the model is a Cox model with diabetes duration as underlying timescale
and age at diagnosis, \texttt{Age-DMdur}, as covariate.

Also note that we used \texttt{I(lex.Cst=="Ins")} instead of just
\texttt{lex.Cst}, because \texttt{coxph} assigns design matrix columns
to all levels of \texttt{lex.Cst}, also those not present in data,
which would give \texttt{NA}s among the parameter estimates and
\texttt{NA}s as mortality outcomes.

We see that the effect of insulin and the other covariates are pretty
much the same as in the two-time-scale model. We can simulate from this
model too; there is no restrictions on what type of model can be used
for different transitions
\begin{Schunk}
\begin{Sinput}
> Tr.c <- list( "DM" = list( "Ins"       = Tr$DM$Ins,
+                            "Dead"      = Cox.Dead  ),
+              "Ins" = list( "Dead(Ins)" = Cox.Dead ) )
> system.time( simC <- simLexis( Tr.c,
+                                 ini,
+                             t.range = 12,
+                                   N = Nsim ) )
\end{Sinput}
\begin{Soutput}
   user  system elapsed 
 19.195   1.241  19.470 
\end{Soutput}
\begin{Sinput}
> summary( simC, by="sex" )
\end{Sinput}
\begin{Soutput}
$M
     
Transitions:
     To
From    DM  Ins Dead Dead(Ins)  Records:  Events: Risk time:  Persons:
  DM  1714 2039 1247         0      5000     3286   37280.04      5000
  Ins    0 1348    0       691      2039      691    9990.38      2039
  Sum 1714 3387 1247       691      7039     3977   47270.42      5000

$F
     
Transitions:
     To
From    DM  Ins Dead Dead(Ins)  Records:  Events: Risk time:  Persons:
  DM  2332 1702  966         0      5000     2668   42168.20      5000
  Ins    0 1313    0       389      1702      389    9083.14      1702
  Sum 2332 3015  966       389      6702     3057   51251.34      5000
\end{Soutput}
\end{Schunk}

\section{Reporting the simulation results}

We can now tabulate the number of persons in each state at a
predefined set of times on a given time scale. Note that in order for
this to be sensible, the \texttt{from} argument would normally be
equal to the starting time for the simulated individuals.
\begin{Schunk}
\begin{Sinput}
> system.time(
+ nSt <- nState( subset(simL,sex=="M"),
+                at=seq(0,11,0.2), from=1995, time.scale="Per" ) )
\end{Sinput}
\begin{Soutput}
   user  system elapsed 
  0.744   0.000   0.743 
\end{Soutput}
\begin{Sinput}
> nSt[1:10,]
\end{Sinput}
\begin{Soutput}
        State
when       DM  Ins Dead Dead(Ins)
  1995   5000    0    0         0
  1995.2 4932   38   29         1
  1995.4 4843   93   62         2
  1995.6 4773  137   87         3
  1995.8 4702  179  116         3
  1996   4621  226  148         5
  1996.2 4547  269  179         5
  1996.4 4469  309  212        10
  1996.6 4407  342  237        14
  1996.8 4322  386  275        17
\end{Soutput}
\end{Schunk}
We see that as time goes by, the 5000 men slowly move away from the
starting state (\texttt{DM}).

Based on this table (\texttt{nSt} is a table) we can now compute the
fractions in each state, or, rather more relevant, the cumulative fraction
across the states in some specified order, so that a plot of the
stacked probabilities can be made, using either the default rather
colorful layout, or a more minimalist version (both in figure \ref{fig:pstate0}):
\begin{Schunk}
\begin{Sinput}
> pM <- pState( nSt, perm=c(1,2,4,3) )
> head( pM )
\end{Sinput}
\begin{Soutput}
        State
when         DM    Ins Dead(Ins) Dead
  1995   1.0000 1.0000    1.0000    1
  1995.2 0.9864 0.9940    0.9942    1
  1995.4 0.9686 0.9872    0.9876    1
  1995.6 0.9546 0.9820    0.9826    1
  1995.8 0.9404 0.9762    0.9768    1
  1996   0.9242 0.9694    0.9704    1
\end{Soutput}
\begin{Sinput}
> par( mfrow=c(1,2), mar=c(3,3,1,1), mgp=c(3,1,0)/1.6 )
> plot( pM )
> plot( pM, border="black", col="transparent", lwd=3 )
> text( rep(as.numeric(rownames(pM)[nrow(pM)-1]),ncol(pM)),
+       pM[nrow(pM),]-diff(c(0,pM[nrow(pM),]))/5,
+       colnames( pM ), adj=1 )
> box( col="white", lwd=3 )
> box()
\end{Sinput}
\end{Schunk}
\insfig{pstate0}{1.0}{Default layout of the \textrm{\tt plot.pState}
  graph (left), and a version with the state probabilities as lines and
  annotation of states.}

A more useful set-up of the graph would include a more through
annotation and sensible choice of colors, as seen in figure \ref{fig:pstatex}:
\begin{Schunk}
\begin{Sinput}
> clr <- c("limegreen","orange")
> # expand with a lighter version of the two chosen colors
> clx <- c( clr, rgb( t( col2rgb( clr[2:1] )*2 + rep(255,3) ) / 3, max=255 ) )
> par( mfrow=c(1,2), las=1, mar=c(3,3,4,2), mgp=c(3,1,0)/1.6 )
> # Men
> plot( pM, col=clx, xlab="Date of FU" )
> lines( as.numeric(rownames(pM)), pM[,2], lwd=3 )
> mtext( "60 year old male, diagnosed 1990, aged 55", side=3, line=2.5, adj=0, col=gray(0.6) )
> mtext( "Survival curve", side=3, line=1.5, adj=0 )
> mtext( "DM, no insulin   DM, Insulin", side=3, line=0.5, adj=0, col=clr[2] )
> mtext( "DM, no insulin", side=3, line=0.5, adj=0, col=clr[1] )
> axis( side=4 )
> axis( side=4, at=1:19/20, labels=FALSE )
> axis( side=4, at=1:99/100, labels=FALSE, tcl=-0.3 )
> # Women
> pF <- pState( nState( subset(simL,sex=="F"),
+                       at=seq(0,11,0.2),
+                       from=1995,
+                       time.scale="Per" ),
+               perm=c(1,2,4,3) )
> plot( pF, col=clx, xlab="Date of FU" )
> lines( as.numeric(rownames(pF)), pF[,2], lwd=3 )
> mtext( "60 year old female, diagnosed 1990, aged 55", side=3, line=2.5, adj=0, col=gray(0.6) )
> mtext( "Survival curve", side=3, line=1.5, adj=0 )
> mtext( "DM, no insulin   DM, Insulin", side=3, line=0.5, adj=0, col=clr[2] )
> mtext( "DM, no insulin", side=3, line=0.5, adj=0, col=clr[1] )
> axis( side=4 )
> axis( side=4, at=1:19/20, labels=FALSE )
> axis( side=4, at=1:99/100, labels=FALSE, tcl=-0.3 )
\end{Sinput}
\end{Schunk}
\insfig{pstatex}{1.0}{\textrm{\tt plot.pState} graphs where persons
  ever on insulin are given in orange and persons never on insulin in
  green, and the overall survival (dead over the line) as a black line.}

If we instead wanted to show the results on the age-scale, we would
use age as timescale when constructing the probabilities; otherwise the
code is pretty much the same as before (Figure \ref{fig:pstatey}):
\begin{Schunk}
\begin{Sinput}
> par( mfrow=c(1,2), las=1, mar=c(3,3,4,2), mgp=c(3,1,0)/1.6 )
> # Men
> pM <- pState( nState( subset(simL,sex=="M"),
+                       at=seq(0,11,0.2),
+                       from=60,
+                       time.scale="Age" ),
+               perm=c(1,2,4,3) )
> plot( pM, col=clx, xlab="Age" )
> lines( as.numeric(rownames(pM)), pM[,2], lwd=3 )
> mtext( "60 year old male, diagnosed 1990, aged 55", side=3, line=2.5, adj=0, col=gray(0.6) )
> mtext( "Survival curve", side=3, line=1.5, adj=0 )
> mtext( "DM, no insulin   DM, Insulin", side=3, line=0.5, adj=0, col=clr[2] )
> mtext( "DM, no insulin", side=3, line=0.5, adj=0, col=clr[1] )
> axis( side=4 )
> axis( side=4, at=1:19/20, labels=FALSE )
> axis( side=4, at=1:19/20, labels=FALSE, tcl=-0.4 )
> axis( side=4, at=1:99/100, labels=FALSE, tcl=-0.3 )
> # Women
> pF <- pState( nState( subset(simL,sex=="F"),
+                       at=seq(0,11,0.2),
+                       from=60,
+                       time.scale="Age" ),
+               perm=c(1,2,4,3) )
> plot( pF, col=clx, xlab="Age" )
> lines( as.numeric(rownames(pF)), pF[,2], lwd=3 )
> mtext( "60 year old female, diagnosed 1990, aged 55", side=3, line=2.5, adj=0, col=gray(0.6) )
> mtext( "Survival curve", side=3, line=1.5, adj=0 )
> mtext( "DM, no insulin   DM, Insulin", side=3, line=0.5, adj=0, col=clr[2] )
> mtext( "DM, no insulin", side=3, line=0.5, adj=0, col=clr[1] )
> axis( side=4 )
> axis( side=4, at=1:9/10, labels=FALSE )
> axis( side=4, at=1:19/20, labels=FALSE, tcl=-0.4 )
> axis( side=4, at=1:99/100, labels=FALSE, tcl=-0.3 )
\end{Sinput}
\end{Schunk}
Note the several statements with \texttt{axis(side=4,...}; they are
necessary to get the fine tick-marks in the right hand side of the
plots that you will need in order to read off the probabilities at
2006 (or 71 years).

\insfig{pstatey}{1.0}{\textrm{\tt plot.pState} graphs where persons
  ever on insulin are given in orange and persons never on insulin in
  green, and the overall survival (dead over the line) as a black line.}

\subsection{Comparing predictions from different models}

We have actually fitted different models for the transitions, and we
have simulated Lexis objects from all three approaches, so we can plot
these predictions on top of each other:
\begin{Schunk}
\begin{Sinput}
> PrM  <- pState( nState( subset(simP,sex=="M"),
+                         at=seq(0,11,0.2),
+                         from=60,
+                         time.scale="Age" ),
+                 perm=c(1,2,4,3) )
> PrF  <- pState( nState( subset(simP,sex=="F"),
+                         at=seq(0,11,0.2),
+                         from=60,
+                         time.scale="Age" ),
+                 perm=c(1,2,4,3) )
> CoxM <- pState( nState( subset(simC,sex=="M"),
+                         at=seq(0,11,0.2),
+                         from=60,
+                         time.scale="Age" ),
+                 perm=c(1,2,4,3) )
> CoxF <- pState( nState( subset(simC,sex=="F"),
+                         at=seq(0,11,0.2),
+                         from=60,
+                         time.scale="Age" ),
+                 perm=c(1,2,4,3) )
> par( mfrow=c(1,2), mar=c(3,3,1,1), mgp=c(3,1,0)/1.6 )
>  plot(   pM, border="black", col="transparent", lwd=3 )
> lines(  PrM, border="blue" , col="transparent", lwd=3 )
> lines( CoxM, border="red"  , col="transparent", lwd=3 )
> text( 60.5, 0.05, "M" )
> box( lwd=5, col="white" ) ; box( lwd=2, col="black" )
>  plot(   pF, border="black", col="transparent", lwd=3 )
> lines(  PrF, border="blue" , col="transparent", lwd=3 )
> lines( CoxF, border="red"  , col="transparent", lwd=3 )
> text( 60.5, 0.05, "F" )
> box( lwd=5, col="white" ) ; box( lwd=2, col="black" )
\end{Sinput}
\end{Schunk}
\insfig{comp-0}{1.0}{Comparison of the simulated state occupancy
  probabilities using separate Poisson models for the mortality rates
  with and without insulin (black) and using proportional hazards
  Poisson models (blue) and Cox-models with diabetes duration as
  timescale and age at diabetes diagnosis as covariate (red).}

From figure \ref{fig:comp-0} it is clear that the two proportional
hazards models (blue and red curves) produce pretty much the same
estimates of the state occupancy probabilities over time, but also that
they relative to the model with separately estimated transition
intensities overestimates the probability of being alive without
insulin and underestimates the probabilities of being dead without
insulin. However both the overall survival, and the fraction of
persons on insulin are quite well in agreement with the more elaborate
model. Thus the proportional hazards models overestimate the relative
mortality of the insulin treated diabetes patients relative to the
non-insulin treated.

Interestingly, we also see a bump in the estimated probabilities from
the Cox-model based model, but this is entirely an artifact that comes
from the estimation method for the baseline hazard of the Cox-model
that lets the (cumulative) hazard have large jumps at event times
where the risk set is small. So also here it shows up that an
assumption of continuous underlying hazards leads to more credible
estimates.

\chapter{Simulation of transitions in multistate models}

\section{Theory}

Suppose that the rate functions for the transitions out of the current
state to, say, 3 different states are $\lambda_1$, $\lambda_2$ and
$\lambda_3$, and the corresponding cumulative rates are $\Lambda_1$,
$\Lambda_2$ and $\Lambda_3$, and we want to simulate an exit time and
an exit state (that is either 1, 2 or 3). This can be done in two
slightly different ways:
\begin{enumerate}
\item First time, then state:
  \begin{enumerate}
  \item Compute the survival function, $S(t) =
    \exp\bigl(-\Lambda_1(t)-\Lambda_2(t)-\Lambda_3(t)\bigr)$
  \item Simulate a random U(0,1) variate, $u$, say.
  \item The simulated exit time is then the solution $t_u$ to
    the equation $S(t_u) = u \quad \Leftrightarrow \quad \sum_j\Lambda_j(t_u) = -\log(u)$.
  \item A simulated transition at $t_u$ is then found by simulating a
    random draw from the multinomial distribution with probabilities
    $p_i=\lambda_i(t_u) / \sum_j\lambda_j(t_u)$.
  \end{enumerate}
\item Separate cumulative incidences:
  \begin{enumerate}
  \item Simulate 3 independent U(0,1) random variates $u_1$, $u_2$ and $u_3$.
  \item Solve the equations $\Lambda_i(t_i)=-\log(u_i), i=1,2,3$ and get $(t_1,t_2,t_3)$.
  \item The simulated survival time is then $\min(t_1,t_2,t_3)$, and
    the simulated transition is to the state corresponding to this,
    that is $k \in \{1,2,3\}$, where $t_k=\min(t_1,t_2,t_3)$
  \end{enumerate}
\end{enumerate}
The intuitive argument is that with three possible transition there are
3 independent processes running, but only the first transition is observed.
The latter approach is used in the implementation in \texttt{simLexis}.

The formal argument for the equality of the two approaches goes as
follows:
\begin{enumerate}
\item Equality of the transition times:
  \begin{enumerate}
  \item In the first approach we simulate from a distribution with
    cumulative rate $\Lambda_1(t)+\Lambda_2(t)+\Lambda_3(t)$, hence
    from a distribution with survival function:
    \begin{align*}
    S(t) & = \exp\bigl(-(\Lambda_1(t)+\Lambda_2(t)+\Lambda_3(t))\bigr) \\
         & = \exp\bigl(-\Lambda_1(t)\bigr)\times
             \exp\bigl(-\Lambda_2(t)\bigr)\times
             \exp\bigl(-\Lambda_3(t)\bigr)
    \end{align*}
  \item In the second approach we choose the smallest of three
    independent survival times, with survival functions
    $\exp(-\Lambda_i), i=1,2,3$. Now, the survival function for the
    minimum of three independent survival times is:
    \begin{align*}
      S_\text{min}(t) & = \pmat{\min(t_1,t_2,t_3)>t} \\
                     & = \pmat{t_1>t} \times
                         \pmat{t_2>t} \times
                         \pmat{t_3>t} \\
                     & = \exp\bigl(-\Lambda_1(t)\bigr)\times
                         \exp\bigl(-\Lambda_2(t)\bigr)\times
                         \exp\bigl(-\Lambda_3(t)\bigr)
    \end{align*}
    which is the same survival function as derived above.
  \end{enumerate}
\item Type of transition:
  \begin{enumerate}
  \item In the first instance the probability of a transition to state
    $i$, conditional on the transition time being $t$, is as known
    from standard probability theory:
    $\lambda_i(t)/\bigl(\lambda_1(t)+\lambda_2(t)+\lambda_3(t)\bigr)$.
  \item In the second approach we choose the transition corresponding
    to the the smallest of the transition times. So when we condition
    on the event that a transition takes place at time $t$, we have to
    show that the conditional probability that the smallest of the
    three simulated transition times was actually the $i$th, is as above.

    But conditional on \emph{survival} till $t$, the probabilities
    that events of type $1,2,3$ takes place in the interval $(t,t+\dif
    t)$ are $\lambda_1(t)\dif t$, $\lambda_2(t)\dif t$ and
    $\lambda_1(t)\dif t$, respectively (assuming that the probability
    of more than one event in the interval of length $\dif t$ is
    0). Hence the conditional probabilities \emph{given a transition
      time} in $(t,t+\dif t)$ is:
    \[
    \frac{\lambda_i(t)\dif t}{\lambda_1(t)\dif t+\lambda_2(t)\dif t+\lambda_3(t)\dif t}=
    \frac{\lambda_i(t)}{\lambda_1(t)+\lambda_2(t)+\lambda_3(t)}
    \]
    --- exactly as above.
  \end{enumerate}
\end{enumerate}

\section{Components of \texttt{simLexis}}

This section explains the actually existing code for
\texttt{simLexis}, as it is in the current version of \texttt{Epi}.

% The following code sources the originally formatted code in
% simLexis.R in order to make it printable with all the formatting and
% comments in it. However the sourcing does not work when compiling
% the vignettes in R CMD build. So when checking the code we comment
% this out by putting eval=FALSE, and moreover, because it is only
% simLexis that is exported, we also need to bring the functions simX,
% sim1, lint, get.next and chop.lex into the workspace. So depending
% on whether we actually construct the pdf for the inst/doc folder or
% test (upload) the package, one of the following to chunks are run
% with eval=FALSE and the other with eval=TRUE

% When compiling the published vignette
% When checking the package
The function \texttt{simLexis} takes a \texttt{Lexis} object as
input. This defines the initial state(s) and times of the start for a
number of persons. Since the purpose is to simulate a history through
the estimated multistate model, the input values of the outcome
variables \texttt{lex.Xst} and \texttt{lex.dur} are ignored --- the
aim is to simulate values for them.

Note however that the attribute \texttt{time.since} must be present in the
object. This is used for initializing timescales defined as time since
entry into a particular state, it is a character vector of the same
length as the \texttt{time.scales} attribute, with value equal to a
state name if the corresponding time scale is defined as time since
entry into that state. In this example the 4th timescale is time since
entry into the \texttt{Ins} state, and hence:
\begin{Schunk}
\begin{Sinput}
> cbind(
+ attr( ini, "time.scales" ),
+ attr( ini, "time.since" ) )
\end{Sinput}
\begin{Soutput}
     [,1]    [,2] 
[1,] "Per"   ""   
[2,] "Age"   ""   
[3,] "DMdur" ""   
[4,] "t.Ins" "Ins"
\end{Soutput}
\end{Schunk}
\texttt{Lexis} objects will have this attribute set for time scales created
using \texttt{cutLexis}.

The other necessary argument is a transition object \texttt{Tr}, which
is a list of lists. The elements of the lists should be \texttt{glm}
objects derived by fitting Poisson models to a \texttt{Lexis} object
representing follow-up data in a multistate model.  It is assumed (but
not checked) that timescales enter in the model via the timescales of
the \texttt{Lexis} object. Formally, there are no assumptions about
how \texttt{lex.dur} enters in the model.

Optional arguments are \texttt{t.range}, \texttt{n.int} or
\texttt{time.pts}, specifying the times after entry at which the
cumulative rates will be computed (the maximum of which will be taken
as the censoring time), and \texttt{N} a scalar or numerical vector of
the number of persons with a given initial state each record of the
\texttt{init} object should represent.

The central part of the functions uses a \texttt{do.call} /
\texttt{lapply} / \texttt{split} construction to do simulations for
different initial states. This is the construction in the middle that
calls \texttt{simX}. \texttt{simLexis} also calls \texttt{get.next}
which is further detailed below.
\begin{Schunk}
\begin{Sinput}
> simLexis
\end{Sinput}
\begin{Soutput}
function (Tr, init, N = 1, lex.id, t.range = 20, n.int = 101, 
    time.pts = seq(0, t.range, length.out = n.int)) 
{
    if (time.pts[1] != 0) 
        stop("First time point must be 0, time.pts[1:3]= ", time.pts[1:3])
    if (!missing(N)) {
        if (length(N) == 1) 
            init <- init[rep(1:nrow(init), each = N), ]
        else init <- init[rep(1:nrow(init), N), ]
    }
    if (!missing(lex.id)) {
        if (length(lex.id) == nrow(init)) 
            init$lex.id <- lex.id
        else init$lex.id <- 1:nrow(init)
    }
    else init$lex.id <- 1:nrow(init)
    if (is.null(tS <- attr(init, "time.scales"))) 
        stop("No time.scales attribute for init")
    if (is.null(tF <- attr(init, "time.since"))) {
        attr(init, "time.since") <- tF <- rep("", tS)
        warning("'time.since' attribute set to blanks")
    }
    np <- length(time.pts)
    tr.st <- names(Tr)
    sf <- NULL
    nxt <- init[init$lex.Cst %in% tr.st, ]
    if (nrow(nxt) < nrow(init)) {
        tt <- table(init$lex.Cst)
        tt <- tt[tt > 0]
        nt <- length(tt)
        warning("\nSome initiators start in a absorbing state\n", 
            "Initiator states represented are: ", paste(rbind(names(tt), 
                rep(":", nt), paste(tt), rep(" ", nt)), collapse = ""), 
            "\n", "Transient states are: ", paste(names(Tr), 
                coll = " "))
        if (nrow(nxt) == 0) 
            stop("\nNo initiators in transient states!")
    }
    while (nrow(nxt) > 0) {
        nx <- do.call(rbind.data.frame, lapply(split(nxt, nxt$lex.Cst), 
            simX, Tr, time.pts, tS))
        sf <- rbind.data.frame(sf, nx)
        nxt <- get.next(nx, tr.st, tS, tF)
    }
    sf$lex.Xst <- factor(sf$lex.Xst, levels = levels(sf$lex.Cst))
    sf$lex.Xst[is.na(sf$lex.Xst)] <- sf$lex.Cst[is.na(sf$lex.Xst)]
    nord <- match(c("lex.id", tS, "lex.dur", "lex.Cst", "lex.Xst"), 
        names(sf))
    noth <- setdiff(1:ncol(sf), nord)
    sf <- sf[order(sf$lex.id, sf[, tS[1]]), c(nord, noth)]
    rownames(sf) <- NULL
    attr(sf, "time.scales") <- tS
    attr(sf, "time.since") <- tF
    chop.lex(sf, tS, max(time.pts))
}
<bytecode: 0xd109cf0>
<environment: namespace:Epi>
\end{Soutput}
\end{Schunk}

\subsection{\texttt{simX}}

\texttt{simX} is called by \texttt{simLexis} and simulates
transition-times and -types for a set of patients assumed to be in the
same state. It is called from \texttt{simLexis} with a data frame as
argument, uses the state in \texttt{lex.Cst} to select the relevant
component of \texttt{Tr} and compute predicted cumulative intensities
for all states reachable from this state.

Note that it is here the switch between \texttt{glm}, \texttt{coxph}
and objects of class \texttt{function} is made.

The dataset on which this prediction is done has
\texttt{length(time.pts)} rows per person.
\begin{Schunk}
\begin{Sinput}
> simX
\end{Sinput}
\begin{Soutput}
function (nd, Tr, time.pts, tS) 
{
    np <- length(time.pts)
    nr <- nrow(nd)
    if (nr == 0) 
        return(NULL)
    cst <- as.character(unique(nd$lex.Cst))
    if (length(cst) > 1) 
        stop("More than one lex.Cst present:\n", cst, "\n")
    prfrm <- nd[rep(1:nr, each = np), ]
    prfrm[, tS] <- prfrm[, tS] + rep(time.pts, nr)
    prfrm$lex.dur <- il <- min(diff(time.pts))
    prfrp <- prfrm
    prfrp[, "lex.dur"] <- 1
    prfrp[, tS] <- prfrp[, tS] + il/2
    rt <- data.frame(lex.id = prfrm$lex.id)
    for (i in 1:length(Tr[[cst]])) {
        if (inherits(Tr[[cst]][[i]], "glm")) 
            rt <- cbind(rt, predict(Tr[[cst]][[i]], type = "response", 
                newdata = prfrp) * il)
        else if (inherits(Tr[[cst]][[i]], "coxph")) 
            rt <- cbind(rt, predict(Tr[[cst]][[i]], type = "expected", 
                newdata = prfrm))
        else if (is.function(Tr[[cst]][[i]])) 
            rt <- cbind(rt, Tr[[cst]][[i]](prfrm))
        else stop("Invalid object supplied as transition, elements of the list must be either:\n", 
            "- a glm(poisson) object fitted to a Lexis object\n", 
            "- a coxph object fitted to a Lexis object\n", "- a function that takes a Lexis object as argument and returns\n", 
            "  average rates for each record in the same units as lex.dur.")
    }
    names(rt)[-1] <- names(Tr[[cst]])
    xx <- match(c("lex.dur", "lex.Xst"), names(nd))
    if (any(!is.na(xx))) 
        nd <- nd[, -xx[!is.na(xx)]]
    merge(nd, do.call(rbind, lapply(split(rt, rt$lex.id), sim1, 
        time.pts)), by = "lex.id")
}
<bytecode: 0xc665600>
<environment: namespace:Epi>
\end{Soutput}
\end{Schunk}
As we see, \texttt{simX} calls \texttt{sim1} which simulates the
transition for one person.

\subsection{\texttt{sim1}}

The predicted cumulative intensities are fed, person by person, to
\texttt{sim1} --- again via a \texttt{do.call} / \texttt{lapply} /
\texttt{split} construction --- and the resulting time and state is
appended to the \texttt{nd} data frame. This way we have simulated
\emph{one} transition (time and state) for each person:
\begin{Schunk}
\begin{Sinput}
> sim1
\end{Sinput}
\begin{Soutput}
function (rt, time.pts) 
{
    ci <- apply(rbind(0, rt[, -1, drop = FALSE]), 2, cumsum)[1:nrow(rt), 
        , drop = FALSE]
    tt <- uu <- -log(runif(ncol(ci)))
    for (i in 1:ncol(ci)) tt[i] <- lint(ci[, i], time.pts, uu[i])
    data.frame(lex.id = rt[1, 1], lex.dur = min(tt, na.rm = TRUE), 
        lex.Xst = factor(if (min(tt) < max(time.pts)) 
            colnames(ci)[tt == min(tt)]
        else NA))
}
<bytecode: 0xc672ce0>
<environment: namespace:Epi>
\end{Soutput}
\end{Schunk}
The \texttt{sim1} function uses \texttt{lint} to do linear interpolation.

\subsection{\texttt{lint}}

We do not use \texttt{approx} to do the linear interpolation, because
this function does not do the right thing if the cumulative incidences
(\texttt{ci}) are constant across a number of times. Therefore we have
a custom made linear interpolator that does the interpolation
exploiting the fact the the \texttt{ci} is non-decreasing and
\texttt{tt} is strictly monotonously increasing:
\begin{Schunk}
\begin{Sinput}
> lint
\end{Sinput}
\begin{Soutput}
function (ci, tt, u) 
{
    if (any(diff(ci) < 0) | any(diff(tt) < 0)) 
        stop("Non-increasing arguments")
    c.u <- min(c(ci[ci > u], max(ci)))
    c.l <- max(c(ci[ci < u], min(ci)))
    t.u <- min(c(tt[ci > u], max(tt)))
    t.l <- max(c(tt[ci < u], min(tt)))
    ifelse(c.u == c.l, t.l, t.l + (u - c.l)/(c.u - c.l) * (t.u - 
        t.l))
}
<bytecode: 0x1c65a850>
<environment: namespace:Epi>
\end{Soutput}
\end{Schunk}

\subsection{\texttt{get.next}}

We must repeat the simulation operation on those that have a simulated
entry to a transient state, and also make sure that any time scales
defined as time since entry to one of these states be initialized to 0
before a call to \texttt{simX} is made for these persons. This
accomplished by the function \texttt{get.next}:
\begin{Schunk}
\begin{Sinput}
> get.next
\end{Sinput}
\begin{Soutput}
function (sf, tr.st, tS, tF) 
{
    if (nrow(sf) == 0) 
        return(sf)
    nxt <- sf[sf$lex.Xst %in% tr.st, ]
    if (nrow(nxt) == 0) 
        return(nxt)
    nxt[, tS] <- nxt[, tS] + nxt$lex.dur
    wh <- tF
    for (i in 1:length(wh)) if (wh[i] != "") 
        nxt[nxt$lex.Xst == wh[i], tS[i]] <- 0
    nxt$lex.Cst <- nxt$lex.Xst
    return(nxt)
}
<bytecode: 0x35330990>
<environment: namespace:Epi>
\end{Soutput}
\end{Schunk}

\subsection{\texttt{chop.lex}}

The operation so far has censored individuals \texttt{max(time.pts)}
after \emph{each} new entry to a transient state. In order to groom
the output data we use \texttt{chop.lex} to censor all persons at the
same designated time after \emph{initial} entry.
\begin{Schunk}
\begin{Sinput}
> chop.lex
\end{Sinput}
\begin{Soutput}
function (obj, tS, cens) 
{
    zz <- entry(obj, 1, by.id = TRUE)
    ww <- merge(obj, data.frame(lex.id = as.numeric(names(zz)), 
        cens = zz + cens))
    ww <- ww[ww[, tS[1]] < ww$cens, ]
    x.dur <- pmin(ww$lex.dur, ww[, "cens"] - ww[, tS[1]])
    ww$lex.Xst[x.dur < ww$lex.dur] <- ww$lex.Cst[x.dur < ww$lex.dur]
    ww$lex.dur <- pmin(x.dur, ww$lex.dur)
    ww
}
<bytecode: 0x15277c90>
<environment: namespace:Epi>
\end{Soutput}
\end{Schunk}

\section{Probabilities from simulated \texttt{Lexis} objects}

Once we have simulated a Lexis object we will of course want to use it
for estimating probabilities, so basically we will want to enumerate
the number of persons in each state at a pre-specified set of time
points.

\subsection{\texttt{nState}}

Since we are dealing with multistate model with potentially multiple
time scales, it is necessary to define the timescale
(\texttt{time.scale}), the starting point on this timescale
(\texttt{from}) and the points after this where we compute the number
of occupants in each state, (\texttt{at}).
\begin{Schunk}
\begin{Sinput}
> nState
\end{Sinput}
\begin{Soutput}
function (obj, at, from, time.scale = 1) 
{
    tS <- check.time.scale(obj, time.scale)
    TT <- tmat(obj)
    absorb <- rownames(TT)[apply(!is.na(TT), 1, sum) == 0]
    transient <- setdiff(rownames(TT), absorb)
    tab.frm <- obj[rep(1:nrow(obj), each = length(at)), c(tS, 
        "lex.dur", "lex.Cst", "lex.Xst")]
    tab.frm$when <- rep(at, nrow(obj)) + from
    tab.tr <- tab.frm[tab.frm[, tS] <= tab.frm$when & tab.frm[, 
        tS] + tab.frm$lex.dur > tab.frm$when, ]
    tab.tr$State <- tab.tr$lex.Cst
    tab.ab <- tab.frm[tab.frm[, tS] + tab.frm$lex.dur <= tab.frm$when & 
        tab.frm$lex.Xst %in% absorb, ]
    tab.ab$State <- tab.ab$lex.Xst
    with(rbind(tab.ab, tab.tr), table(when, State))
}
<bytecode: 0x1bac06d8>
<environment: namespace:Epi>
\end{Soutput}
\end{Schunk}

\subsection{\texttt{pState}, \texttt{plot.pState} and \texttt{lines.pState}}

In order to plot probabilities of state-occupancy it is useful to
compute cumulative probabilities across states in any given order;
this is done by the function \texttt{pState}, which returns a matrix
of class \texttt{pState}:
\begin{Schunk}
\begin{Sinput}
> pState
\end{Sinput}
\begin{Soutput}
function (nSt, perm = 1:ncol(nSt)) 
{
    tt <- t(apply(nSt[, perm], 1, cumsum))
    tt <- sweep(tt, 1, tt[, ncol(tt)], "/")
    class(tt) <- c("pState", "matrix")
    tt
}
<bytecode: 0x15d9f738>
<environment: namespace:Epi>
\end{Soutput}
\end{Schunk}
There is also a \texttt{plot} and \texttt{lines} method for the
resulting \texttt{pState} objects:
\begin{Schunk}
\begin{Sinput}
> plot.pState
\end{Sinput}
\begin{Soutput}
function (x, col = rainbow(ncol(x)), border = "transparent", 
    xlab = "Time", ylim = 0:1, ylab = "Probability", ...) 
{
    matplot(as.numeric(rownames(x)), x, type = "n", ylim = ylim, 
        yaxs = "i", xaxs = "i", xlab = xlab, ylab = ylab, ...)
    lines.pState(x, col = col, border = border, ...)
}
<bytecode: 0x37e074f0>
<environment: namespace:Epi>
\end{Soutput}
\begin{Sinput}
> lines.pState
\end{Sinput}
\begin{Soutput}
function (x, col = rainbow(ncol(x)), border = "transparent", 
    ...) 
{
    nc <- ncol(x)
    col <- rep(col, nc)[1:nc]
    border <- rep(border, nc)[1:nc]
    pSt <- cbind(0, x)
    for (i in 2:ncol(pSt)) {
        polygon(c(as.numeric(rownames(pSt)), rev(as.numeric(rownames(pSt)))), 
            c(pSt[, i], rev(pSt[, i - 1])), col = col[i - 1], 
            border = border[i - 1], ...)
    }
}
<bytecode: 0x3755c4c0>
<environment: namespace:Epi>
\end{Soutput}
\end{Schunk}

\bibliographystyle{plain}
\begin{thebibliography}{1}

\bibitem{Carstensen.2011a}
B~Carstensen and M~Plummer.
\newblock Using {L}exis objects for multi-state models in {R}.
\newblock {\em Journal of Statistical Software}, 38(6):1--18, 1 2011.

\bibitem{Iacobelli.2013}
S~Iacobelli and B~Carstensen.
\newblock {Multiple time scales in multi-state models}.
\newblock {\em Stat Med}, 32(30):5315--5327, Dec 2013.

\bibitem{Plummer.2011}
M~Plummer and B~Carstensen.
\newblock Lexis: An {R} class for epidemiological studies with long-term
  follow-up.
\newblock {\em Journal of Statistical Software}, 38(5):1--12, 1 2011.

\end{thebibliography}

\addcontentsline{toc}{chapter}{References}

\end{document}
