msm/0000755000176200001440000000000014124311712011042 5ustar liggesusersmsm/NAMESPACE0000644000176200001440000000446713430246770012306 0ustar liggesusersuseDynLib(msm) export( absorbing.msm, boot.msm, coef.msm, contour.msm, crudeinits.msm, deltamethod, draic.msm, drlcv.msm, efpt.msm, ematrix.msm, envisits.msm, hazard.msm, image.msm, MatrixExp, msm, msm2Surv, msm.form.qoutput, msm.form.eoutput, logLik.msm, lrtest.msm, odds.msm, pearson.msm, persp.msm, phasemeans.msm, plot.msm, plotprog.msm, pmatrix.msm, pmatrix.piecewise.msm, pnext.msm, ppass.msm, plot.prevalence.msm, plot.survfit.msm, prevalence.msm, printold.msm, printnew.msm, qmatrix.msm, qratio.msm, recreate.olddata, scoreresid.msm, sim.msm, simmulti.msm, simfitted.msm, sojourn.msm, statetable.msm, summary.msm, surface.msm, totlos.msm, transient.msm, updatepars.msm, viterbi.msm, hmmCat, hmmIdent, hmmUnif, hmmNorm, hmmLNorm, hmmExp, hmmGamma, hmmWeibull, hmmPois, hmmBinom, hmmBetaBinom, hmmTNorm, hmmMETNorm, hmmMEUnif, hmmNBinom, hmmBeta, hmmT, hmmMV, dtnorm, ptnorm, qtnorm, rtnorm, dmenorm, pmenorm, qmenorm, rmenorm, dmeunif, pmeunif, qmeunif, rmeunif, dpexp, ppexp, qpexp, rpexp, qgeneric, d2phase, p2phase, q2phase, r2phase, h2phase ) importFrom(graphics, plot) importFrom(graphics, persp) importFrom(graphics, contour) importFrom(graphics, image) importFrom(stats, coef) importFrom(mvtnorm, rmvnorm) importFrom(survival, Surv) importFrom(survival, survfit) importFrom(expm, expm) S3method(print, msm) S3method(summary, msm) S3method(plot, msm) S3method(contour, msm) S3method(persp, msm) S3method(image, msm) S3method(coef, msm) S3method(logLik, msm) S3method(model.frame, msm) S3method(model.matrix, msm) S3method(print, hmodel) S3method(print, hmmdist) S3method(print, hmmMVdist) S3method(print, msm.est) S3method("[", msm.est) S3method(print, pearson.msm) S3method(plot, prevalence.msm) S3method(plot, survfit.msm) importFrom("grDevices", "rainbow") importFrom("graphics", "filled.contour", "legend", "lines", "par", "text") importFrom("stats", "as.formula", "deriv", "dexp", "dnorm", "integrate", "logLik", "model.extract", "model.frame", "model.matrix", "na.fail", "na.omit", "na.pass", "numericDeriv", "optimHess", "pchisq", "pexp", "plogis", "pnorm", "qlogis", "qnorm", "quantile", "rbeta", "rbinom", "reformulate", "rexp", "rgamma", "rlnorm", "rnbinom", "rnorm", "rpois", "rt", "runif", "rweibull", "sd", "setNames", "terms", "uniroot") msm/ChangeLog0000644000176200001440000022675013066541173012642 0ustar liggesusers2016-11-02 THIS FILE IS NO LONGER MAINTAINED. Detailed changes are visible through the commits on https://github.com/chjackson/msm 2016-10-19 Chris Jackson * Bug fix to prevalence.msm with factor subject IDs 2016-10-02 Chris Jackson * Vignette sources moved from "src/doc" to "vignettes" on CRAN request. * DESCRIPTION: Version 1.6.4 released to CRAN and r-forge 2016-06-03 Chris Jackson * R/utils.R: Bug fix for qtnorm with vectorised arguments. Thanks to James Gibbons for the report. * DESCRIPTION: Version 1.6.3 released to r-forge. 2016-03-09 Chris Jackson * R/pearson.R: Bug fix for dropping censored states. Thanks to Casimir Sofeu for the report. * DESCRIPTION: Version 1.6.2 released to r-forge. 2016-03-09 Chris Jackson * DESCRIPTION: Version 1.6.1 released to CRAN. 2016-03-07 Chris Jackson * tests: tests updated to work with the development version of testthat. 2016-02-18 Chris Jackson * src/lik.c,R/msm.R: Bug fix and documentation clarification for models with "obstrue" and "ematrix". * R/draic.R: Bug fix for initprobs, and only allow expected information if all panel data. * R/msm.R: Bug fix for printing CIs with pci and all fixedpars. * DESCRIPTION: Version 1.6.1 released to r-forge. 2015-11-17 Chris Jackson * DESCRIPTION: Version 1.6 released to r-forge and CRAN. 2015-11-10 Chris Jackson * src/lik.c: Several bug fixes in calculation of the derivatives for multivariate HMMs. * R/msm.R(msm.form.obstrue): Better detection of when obstrue is supplied as an indicator or a true state + NA. 2015-10-07 Chris Jackson * R/outputs.R(msm.form.qoutput): Bug fix for printing model output when only one transition rate is affected by covariates. Thanks to Jordi Blanch for the report. 2015-09-14 Chris Jackson * src/lik.c: More underflow correction for probabilities of hidden states in viterbi.msm. Thanks to Hannah Linder for the report. * R/msm.R: "death" argument in msm() is deprecated and renamed to "deathexact". * R/msm.R: censor.states now defaults to all transient states if not supplied, instead of complaining, even if there is no absorbing state. Thanks to Jonathan Williams for the report. * DESCRIPTION: Version 1.5.3 released to r-forge. 2015-04-10 Chris Jackson * R/msm.R(statetable.msm): Code simplified, now row names work with factor states. 2015-02-17 Chris Jackson * DESCRIPTION: Version 1.5.2 released to r-forge. 2015-02-10 Chris Jackson * R/msm.R, src/lik.c: obstrue can now contain the actual true state, instead of an indicator. This allows the information from HMM outcomes generated conditionally on this state to be included in the model. * R/msm.R(na.find.msmdata): Fix of bug in na.find.msmdata that could lead to NAs being passed through to C and causing a crash. Triggered when state or time were NA and there were covariates. 2015-02-09 Chris Jackson * R/hmm-dists.R(hmmDIST): Fix of bug when HMM parameters come from named vectors. 2015-01-29 Chris Jackson * R/outputs.R(msm.form.qoutput) Bug fix in printing fitted model objects. 2015-01-16 Chris Jackson * hmm.R: "links" component dropped from hmodel objects, as it is no longer used. * simul.R: "keep" component added to simmulti.msm result. * R/hmm.R and others: Multivariate observations in HMMs with different models for each variable. Limited testing so far. 2015-01-15 Chris Jackson * Correct version of the built vignette restored to the package (1.5 instead of 1.3.2). * Experimental feature: multivariate observations in HMMs. Start by supporting multiple outcomes from the same distribution at the same time, with the data supplied as a matrix. * DESCRIPTION: Version 1.5.1 released to r-forge. 2015-01-05 Chris Jackson * DESCRIPTION: Version 1.5 released to CRAN. 2014-12-12 Chris Jackson * R/msm.R,R/phase.R. Phase type models now allow HMM on top. Bug fixes to these models. * DESCRIPTION: Version 1.4.3 released to r-forge. 2014-12-11 Chris Jackson * Posterior probability of the hidden state at each time in the Viterbi algorithm now conditions on all the data. * R/msm.R,R/outputs.R(various): Bug fixes to misclassification models where some states were misclassified as other states with probability 1, for both ematrix and hmmCat specifications. Thanks to Li Su for the report. * DESCRIPTION: Version 1.4.2 released to r-forge. 2014-12-10 Chris Jackson * src/lik.c, R/outputs.R: Viterbi algorithm now also returns the probability of each hidden state at each time given the data up to that point. * data/msmdata.rda: statemax added to CAV data. * man: Document that generic AIC function AIC() works for msm models. * DESCRIPTION: Version 1.4.1 released to r-forge. 2014-12-08 Chris Jackson * R/phase.R,R/msm.R,Rd/2phase.Rd: New features for phase-type models. 2014-12-04 Chris Jackson * R/draic.R: Bug fixes in drlcv.msm (likelihood of big model on left-one-out subject was using the original instead of the refitted model, and used covariate centering inconsistently). Thanks to Howard Thom. 2014-12-02 Chris Jackson * R/msm.R(msm.initprobs2mat,msm.form.houtput): Bug fixes for covariates on initial state occupancy probabilities with structural zeros in. Thanks to Jeffrey Eaton and Tara Mangal. * R/msm.R(msm.form.output): Clean up code, also ensure models fitted with 1.4 can be printed with 1.4.1. 2014-11-27 Chris Jackson * R/draic.R: Bug fix in "prob > 0" in drlcv.msm. Thanks to Howard Thom. * R/msm.R: colSums efficiency improvement in msm.add.qcovs, msm.form.dq. Thanks to Jeffrey Eaton. 2014-11-19 Chris Jackson * R/outputs.R: Allow qmatrix to be passed to pmatrix.msm, and a list of qmatrices to pmatrix.piecewise.msm, instead of a fitted model. 2014-11-18 Chris Jackson * R/outputs.R: qmatrix.msm and related functions tidied up. * R/outputs.R,R/msm.R: Don't print CIs for fixed parameters in output formatting functions. * R/msm.R: Warn that polynomial contrasts aren't supported. 2014-11-11 Chris Jackson * src/pijt.c(MatrixExpEXPM): give error if optimiser has chosen overflowing parameter values. Stops infinite loops seen on Windows. 2014-11-10 Chris Jackson * R/msm.R: Documentation and error message for factor states. 2014-10-31 Chris Jackson * R/outputs.R(efpt.msm): Support tostate as character. * man/plot.survfit.msm: Reference Turnbull method. * src/lik.c(GetCensored): Fixed valgrind uninitialized value warning. 2014-09-22 Chris Jackson * R/optim.R(deriv.test): require namespace instead of loading numDeriv 2014-07-04 Chris Jackson * src/analyticp.c: memory leaks removed. 2014-07-04 Chris Jackson * DESCRIPTION: Version 1.4 released to CRAN. 2014-07-02 Chris Jackson * R/outputs.R: Default CI method for pnext.msm changed to "normal", since delta method may not respect probability <1 constraint. 2014-06-23 Chris Jackson * C interface changed from .C to .Call. * Added ppass.msm for passage probabilites. * DESCRIPTION: Version 1.3.3 released to r-forge. 2014-06 Chris Jackson * src/lik.c: Bug fix in infosimple: info was not being initialized at zero, leading to occasional random output. * DESCRIPTION: Version 1.3.2 released to r-forge. 2014-06 Chris Jackson * tests: Test suite tidied up and converted to use "testthat" package. * R/boot.R(efpt.ci.msm): Bug fix for bootstrap and efpt.msm. * src/lik.c(likhidden): Give informative warning for initial outcomes in HMMs which are impossible for given initial state probabilites and outcome models. Makes use of a global variable in a private environment called msm.globals. * draic.msm, drlcv.msm added. 2014-06 Chris Jackson * If msm is called with hessian=FALSE, then the Fisher (expected) information is used to obtain standard errors and CIs, which may be preferable if the observed Hessian is very intensive to approximate or its estimate is nonsingular / nonpositive-definite. 2014-05 Chris Jackson * Analytic derivatives available for most hidden Markov models and models with censored states (excluding unknown initial state probabilities, constraints on misclassification / categorical outcome probabilities and their covariates, and truncated or measurement error distributions). This should speed up optimisation with the BFGS or CG methods. The corresponding Fisher information matrix is also available for misclassification (categorical/identity outcome) models. * The BFGS optimisation method is now the default, rather than Nelder-Mead. 2014-05 Chris Jackson * msm.optim.fixed, msm.rep.constraints: Bug fix for constraints on misclassification probabilities and fixed parameters. 2014-05 Chris Jackson * msm.R(msm.mnlogit.transform): Bug fix: reapply sum to 1 constraint after applying constraints to baseline probabilities in HMMs. May affect results. 2014-05 Chris Jackson * hmm.R(msm.econstr2hconstr): internal constraints in misclassification models mapped to 1,2,... using match(constr, unique(constr)) 2014-05 Chris Jackson * msm.R(msm.unfixallparams): Don't unconstrain constraints, so derivatives of fully fixed models refer to constrained pars. 2014-05 Chris Jackson * Various help pages now document the objects and data structures used internally and returned by msm() in the fitted model object. 2014-04 Chris Jackson * msm.R and others: major rewrite of much of the internal code that deals with reading the data and passing it to models. This uses model frames and model formulae more efficiently. As a result the "data" component of the msm has a different structure: a list with one component "mf", the model frame, containing all original variables required for the model fit. This and related data structures can can be extracted with the new "model.frame.msm" and "model.matrix.msm" methods. * outputs.R: new print method now the default, and new functions msm.form.qoutput and msm.form.eoutput to produce the printed numbers in the same arrangement. * msm.R: Centering of "timeperiod" covariates in "pci" models is now done consistently with other covariates, i.e. with last observation omitted. * outputs.R(factorcov2numeric.msm): bug fix for misclassification covariates. * msm.R(crudeinits.msm): Times consistency check added. * msm.R(msm.check.model): Model consistency check error messages now report row numbers before missing data are omitted. * hmm.R(msm.form.hcmodel): Bug fix for when initial values for HMM covariate effects of wrong length, this should ignore and carry on. * pearson.R: Bug fix for when integral for accurate p-value doesn't converge. * lik.c: Don't recalculate P matrices for timelag / obstype / covariate combinations that occur more than once. This may speed up some hidden Markov or censoring models. 2014-04-11 Chris Jackson * msm.R(msm.form.params): Fix of bug which broke models with covariates on initial state occupancy. 2014-04-10 Chris Jackson * R/boot.R,R/outputs.R: Parallel processing using "doParallel" added for bootstrapping and bootstrap CIs. 2014-04-09 Chris Jackson * R/optim.R: Optimisation methods abstracted into their own functions. 2014-04-04 Chris Jackson * DESCRIPTION: Version 1.3.1 released to r-forge. 2014-04-03 Chris Jackson * R/msm.R(msm.add.qcovs,msm.add.dqcovs): Fix of drop=FALSE bug for data with only one transition. 2014-04-02 Chris Jackson * R/msm.R: Fix of obscure bug that broke some subject-specific likelihoods, caused by omitting obstype.obs from data object. 2014-04-01 Chris Jackson * R/outputs.R: Time-dependent covariates supported in totlos.msm. * R/outputs.R(envisits.msm, totlos.msm): New facility for expected number of visits. 2014-02-26 Chris Jackson * R/mstate.R,man/msm2Surv.Rd: New function for exporting data in counting process format for use with survival and mstate. 2014-02-25 Chris Jackson * R/msm.R: Handle convergence failure codes from optim(). 2014-02-20 Chris Jackson * R/outputs.R(mattotrans): printnew.msm fixed for 2-state models. Thanks to Martyn Plummer. 2014-01-15 Chris Jackson * DESCRIPTION: Version 1.3 released to CRAN. 2014-01-09 Chris Jackson * inst/doc/msm-manual.Rnw: Fixed error in analytic p13(t) in section 1.4. 2013-12-04 Chris Jackson * R/outputs.R: Experimental new print method available as printnew.msm. * srcR/pijt.c(MatrixExpPade): Fix for int coercion from special values, to pass CRAN UBSanitizer check. * src/analyticp.c: Some algebra rearranged to fix potential division by zeros. * src/analyticp.c, R/msm.R(msm.form.qmodel): Corrected permutation for Q matrix, fixing bug from 1.2.3 which broke models with non-standard state ordering. * R/outputs.R: New "start" argument to efpt.msm, allowing averaging over a set of starting states. * DESCRIPTION: Datasets now lazy loaded so data() not required. 2013-10-07 Chris Jackson * DESCRIPTION: Version 1.2.7 released to r-forge. 2013-10-04 Chris Jackson * R/outputs.R(observed.msm): Don't use Viterbi imputed states at change points when computing observed prevalences in "pci" models with piecewise-constant intensities. 2013-10-01 Chris Jackson * R/msm.R(msm.mninvlogit.transform): Fix for bug with misclassification models with only one misclassification probability. * src/lik.c: Match Q matrices with covariates from start of transition, not end, in likelihoods and derivatives by subject. 2013-09-13 Chris Jackson * R/msm.R: "missing" for some null default arguments in msm() changed to is.null. * DESCRIPTION: Version 1.2.6 released to r-forge. 2013-08-30 Chris Jackson * R/msm.R(msm.R): Give an informative error if trying to use gen.inits with a HMM, and document that this is not supported. 2013-08-20 Chris Jackson * R/msm.R(msm.check.times): Row numbers reported in error message about different states at the same time corrected to account for missing data. Thanks to Lucy Leigh for the report. 2013-07-30 Chris Jackson * R/outputs.R: formula for totlos.msm implemented, which is vastly more efficient than the numerical integration used previously. Debugging outputs left in 1.2.3 also removed. * R/msm.R, src/*.c: Likelihood calculations use expm from the expm package by default where matrix exponentiation is required. As a result msm now depends on the expm package. * R/utils.R: MatrixExp now uses expm from the expm package by default. * R/various: some fixes for bugs introduced by the range facility. * DESCRIPTION: Version 1.2.5 released to r-forge. 2013-07-22 Chris Jackson * R/(various): Range constraints can now be given for HMM outcome parameters, through a new argument "hranges" to msm(). This may improve HMM identifiability. Thanks to Soon-Ee Cheah for the suggestion. * R/constants.R: Scale parameters of Weibull and t HMM outcome distributions now restricted properly to be positive in estimation. * DESCRIPTION: Version 1.2.4 released to r-forge. 2013-07-04 Chris Jackson * R/utils.R: MatrixExp rewritten to use C code for series method and analytic solutions for Markov models, avoiding code duplication. 2013-07-02 Chris Jackson * R/msm.R: If available, loglikelihood derivatives, expected and (if requested) observed information are returned in paramdata component for all models. If all parameters fixed, these are over all parameters. If some are fixed, than these are just over the parameters that are optimised. * R/outputs.R: surface.msm fixed for models fitted with Fisher scoring. 2013-06-06 Chris Jackson * R/outputs.R: totlos.msm was calculating the wrong thing for fromt > 0. * DESCRIPTION: Version 1.2.3 released to r-forge. 2013-06-04 Chris Jackson * R/pearson.R: Corrected data rows mismatch in bootstrapping with imputed sampling times after deaths in Pearson statistic. * src/lik.c: Memory crash bug in Viterbi fixed. 2013-06-03 Chris Jackson * (Most R and C files): Major restructuring of the internals. Main change is to adjust all parameters for covariates in R rather than C, making for much tidier code. New R functions for applying transformations and inverse transformations. * src/pijt.c: Derivatives of the likelihood for non-hidden models now work properly with negative constraints. * R/msm.R: Initial state occupancy probabilities are estimated on the multivariate logit scale, rather than univariate logit, and confidence intervals are calculated using the normal simulation method. Probability for the baseline category "initpbase" is now a labelled parameter. * R/msm.R: When centering covariates around their means for the default likelihood calculation, the means used are now after dropping missing values and subjects with one observation, not before. Thanks to Howard Thom for the report. * Relatedly, the covariate values for subjects' last observations are not included in this mean, since they don't contribute to the likelihood, so interpretation of initial values for the qmatrix, and outputs for covariates="mean", will now be very slightly different. 2013-05-28 Chris Jackson * inst/doc/msm-manual.Rnw: Likelihood for exact times still had wrong sign for qii (see version 1.1.2). 2013-05-25 Chris Jackson * inst/doc/msm-manual.Rnw: Added advice about "function cannot be evaluated at initial parameters". 2013-05-24 Chris Jackson * R/msm.R: New interface for supplying different covariates on different transition intensities. * R/msm.R: Redundant constraint check and factor warning fixed and cleaned. 2013-05-23 Chris Jackson * R/msm.R(msm.form.covdata): checks on constraints and covinits separated into new functions. * R/msm.R(msm.form.covmodel): wrong names in error message for constraint length checking. 2013-05-21 Chris Jackson * R/msm.R(msm.form.data): Handle factor states (with levels 1:nstates) by converting to numeric. * R/msm.R, src/lik.c: Can now print subject-specific log-likelihoods at the MLE via logLik.msm(). * DESCRIPTION: Version 1.2.2 released to r-forge. 2013-05-19 Chris Jackson * R/utils.R: qtnorm, qmenorm, qmeunif and qpexp changed to use qgeneric. Their results should be the same. * R/utils.R: long-redundant identity function finally removed. 2013-05-18 Chris Jackson * R/utils.R: qgeneric function copied from flexsurv package and modified to handle argument clashes. * R/utils.R: Return NaN for all dpqr(tnorm,menorm,meunif) if lower bound greater than upper bound. 2013-05-17 Chris Jackson * R/msm.R: Don't warn if not all states observed in data for misclassification models (typo bugfix in msm.form.data). 2013-05-16 Chris Jackson * R/msm.R,R/hmm.R,src/lik.c: Allow matrix by patient to be supplied for the initial state occupancy probabilities. * DESCRIPTION: Version 1.2.1 released to r-forge. 2013-05-15 Chris Jackson * R/msm.R: move gen.inits from msm.form.qmodel to main function. 2013-05-14 Chris Jackson * DESCRIPTION: Version 1.2 released 2013-05-08 Chris Jackson * R/msm.R,R/outputs.R: Misclassification models where some off-diagonal misclassification probabilities are 1 are now handled properly. Thanks to Howard Thom for uncovering this. 2013-04-19 Chris Jackson * R/outputs.R: prevalence.msm can now produce expected values by integrating model predictions over the covariate histories observed in the data. * R/msm.R(msm.form.data): Drop subjects with only one observation remaining after dropping missing data (e.g. psor data). This gives a more appropriate measure of the numbers at risk in prevalence.msm. 2013-04-18 Chris Jackson * R/outputs.R(summary.msm): Allow arguments to be passed through summary.msm to prevalence.msm. * R/outputs.R(pmatrix.piecewise.msm): Allow this to be used for time-homogeneous models with change point vector "times" of length 0. 2013-04-15 Chris Jackson * R/outputs.R: New function efpt.msm for expected first passage times for time-homogeneous models. Thanks to Howard Thom for the research. * R/outputs.R: totlos.msm now passes options to integrate() to bootstrapping functions. 2013-04-10 Chris Jackson * R/msm.form.data: firstobs was wrong with missing data. 2013-04-08 Chris Jackson * R/simul.R, R/pearson.R: Function boot.param.msm renamed to simfitted.msm and made user-accessible. 2013-04-05 Chris Jackson * R/pearson.R: Accurate p-values from Titman (Lifetime Data Analysis, 2009). * R/pearson.R: Degrees of freedom were being calculated incorrectly (via "n.zerofrom" variable) when user-defined groups included from-states. * R/simul.R: Include an option to simmulti.msm (and getobs.msm) to not drop absorbing-absorbing transitions. 2013-03-22 Chris Jackson * R/pearson.R: Fix of bug in Pearson test introduced in version 0.9.5, which affected the expected transitions to the final state (and resulting test statistics) for panel data without exact death times. * src/lik.c, src/pijt.c: Implement the Fisher information for non-hidden models without censored states. * R/msm.R: Implement a Fisher scoring algorithm which uses this expected information. 2013-02-02 Chris Jackson * R/outputs.R(observed.msm): Add a censoring time facility to optionally remove subjects from the risk set a certain time after they have reached an absorbing state. Thanks to Andrew Titman. 2013-02-02 Chris Jackson * src/lik.c: Bug fix for Viterbi with obstrue. Thanks to Linda Sharples. * R/outputs.R(print.msm): Don't print message about baseline covariate values in misclassification model outputs if there are no covariates. 2013-01-14 Chris Jackson * R/outputs.R(observed.msm): Bug fix for interp="midpoint" method in observed prevalence calculation. Thanks to Erica Liu. 2012-12-10 Chris Jackson * tests/simple.R: Modified pmatrix.msm normal bootstrap test output to work with new seeding behaviour of rmvnorm. * DESCRIPTION: Version 1.1.4 released 2012-09-28 Chris Jackson * src/doc: Remember to copy the up-to-date manual source into src for new releases, as required by Linux distribution package builders. * DESCRIPTION: Version 1.1.3 released 2012-09-27 Chris Jackson * inst/doc/msm-manual.Rnw: Work around texi2dvi problem where non-breaking spaces appear as tildes. 2012-09-25 Chris Jackson * R/outputs.R(qematrix.msm): Bug fix for user-supplied covariate values when center=FALSE. Thanks to Vikki O'Neill for the report. 2012-09-24 Chris Jackson * man/boot.msm.Rd: Documented failure of boot.msm to handle user-defined objects that clash with built-in objects. 2012-09-21 Chris Jackson * R/msm.R: Use BFGS method for one-parameter optimisation unless method supplied explicitly, avoiding warning about unreliability of Nelder-Mead. 2012-07-31 Chris Jackson * R/pearson.R: Browser was still on for pearson.msm. Thanks to Chyi-Hung Hsu. * DESCRIPTION: Version 1.1.2 released 2012-05-28 Chris Jackson * (various files): New Student t distribution for hidden Markov model outcomes. Thanks to Darren Gillis. 2012-05-11 Chris Jackson * R/msm.R(msm.check.times): Bug fix in data consistency checks with unsorted subject IDs. Thanks to Kelly Williams-Sieg for the report. * DESCRIPTION: Version 1.1.1 released 2012-05-01 Chris Jackson * R/utils.R: Corner cases in qtnorm fixed. Thanks to Art Owen for the report. * R/boot.R: Multicore functionality removed from this release since doSMP was removed from CRAN. Will restore when a stable preferred cross-platform solution emerges. 2012-01-31 Chris Jackson * R/pearson.R: Bug fix for models where transitions are only allowed from one state. Thanks to Gavin Chan for the report. 2012-01-31 Chris Jackson * R/msm.R: If user supplies an ematrix with all misclassification probabilities zero, the non-misclassification model is fitted. Thanks to Sharareh Taghipour for the report. * R/msm.R(msm.check.model): Bug fix for error messages when model inconsistent with data. 2011-11-28 Chris Jackson * R/boot.R: boot.msm and functions which use this can now use doSMP to parallelise calculations. 2011-11-25 Chris Jackson * R/boot.R: Fix of bug which affected calculation of confidence intervals by the "normal" method when there were fixed parameters or HMMs. 2011-10-27 Chris Jackson * R/outputs.R: Bug fix: Subset function "[.msm.est" was labelling columns wrong for objects with no SE component (pmatrix.msm, pnext.msm). 2011-09-09 Chris Jackson * DESCRIPTION: Version 1.1 released 2011-07-25 Chris Jackson * R/outputs.R: New function "[.msm.est" to extract specific rows and columns of the output from, e.g., qmatrix.msm() in a more intuitive way. 2011-07-24 Chris Jackson * R/outputs.R: New function "pnext.msm" to compute a matrix of probabilities for the next state of the process. 2011-07-07 Chris Jackson * man/msm.Rd: Doc clarifies that "death" is overridden by "obstype" and "exacttimes", and "exacttimes" is overridden by "obstype". 2011-06-09 Chris Jackson * man/msm.Rd: Correct documentation for factor levels of "timeperiod". * R/outputs.R(qematrix.msm): Fix CIs for diagonal entries when first state is absorbing. * R/msm.R(msm.check.model): Refer to observation numbers, not transition numbers, in "data inconsistent with model" error message. 2011-05-26 Chris Jackson * DESCRIPTION: Version 1.0.1 released 2011-05-20 Chris Jackson * R/outputs.R(msm.fill.pci.covs): Bug fix, pmatrix.msm would break for models with non-integer time change points "pci". Thanks to Christos Argyropoulos for the report. * man/prevalence.msm.Rd: Clarify that "piecewise.times" is not needed for models fitted with "pci". Thanks to Christos Argyropoulos. * R/msm.R(msm): Warning if initcovariates is supplied but the model is not hidden Markov. Thanks to Christos Argyropoulos. 2011-05-05 Chris Jackson * R/utils.R(dtnorm): Return -Inf when log=TRUE and x outside truncation bounds. Thanks to William Leeds for the report. 2011-02-08 Chris Jackson * man/msm.Rd: Help page clarified to say that "state" is also used for the observed outcome in a HMM. Thanks to Ricardo Antunes. 2010-11-24 Chris Jackson * R/outputs.R: Line types, colours and widths can be configured in plotprog.msm, plot.survfit.msm and plot.prevalence.msm. * DESCRIPTION: Version 1.0 finally released to accompany the forthcoming paper on msm in Journal of Statistical Software. 2010-11-12 Chris Jackson * man/msm.Rd: Documentation for the return value of msm corrected to state that the "logbaseline" components of result matrices are evaluated with covariates set to zero if center=FALSE, and at their means if center=TRUE. Previously it stated that "logbaseline" was evaluated at the mean covariate values. * R/msm.R(msm), R/outputs.R(print.msm): Return the "baseline" and "sojourn" components of result matrices at covariate values of 0 if center=0. Thanks to Kenneth Gundersen for the report. 2010-11-01 Chris Jackson * R/boot.R(bootdata.trans.msm): Fix for bootstrapping when some levels of a factor do not appear in a bootstrapped dataset. Thanks to Gale Bravener for the report. 2010-10-29 Chris Jackson * R/msm.R(msm.check.times): Fixed a bug in comparing small floating point numbers to zero, and added "may be" to warning about data inconsistent with transition matrix, due to uncertainty about these comparisons. 2010-09-22 Chris Jackson * R/msm.R(msm.check.times): Added warning for multiple observations at the same time on the same person with different states, which leads to zero likelihood and "cannot be evaluated at initial values" message. 2010-05-18 Chris Jackson * DESCRIPTION: Version 0.9.7 released 2010-05-07 Chris Jackson * R/msm.R: Ematrices and ematrix.msm for models with all "fixedpars" returned correctly. 2010-05-04 Chris Jackson * R/boot.R: Bug fixes. "end" argument wasn't included in totlos.ci.msm and totlos.normci.msm, bootstrapping broke with covariates on HMM outcomes, and "fixedpars" weren't accounted for in normboot.msm. Thanks to Li Su for these reports. 2010-02-09 Chris Jackson * R/pearson.R: Fix for "NA in probability vector" error caused by floating point comparisons in empiricaldists(), which were still happening. Thanks to Wen-Wen Yang for the report. * DESCRIPTION: Version 0.9.6 released 2010-01-29 Chris Jackson * src/pijt.c(Pmat): Don't round extreme likelihood contributions to 0 and 1 for models with "exacttimes", since they are not probabilities. Fixes occasional wrong likelihood calculations. 2010-01-14 Chris Jackson * R/msm.R: The "pci" element of fitted model objects now excludes values which are outside the time range of the data. Allows pmatrix.msm to be used on such models without error. Also give a warning when any "pci" cut points equal the min/max time point in the data. Thanks to Matt Cowperthwaite. 2009-11-25 Chris Jackson * R/pearson.R: Fix for problem revealed by different handling of factors in R-2.10.0, which caused all expected values to be returned as zero. Thanks to Brian Tom for the report. * DESCRIPTION: Version 0.9.5 released. 2009-11-13 Chris Jackson * R/msm.R(msm.form.data): Bug fix for handling missing subject ID. * DESCRIPTION: Version 0.9.4 released. 2009-11-05 Chris Jackson * R/outputs.R(pmatrix.msm, pmatrix.piecewise.msm): Allow options to MatrixExp to be passed through. * R/msm.R(crudeinits.msm): Don't break with missing values. 2009-09-15 Chris Jackson * R/likderiv.msm: Bug fix: Use obstype.obs when calculating score residuals, not obstype. Also fixed misplaced for loop initialising patient derivatives to zero in src/lik.c(derivsimple_subj). Thanks to Aidan O'Keeffe for the report. 2009-08-26 Chris Jackson * R/pearson.R: Fix for "replacement has 0 rows" error - don't add covariates column to internal data when there are no covariates. * R/pearson.R: timeinterval rounded in empiricaldists to avoid "NA in probability vector" errors in R-devel arising from floating point fuzz. 2009-08-20 Chris Jackson * R/msm.R: fix of previous bug fix from 06-24 for derivatives with respect to fixed parameters. Thanks to Aidan O'Keeffe for the report. * DESCRIPTION: Version 0.9.3 released. 2009-07-27 Chris Jackson * R/msm.R(msm.form.output): Bug fix - estimates of covariate effects were being ordered wrongly in matrices outputted by msm in models with "qconstraint". Thanks to Brian Tom for the report. 2009-06-24 Chris Jackson * DESCRIPTION: Version 0.9.2 released. 2009-06-24 Chris Jackson * R/msm.R: Bug fix - don't return derivatives with respect to fixed parameters - this was causing "gradient in optim evaluated to wrong length" error for models with fixed parameters fitted using BFGS. Thanks to Isaac Dinner for the report. 2009-06-12 Chris Jackson * tests/simple.R: Removed a couple of tests which fail due to floating point fuzz on Fedora/Red Hat PPC Linux. * DESCRIPTION: Version 0.9.1 released. 2009-06-09 Chris Jackson * R/pearson.R: Covariate grouping fixed to 1 for pci models with no other covariates, as the covariate group is equivalent to the time group. * DESCRIPTION: Version 0.9 released. 2009-06-05 Chris Jackson * DESCRIPTION: Licence altered from GPLv2 to GPL v2 or later. Licence text removed from src/pijt.c. * R/msm.R(msm): Default changed to use.deriv=TRUE. * R/msm.R(msm.pci): Don't impute observations for pci models at times when there is already an observation. This fixes "times not ordered" errors when bootstrap resampling for Pearson test. 2009-04-29 Chris Jackson * R/outputs.R(factorcov2numeric.msm): Extractor functions now set unspecified covariate values in covariate lists to 0, and ignore unknown covariates. * R/outputs.R(factorcov2numeric.msm): All extractor functions can now accept covariate values as numeric contrasts as well as factor levels. * R/outputs.R(plot.survfit.msm): Call to survfit fixed for compatibility with R version 2.9.0. * R/outputs.R(pmatrix.msm): Adapted to automatically handle "pci" models with piecewise constant intensities, with new "t1" argument representing start time. New internal function "msm.fill.pci.covs" to enable time-constant covariates to be passed through this facility properly. Arguments of all calls to pmatrix.msm changed. As a result, functions which call pmatrix.msm (prevalence.msm, expected.msm, totlos.msm, plot.survfit.msm) now handle time-inhomogeneous models specified using "pci". * R/msm.R(msm.pci): Bug fix - covmeans calculated wrong in pci models with other covariates, leading to error in qmatrix.msm for covariates=0. 2009-04-29 Chris Jackson * src/lik.c: Bug fix - score residuals were being calculated wrongly for models with covariates. 2009-04-24 Chris Jackson * R/pearson.R: Fixed "second argument must be a list" bug. * R/outputs.R: Order of effects in hazard.msm and odds.msm changed to read across rows of the transition/misclassification matrix. This is for consistency with, e.g. fixedpars. 2009-04-08 Chris Jackson * man/msm.Rd: Documentation for qconstraint clarified. * R/outputs.R: Bug fix - interactions now expanded properly when calling extractor functions for models with interactions between covariates. * R/msm.R: Bug fix which affected bootstrap refitting in pearson.msm, giving "Error in `$<-.data.frame`(`*tmp*`, "pci.imp"..." * DESCRIPTION: Version 0.8.2 released. 2009-04-03 Chris Jackson * LaTeX sources for PDF manual included in src/doc to enable msm to be approved as a Debian package. 2008-07-25 Chris Jackson * R/pearson.R: Bug fix, maxtimes was producing negative censoring times. * DESCRIPTION: Version 0.8.1 released. 2008-07-23 Chris Jackson * R/msm.R: New option "pci" to msm, which automatically constructs a model with piecewise-constant transition intensities which change at the supplied times. * R/boot.R: Give an informative error in normal theory CIs when SEs not available from fitted model. 2008-07-22 Chris Jackson * src/lik.c (GetOutcomeProb): HMM now applies to censored outcomes, unless obstrue = 1. Thanks to Norm Good for the suggestion. 2008-04-15 Chris Jackson * R/msm.R: deriv.test argument to msm removed. * src/lik.c: Bug fix in liksimple/derivsimple - the P matrix was not being recalculated when the obstype changed between 1 and 2. Thanks to Peter Jepsen for uncovering this. 2008-03-31 Chris Jackson * R/outputs.R: totlos.msm now computes total length of stay for all states, not just transient states. New argument "end" added. * R/outputs.R: xlim argument added to plotprog.msm. * R/outputs.R: legend added to plot.prevalence.msm. 2008-03-28 Chris Jackson * DESCRIPTION: Version 0.8 released. 2008-03-18 Chris Jackson * R/pearson.R: New file for the Pearson-type goodness-of-fit test. Thanks to Andrew Titman for his work on this. * data/heart.txt: Data "heart" renamed to "cav". * R/simul.R: any() bugs in simmisc.msm for simulating misclassification models fixed 2008-03-11 Chris Jackson * R/outputs.R: logLik.msm degrees of freedom corrected for models with parameter constraints. * R/outputs.R: New function "plot.survfit.msm" to plot Kaplan-Meier estimate of survival probabilty compared with the fitted survival probability from a model. * R/outputs.R: Allow customisable axis titles and line widths in all plot functions. 2008-03-03 Chris Jackson * R/outputs.R: New function "plotprog.msm" to plot Kaplan-Meier estimates of time to first occurrence of each state. Added "survfit" and "Surv" imports from the "survival" package. * R/outputs.R: New likelihood ratio test function "lrtest.msm". 2008-03-03 Chris Jackson * R/outputs.R: logLik method returns the log-likelihood, not the minus log-likelihood. Thanks to Jay Rotella for the report. 2008-02-27 Chris Jackson * R/utils.R: Transformation bug fixed which caused rtnorm to hang for extreme means. Thanks to Bjrn Bornkamp. 2008-02-18 Chris Jackson * R/boot.R: Simulate normal CIs using unreplicated parameters, so that they work with the new release of mvtnorm. Thanks to Peter Jepsen for the report. 2007-12-12 Chris Jackson * R/msm.R,src/lik.c: Score residuals implemented. 2007-12-10 Chris Jackson * R/utils.R: Quantile functions: uniroot() convergence tolerance tightened to solve problems with obtaining quantiles for small arguments. Thanks to Barbara Bredner for the report. * DESCRIPTION: Version 0.7.6 released. 2007-11-21 Chris Jackson * R/simul.R: Bug fix, "cur.t not found" error. * R/simul.R: Allow covariates on misclassification probabilities in simulations 2007-11-20 Chris Jackson * R/msm.R: Don't give no-SEs warning when hessian=FALSE * R/simul.R: Handle only one observation per subject. * R/outputs.R: New internal function intervaltrans.msm to determine set of allowed transitions in an interval. * DESCRIPTION: Version 0.7.5 released. 2007-11-08 Chris Jackson * R/outputs.R(qratio.se.msm): Bug fix for factor covariates. Thanks to Peter Jepsen. 2007-11-05 Chris Jackson * R/boot.R (bootdata.trans.msm,bootdata.subject.msm), R/msm.R (msm.form.data,msm.form.covdata): Handle factor covariates properly when bootstrap refitting, by retaining the original covariates (not the numeric contrasts) in the data. Thanks to Peter Jepsen. * R/outputs.R: qmatrix.msm, ematrix.msm, sojourn.msm and qratio.msm can now be called with ci="none", returning just the matrix of estimates, with no CI. 2007-11-02 Chris Jackson * R/utils.R: MatrixExp now accepts a vector of t, in which case it only needs to calculate the eigensystem once. 2007-10-30 Chris Jackson * R/utils.R: Bug fix in ppexp. Thanks to Mike Murphy. * msm-manual: More explanation of censored states versus censored event times. 2007-10-25 Chris Jackson * src/hmm.c: New beta HMM outcome distribution. * src/lik.c: Ignore initprobs in HMMs if the true state is known at the initial observation. 2007-10-24 Chris Jackson * src/lik.c: Handle censoring properly in Viterbi algorithm. 2007-10-22 Chris Jackson * R/boot.R(bootdata.subject.msm): Bug fix, wrong covariate matrix was being read. Thanks to Peter Jepsen for the report. * msm-manual.pdf: Correction of algebraic typos in Viterbi algorithm. * src/lik.c: Account for obstrue in Viterbi algorithm. * R/outputs.R: Allow Viterbi algorithm to be used to impute censored states in data with censored states but no HMM. 2007-10-18 Chris Jackson * R/outputs.R(prevalence.msm,plot.prevalence.msm): Account for arguments supplied to prevalence.msm when doing the plot. Thanks to Peter Jepsen for the report. 2007-10-01 Chris Jackson * src/Makevars: CR endings removed to satisfy R CMD CHECK in R 2.6.0 * R/outputs.R(print.msm.est): test for CI using is.list(), since $ on an atomic object fails in R 2.7.0 instead of returning NULL. * DESCRIPTION: Version 0.7.4 released. Use standardised license string. 2007-08-15 Chris Jackson * DESCRIPTION: Version 0.7.3 released. 2007-08-14 Chris Jackson * R/boot.R: Handle obstype and obsmisc in bootstrap refitting, and handle refitting of msm models where obstype, obsmisc and subject vectors are calculated within the argument to msm. Thanks to Peter Jepsen for the report. * R/boot.R, R/outputs.R: Add bootstrap handlers (both nonparametric and normal-theory) for qmatrix.msm, ematrix.msm, sojourn.msm, qratio.msm, pmatrix.piecewise.msm, totlos.msm, prevalence.msm. 2007-07-27 Chris Jackson * src/analyticp.c: Bug fix: exponential of certain degenerate 5 state intensity matrices was not being calculated properly. Thanks to Ross Boylan for the report. * man/msm.Rd: Make clear that the initial values for constrained parameters are taken from the first of the multiple initial values supplied. Thanks to Ross Boylan. 2007-06-30 Chris Jackson * R/outputs.R(surface.msm): Bug fix: don't include auxiliary parameters in HMMs. Thanks to Michael Sweeting. 2007-06-29 Chris Jackson * R/utils.R(MatrixExp), src/pijt.c(MatrixExp): Bug fix. When there are complex eigenvalues, don't use the eigensystem method of calculating the matrix exponential. Thanks to Vronique Bouchard. 2007-06-05 Chris Jackson * R/outputs.R(expected.msm): Bug fix, wrong risk set was being calculated for user-specified "times". * R/outputs.R(observed.msm): Allow interpolation of observed states using the midpoint of an interval. * R/outputs.R(pmatrix.msm), R/boot.R: Confidence intervals for P matrix can now be calculated by simulating from multivariate normal distribution of MLEs. * R/outputs.R(plot.prevalence.msm),man/plot.prevalence.msm.Rd: new function for prevalence plots. * man/pmatrix.piecewise.msm.Rd: Example corrected to use four sets of covariates. Thanks to Qing Wang. * DESCRIPTION,NAMESPACE: Added rmvnorm import from "mvtnorm" package. 2007-05-31 Chris Jackson * DESCRIPTION: Version 0.7.2 released. 2007-05-29 Chris Jackson * R/outputs.R: Functions to calculate SEs and CIs for ematrix.msm adapted to deal with multinomial logistic regression. CIs for probabilities are calculated using delta method approximation to variance of logit p, instead of log p as previously. 2007-05-26 Chris Jackson * R/utils.R: Truncated normal random sampling algorithm improved to use the rejection method by Christian Robert. Thanks to Vivek Roy for the suggestion. 2007-05-25 Chris Jackson * R/msm.R: Constraints on intensity covariate effects that some effects are equal to other effects multiplied by -1 are now allowed. * R/msm.R: Structural zeroes are allowed for initial state occupancy probabilities. * inst/doc/msm-manual.pdf: Misclassification examples on heart data changed so that individuals' first observations are not misclassified. 2007-05-21 Chris Jackson * R/lik.c: Serious bug fix. Effects of covariates on outcome probabilities in misclassification models (categorical HMMs) are now estimated using multinomial logistic regressions, instead of (incorrectly) independent univariate logistic regressions for each probability. * R/msm.R, R/lik.c: Effects of covariates on initial state probabilities in HMMs can now be estimated through multinomial logistic regression. 2007-05-13 Chris Jackson * R/outputs.R, R/boot.R: New option "ci.boot" to prevalence.msm, a helper to calculate bootstrap confidence limits for the expected prevalences using "boot.msm". * R/msm.R, src/lik.c: New argument "obstrue" to msm, to allow some observations to be observed without error in misclassification models. 2007-05-11 Chris Jackson * R/msm.R: Return derivatives in $deriv component of the msm object after optimisation. Thanks to Ole Rummel. 2007-04-18 Chris Jackson * R/msm.R: Don't drop covariates on transition process which are missing at the last observation for a patient, because they are not used in the analysis. This has the consequences that output from prevalence.msm may be different from earlier versions (0.7 or earlier) if there are missing values in the data. Users are advised to drop missing values from their data (if statistically appropriate!) before using msm. * DESCRIPTION: Maintainer email address changed. * DESCRIPTION: Version 0.7.1 released. 2007-04-05 Chris Jackson * R/outputs.R(viterbi.msm): Bug fix for models with covariates. Thanks to Hongjie Wang. * R/outputs.R(prevalence.msm): Can now calculate expected prevalences for models with piecewise-constant intensities, in the same manner as pmatrix.piecewise.msm. 2007-04-04 Chris Jackson * R/outputs.R(prevalence.msm): Bug fix, initstates was being ignored. Thanks to Peter Jensen. * R/msm.R: Give a warning when the standard errors cannot be calculated. * R/msm.R(msm.form.houtput): Bug fix for initprobs display with only two states. 2007-03-02 Chris Jackson * R/outputs.R(print.msm, qematrix.msm): Bug fix: When center=FALSE, reported baseline intensity matrix should be labelled as with covariates set to zero, not at their means. Thanks to Ross Boylan. 2007-02-09 Chris Jackson * src/lik.c: Return likelihood of zero for individuals with only one observation in censoring and hidden models. Thanks to Jonathan Williams for discovering the bug. * data/heart.txt: Age at transplant date corrected. Thanks to Jonathan Williams. 2006-11-21 Chris Jackson * R/msm.R: Initial state occupancy probabilities can now be estimated. See new argument "est.initprobs" to msm. * DESCRIPTION: Version 0.7 released. 2006-11-20 Chris Jackson * R/simul.R(sim.msm): Transpose error in bug fix from 0.6.4 corrected. * R/outputs.R: Values of factor covariates are now supplied to extractor functions in a sensible way, at last. Reordering bug fixed with named covariate lists. 2006-11-19 Chris Jackson * R/boot.R: New file. Implements bootstrap resampling for fitted msm models. * R/outputs.R: Bootstrap confidence intervals available for pmatrix.msm and totlos.msm. * R/outputs.R: pmatrix.msm now defaults to one time unit, instead of forcing time unit to be explicitly given. * R/outputs.R: observed.msm function rewritten. Fixes bug in calculating observed prevalence for state at maximum observed time, reported by Jeremy Penn. It is also now much faster. * R/outputs.R: prevalence.msm is also adapted sensibly to handle data where not all individuals start at a common time. 2006-09-29 Chris Jackson * man/deltamethod.Rd: Example fixed to use correct covariance matrix. Thanks to Andreas Beyerlein. 2006-09-21 Chris Jackson * src/Makevars: PKG_LIBS fix to pass R CMD CHECK in R 2.4.0 * DESCRIPTION: Version 0.6.4 released. 2006-09-12 Chris Jackson * R/simul.R(sim.msm) Bug fix: multiply covariates by baseline intensities in the correct order. Also convert vector beta to matrix. Thanks to Stephan Lenz for the report. 2006-09-08 Chris Jackson * R/utils.R(rtnorm) Bug fix: use the correct components of parameters which are vectors. Thanks to Jean-Baptiste Denis for the report. 2006-07-16 Chris Jackson * Rd/msm.Rd, inst/doc/msm-manual.pdf: Documentation correction - the initial values of the qmatrix are with covariates at their means in the data, not with the covariates at zero. This bug has existed since version 0.5. 2006-07-16 Chris Jackson * R/msm.R: Row and column names of crudeinits output retained from qmatrix input. 2006-06-29 Chris Jackson * Definition of initprobs corrected on manual p31. 2006-06-28 Chris Jackson * References reinstated in the PDF manual. * DESCRIPTION: Version 0.6.3 released. 2006-06-23 Chris Jackson * DESCRIPTION: Version 0.6.2 released. 2006-06-21 Chris Jackson * msm.obs.to.fromto,msm.check.times: Support character subject variables. Thanks to Danstan Bagenda for the report. 2006-06-21 Chris Jackson * Analytically-calculated transition probability matrices implemented for selected 3, 4 and 5 state models. These are calculated in new file src/analyticp.c. New option "analyticp" in msm() to revert to the old matrix exponential method. Update to msm-manual.pdf describing this method. 2006-06-20 Chris Jackson * R/simul.R(getobs.msm): Bug fix - Keep only one observation in the absorbing state when absorbing state is not the highest state. 2006-05-29 Chris Jackson * man/logLik.Rd: help page fixed to explain that this returns the minus log likelihood. Thanks to Ole Rummel. * msm.R (likderiv.msm): bug fix - transformation of the derivatives when all parameters are fixed was returning all NAs. 2006-03-26 Chris Jackson * lik.c(Viterbi): Bug fix - don't ignore initprobs. Thanks to Melanie Wall for reporting this. * DESCRIPTION: Version 0.6.1 released. 2006-03-15 Chris Jackson * NAMESPACE: Import persp, plot and contour in from graphics. * msm.R (msm.check.times): Bug fix for factor subjects with empty levels. Thanks to Jacques Gautrais. 2006-01-04 Chris Jackson * msm.R (msm.form.data): use match(, unique()) to convert subject to ordinal, not factor. Also do msm.check.times after dropping missing data. Plus fix for missing obstime. 2005-11-25 Chris Jackson * DESCRIPTION: Version 0.6 released. 2005-11-17 Chris Jackson * R/outputs.R: New function surface.msm for surface plots of likelihoods. 2005-11-16 Chris Jackson * lik.c,pijt.c, etc.: Analytic derivatives of the likelihood implemented for all models, apart from hidden Markov models or models with censoring. New argument "use.deriv" to tell msm to use these where appropriate. Thanks to Andrew Titman for the debugging help. * The Dennis and Schnabel algorithm in the R function "nlm" can now also be used to maximise the likelihood, as an alternative to the algorithms in "optim". 2005-11-11 Chris Jackson * msm-manual.pdf: definition of initial state probability f corrected in hidden likelihood, equation 13. Thanks to Andrew Titman. 2005-11-08 Chris Jackson * man/deltamethod.Rd: Documentation of deltamethod clarified to explain how to use user-defined variables within the formula. 2005-10-11 Chris Jackson * Negative binomial hidden Markov model output distribution added. * DESCRIPTION: Version 0.5.2 released. 2005-10-10 Chris Jackson * lik.c(Viterbi): Bug fix, wasn't handling Markov chains with progressive and regressive states properly. Thanks to Rochelle Watkins. * msm.R(msm.form.covdata): further fix for missing data. 2005-10-1 Chris Jackson * msm.form.qmodel: Bug fix with gen.inits==TRUE and censoring. Thanks to Jacques Gautrais. 2005-07-27 Chris Jackson * sim.msm: collapse.covs fixed to handle covariate matrices with one observation time. * msm.R(msm.form.covdata): bug fix for covariates in global environment, not a data frame. This bug produced the error "Error in 1:n : NA/NaN argument". 2005-05-27 Chris Jackson * sim.msm: sample replaced by resample as in ?sample, to fix simulations with small models. * msm.R: Fix for one-parameter models. (drop=FALSE in subsetting covmat) 2005-05-25 Chris Jackson * utils.R: New functions (dpqr)pexp for the exponential distribution with piecewise-constant rate. * utils.R: Bug fix: arguments lower.tail and log.p implemented for truncated normal and measurement error distributions. * DESCRIPTION: Version 0.5.1 released. 2005-05-23 Chris Jackson * tests/*: Tests are now fully automated. Outputs are compared against known results using stopifnot(). * outputs.R(hazard.msm, odds.msm) Names "L95", "U95" changed to "L","U" for generality. 2005-05-20 Chris Jackson * msm.R: Data reorganised so that covariates are stored in a matrix throughout. These are available from the model output as cov for one per observation time, and covmat for one per time difference. This fixes a bug which prevented covariates with names such as "state", "time", "subject", among others, from being used. 2005-05-16 Chris Jackson * simul.R(sim.msm) Re-written. Fixes a bug in simulating from models with time-dependent covariates, where not every covariate change was accounted for. Uses new function rpexp to simulate from the exponential distribution with piecewise-constant rate. Thanks to Mike Sweeting for the bug report. * simul.R(sim.msm) Simulations now contain a censoring time at maxtime, instead of the future absorption time. * simul.R(getobs.msm) Re-written, replacing ugly loops with vectorised code. 2005-04-11 Chris Jackson * man/simul.Rd: clarified that qmatrix is with covariates set to zero. Thanks to Anne Presanis. 2005-04-11 Chris Jackson * outputs.R(pmatrix.piecewise.msm): Bug fix for times of length 1. Thanks to Anne Presanis. 2005-03-09 Chris Jackson * pijt.c(Pmat): Don't recalculate pii within j loop. 2005-03-08 Chris Jackson * pijt.c: New function Eigen. MatrixExp merged into one function. 2005-03-07 Chris Jackson * msm.R(msm): Argument "hessian" added to msm. Covariance matrix is set to NULL instead of a string when SEs not available. * msm.R(msm): Confidence limits of fixed parameters set to NA, not zero width. 2005-03-06 Chris Jackson * DESCRIPTION: Version 0.5 released. This is a major re-write, so instead of a detailed change log, the NEWS entry is reproduced below. Version 0.5 (2005-03-06) ----------- * Major update. Much of the internal R and C code has been re-written. * General continuous-time hidden Markov models can now be fitted with msm, as well as misclassification models. Allowed response distributions conditionally on the hidden state include categorical, normal, Poisson, exponential and others. See the new "hmodel" argument. Misclassification models can either be fitted in the old style using an ematrix, or using a general HMM with a categorical response distribution. Covariates can be fitted to many of the new hidden response processes via generalized regressions. See "hcovariates", "hcovinits" arguments. * Per-observation observation schemes, generalising the "exacttimes" and "death" concepts. An optional new variable in the data can specify whether each observation is a snapshot of the process, an exactly-observed transition time, or a death state. Observations are allowed to be at identical times, for example, a snapshot followed instantly by an exact transition time. * Various syntax changes for cleaner moder specification. - Instead of 0/1 indicators, qmatrix and ematrix should contain the initial values for the transition intensity / misclassification matrix. These matrices can be named with names for the states of the Markov chain. - The inits argument is abolished. Initial values are estimated automatically if the new argument to msm "gen.inits = TRUE" is supplied. This uses the initial values calculated by crudeinits.msm. - misc no longer needs to be specified if an ematrix is supplied. - fixedpars=TRUE fixes all parameters, or specific parameters can be fixed as before. - crudeinits.msm takes a state ~ time formula instead of two separate state, time arguments, for consistency with the msm function. - Initial values for covariate effects on transition rates / misclassification probabilities are assumed to be zero unless otherwise specified by the new "covinits" / "misccovinits" argument. * Support for 'from-to' style data has been withdrawn. Storing data in this format is inadvisable as it destroys the longitudinal nature of the data. * Speed improvements. The algorithm for calculating the likelihood for non-hidden multi-state models has changed so that the matrix exponential of the Q matrix is only calculated once for each time difference / covariate combination. Therefore, users should see speed improvements for data where the same from-state, to-state, time difference, covariates combination appears many times. * Confidence intervals are now presented instead of standard errors for uncertainty in parameter estimates. * New method of calculating matrix exponentials when the eigenvector matrix is not invertible. It now uses the more robust method of Pade approximants with scaling and squaring, instead of power series. Faster LAPACK routines are now used for matrix inversion. * covmatch argument to msm has been abolished. To take a time-dependent covariate value from the end of the relevant transition instead of the default start, users are expected to manipulate their data accordingly before calling msm, shifting the positions of the covariate back by one within each subject. * Syntax changes for simmulti.msm. Bug fixes --------- * The likelihood is now calculated correctly for individuals with censored intermediate states, as well as censored initial and final states. Thanks to Michael Sweeting for reporting this. * hazard.scale and odds.scale were interpreted wrongly in hazard.msm and odds.msm respectively. * time-dependent covariate values now taken from the start instead of end of the transition under hidden Markov models. 2005-01-28 Chris Jackson * src/lik.c (GetCensoredPObsTrue): Censored outcomes are now assumed to be not misclassified. * msm.R(msm.form.censor): Bug fix - transient states were detected incorrectly. * src/pijt.c: Bug fix. P matrix calculation for misclassification models was ignoring exacttimes. * src/lik.c: Bug fix. Ignore death when exacttimes = TRUE. * DESCRIPTION: Version 0.4.1 released. 2005-01-07 Chris Jackson * DESCRIPTION: Version 0.4 released. 2005-01-06 Chris Jackson * msm/R/msm.process.covs: Bug fix - covariates were not being centered. Thanks to Andrew Titman. 2004-12-29 Chris Jackson Support added for censored observations. * src/lik.c: Bug fix. Don't ignore exacttimes for misclassification models. Fixes in documentation. Thanks to Ross Boylan. 2004-09-18 Chris Jackson * man: Rd syntax errors fixed to pass R CMD CHECK under 2.0.0 * * msm-manual: Reference to the PDF manual for msm made more prominent. * DESCRIPTION: Version 0.3.3 released. 2004-06-23 Chris Jackson * msm.R(msm.process.covs): Bug fix, constraints were not being calculated properly when some covariates were constrained and some were not. Thanks to Mike Sweeting. 2004-06-01 Chris Jackson * msm-manual: Correction - heartmiscsex.msm is actually run using default Nelder-Mead optimization, not BFGS. 2004-05-13 Chris Jackson * R/outputs.R: plot.msm now plots survival curves in different colours as well as different line types. 2004-05-11 Chris Jackson * R/simul.R: simmulti.msm now returns a data frame, as it should do. 2004-04-23 Chris Jackson * New argument "start" in simmulti.msm to give the starting state for each individual. Thanks to Stephan Lenz for the suggestion. 2004-03-25 Chris Jackson * NEWS file moved to inst directory, so that it ends up in the root directory of binary installs. Leave ChangeLog in the source package. * DESCRIPTION: Version 0.3.2 released. 2004-03-24 Chris Jackson * R/outputs.R(print.msm): Bug fix - only say "covariates set to their means" in the output if there actually are any covariates. * msm-manual.pdf: Hidden Markov model theory moved to straight after general model theory, general cleanups. 2004-03-23 Chris Jackson * msm-manual.pdf: R code examples rewritten using Sweave. Examples run again with different death assumption, most estimates are negligibly different. Misclassification model examples corrected to include death. Example of plot.msm added. This is not distributed as a vignette, as the msm model examples take a long time to fit. 2004-03-22 Chris Jackson * R/simul.R(simmulti.msm, getobs.msm): tunit argument abolished and death times assumed to be known exactly. * src/lik.c(fillparvec): Bug fix. Bounds checking on vector of indices of fixed parameters. Thanks to Ross Boylan. 2004-03-21 Chris Jackson * R/msm.R, src/lik.c: tunit argument is now abolished (with warning given). Death states are assumed to have exact entry times, not within one day. This is cleaner and more logical, as in longitudinal studies all observations are usually accurate to one basic time unit, not just deaths. * R/msm.R, src/lik.c: More than one death state is now supported. A death state has exact entry time, with an unknown transient state at the previous instant. Thanks to Jean-Luc Bulliard for suggesting this. * R/msm.R(msm.check.times): Just give a warning if a subject only has one observation, no need to die. * R/msm.R(lik.msm): Bug fix. set diagonal to 0 when calculating number of misclassified states nms, in case user has given non zero diagonal entries in ematrix. * (various) Changes made so that R CMD CHECK passes with R 1.9.0 alpha: codoc mismatches and PACKAGE argument in .C() 2003-10-14 Chris Jackson * src/pijt.c(MatrixExpSeries): Bug fix. Don't overwrite the matrix A, as it is needed after the function exits. This had led to wrong results when exacttimes = TRUE and the intensity matrix had repeated eigenvalues. * src/lik.c(liksimple, liksimple_fromto, UpdateLik): Don't ignore death argument when exacttimes = TRUE. * R/msm.R(msm.check.times): Use table instead of tapply to count the number of observations per subject. Fixes further problems with running out of memory. * DESCRIPTION: Version 0.3.1 released. 2003-09-29 Chris Jackson * R/outputs.R: Debugging print statements removed from pmatrix.piecewise.msm * msm-manual.pdf: Version number added. * DESCRIPTION: Version 0.3 released. 2003-09-26 Chris Jackson * src/lik.c, src/pijt.c: Allocate memory using S_alloc, not Calloc. Solves the problem of running out of memory for large datasets. * R/outputs.R(observed.msm): Fixed a bug with looping over a factor patient ID, which caused prevalence.msm to fail. 2003-09-25 Chris Jackson * R/outputs.R(print.msm) Don't draw ASCII underlines under "Multi-state Markov models" banner - looks ugly in proportional font. * R/msm.R: nmiscs model attribute (number of misclassification probabilities) changed to nmisc for compatibility with C code. * src/lik.c(liksimple, liksimple_fromto): Bug fixed in the likelhood calculation for non-misclassified reversible models with death time known within one day. The error assumed the unobserved states on the day before death could only be states greater or equal than the previously observed state. This is not true for reversible models. * man/summary.msm.Rd: usage and argument lists made consistent, satisfying new R CMD CHECK. 2003-09-24 Chris Jackson * R/msm.R, R/outputs.R, src/lik.c: A new argument "qconstraint" to msm now allow equality constraints between baseline transition intensities. A similar argument "econstraint" allows equality constraints between misclassification probabilities. Thanks to Mike Sweeting and Ross Boylan for suggesting this. 2003-09-23 Chris Jackson * src/pijt.c(pijt): Bug fixed in the likelihood calculation for exact transition times with reversible models. The error assumed Prr(t) was always equal to exp(-qrr t), when this is only satisfied for a state r which is only visited once. 2003-06-30 Chris Jackson * R/outputs.R(qematrix.msm): Didn't work when the baseline rates or probabilities were fixed to zero, bug fixed (now uses x$model$qvector to test whether a transition is allowed, not x$Qmatrices$logbaseline). * R/outputs.R: New function - pmatrix.piecewise.msm, for calculating P-matrices for processes with non-homogeneous but piecewise-constant intensities. Thanks to Mike Sweeting for suggesting this. * DESCRIPTION: Version 0.2.2 released 2003-06-25 Chris Jackson * R/msm.R (msm.check.model): Bug fix - was reporting the wrong subject numbers when there were disallowed transitions in the data. Thanks to Stephan Lenz for spotting this. 2003-06-20 Chris Jackson * R/outputs.R: Covariates argument is now checked that it is a list, to avoid ugly warnings in R 1.7.0 2003-06-16 Chris Jackson * R/msm.R (msm.form.output): Died when only one parameter in the model, fixed by coercing covmat to matrix. 2003-06-03 Chris Jackson * inst/doc/msm-manual.pdf: Edits to manual, e.g. correction of covariates formulae to include baseline intensity, lots of typos corrected. * DESCRIPTION: Version 0.2.1 released 2003-04-29 Chris Jackson * R/simul.R: Bug fix in simmulti.msm: didn't work for one covariate. Thanks to Mike Sweeting for spotting this. * R/msm.R: Subject identification variable is now allowed to be factor or character. Thanks to Pablo Emilio Verde for the suggestion. * R/msm.R: msm.check.times also checks whether all the observations on a subject are adjacent in the data set. 2003-03-20 Chris Jackson * R/R: Bug fix in msm.check.times. Thanks to Pablo Emilio Verde for helping to find this. 2003-02-20 Chris Jackson * R/simul.R: Bug fix in getobs.msm: exact death times were ignored. (obstimes[i] replaced by sim$times[j+1]). 2003-01-05 Chris Jackson * DESCRIPTION: Version 0.2 released. * inst/doc/msm-manual.pdf: PDF manual completed. 2003-01-03 Chris Jackson * man: Heart transplant data added as an example data set * man: Aesthetic cleanups of all help pages * R/msm.R: New function crudeinits.msm to estimate a set of initial values for transition rates by assuming data represent the only transition times. * R/msm.R: New function statetable.msm to calculate frequencies of successive state pairs in data. * R/outputs.R: Methodology changed for prevalencemisc.msm to make it more similar to prevalence.msm, avoiding confusion. Observed counts now common to both, and separated out into a new function observed.msm. Then prevalencemisc.msm (and the internal C onestep) was removed and prevalence.msm was made general to both misclassification and non-misclassification models. 2002-12-18 Chris Jackson * src/lik.c: Bugfix. nms changed to nst in likelihood-calculating functions. Fixes failure to calculate the likelihood where some states where some states are observed without error, but are not death states (Thanks to Martyn Plummer). * R/simul.R: Bugfix in getobs.msm, which led to the entrance to not being observed for models with absorbing states. 2002-12-09 Chris Jackson * R/outputs.R: new function odds.msm to calculate odds ratios for misclassification probabilities. * R/outputs.R: new function ematrix.msm. Calls new internal functions, including qematrix.msm. 2002-12-03 Chris Jackson * R/outputs.R: new function qratio.msm for estimating ratios of intensities and (via new function qratio.se.msm) their standard errors. Documentation in man/qratio.msm.Rd. 2002-12-02 Chris Jackson * R/outputs.R: new internal function qmatrix.diagse.msm * R/msm.R Null components of msm objects removed, e.g. misclassification parameters for non-misclassification models. 2002-11-27 Chris Jackson * R: File msm.R split into msm.R, outputs.R and utils.R. * R/msm.R. New functions absorbing.msm and transient.msm which give the indices of the absorbing or transient states of the model. * R/msm.R. (plot.msm) Now accepts a "covariates" argument for covariates at which to evaluate the survival probabilities. * R/msm.R. Functions which operate on msm objects now have the msm object argument named "x", instead of "msm", for consistency. * man/qmatrix.msm.Rd, man/pmatrix.msm.Rd, man/sojourn.msm.Rd. Updated documentation. * R/msm.R (msm). The contents of msm objects has been reorganised. The first component of Qmatrices is now called "logbaseline" and gives the estimates of the log intensites as returned from the optimisation. Components "qcenter" and "ecenter" are removed, as they were named confusingly. The component 'Pmatrix' is also removed, as it is obsoleted by the function 'pmatrix.msm'. New component 'foundse' is a logical indicating whether the Hessian is positive definite, i.e. whether standard errors are available. * R/msm.R (sojourn.msm) Function rewritten to allow a given set of covariate values, using the new qmatrix.msm. Now takes a fitted msm model as its argument, and the component "mean" in the return is changed to "estimate". * R/msm.R (qmatrix.msm). New function to compute transition intensity matrix at given covariate values. * R/msm.R (pmatrix.msm). New function to compute transition probability matrix at given covariate values. * R/simul.R (simmulti.msm): Check for ordered patient IDs, and sort input data if not ordered. Also check for duplicated observation times and remove them. Default for 'death' argument changed to FALSE for consistency with msm(). Give column names to the simulated data. 2002-11-13 Chris Jackson * R/msm.R: New function msm.check.qmatrix to test for consistency of Markov chain intensity matrices. * R/msm.R, man/totlos.Rd: New function totlos.msm to estimate total length of stay in a state, with documentation. * src/lik.c, src/pijt.c: Unused and uninitialised variables fixed so the library builds cleanly with -Wall. 2002-11-08 Chris Jackson * src/lik.c: Debugging print statements removed from onestep * msm_0.1.tar.gz: First release msm/data/0000755000176200001440000000000014045251326011761 5ustar liggesusersmsm/data/bos4.rda0000644000176200001440000000675413051600620013323 0ustar liggesusers͜_eƏ6;)IMI'4Cπ 0 F`fdRefeFfeE\tх\xEλ5 3<{a9} 3iƤ\.7.7?0_'&N9Zr8>R*S g()YO ή|FgU`S|/*\ /+\(E _U_+4(XS5jW( (\po(\P7\0U W*\p; LSu'pF7)@a͂[jC5Mp&LY;f .)Hf|A```Up~%  +<(xHaA+mGjFV.X'X/PAg 6 5ؤУY } mGk0 ءSKPc5x\ 5WOXgkO~&x^s (W_ ^/58 *AᏂ? ^Y/7{;JwrJ]!~k'C;#MNO7o=֟&7$>odǗ$i!wP+i}U?S&r=[HR $.̥}ץy!i]:λ4~?S|kWOPYM!Ω8o(ۘ-i}!n)_1ͷ% J.iJV.yHKJC||Z_SIcߴľ4t9A$_Nwr7K\p 6.yz$NHUܣ:}?|H?3WWK7Hlɥ^UnL2ώSCܥϭ߮i5(͖zԷ(\wJUr6h}@}IjZKCP" دt.m1КΦoy̳]]v5_ӁgC\PNNNiNB{ZoJ*vuץaR I]!Y qĴ^Rqki}~׫t٫7y7yz[5OzZ|PrK]{!E7Ij>yb*<vy7zǔ4U"wՏJں4Tbz\ʏWJk^tr7z]_ktg)ŊoQ[P]3Tn{. qA=}Bze0č-!QJo>[Ҽ^bY}}/y5NދJ~OU^u5!*l:_nV~Yn9K)h:4_v轏ͪ\V,/BWIKl0čxk'k]m}s}Gzx1~>o?zn>'X(}i>8R50>1|s~ˍnzccqK9/_cF61_h۱9hsxqcza1 w1sG9>V?|1BzqhG9W߈<f#=~|`Ku^jaq9E \\C3nNj.Lua _]dE(b\C}\5ĕ+W>|DfMd6ٸ&2l"62l#6No#62"|..2"#>#|Y"_ȗIȜE,2g9A>ȜȜW|W|8s!2"_!⤅\\\8s1(أX1eKҲt,=ˌee%@Z4Т hE^UZx ^kZFZx-u:x;Z8x=-<^=Eoo-h7o7DBppsn#p"p;"p];X7E<#P#xLq OTU*T<] s!xx!xIx Ufu77-CNލ{#Q>>"i>  P +a!X9 na 5#0R`0:c`*qXX'& L`*0-f`flldac`lh '[Y $"XTYXlaIZBG#) d"i+@ȅ /P@o66 m| fa;v Y`*5_nQ{Tث &880E*-À#pD#-#p pl "*8pRN)Fi#C33##?~j, 'p~\PVEUpq\/..py\+"\]u >7XG M7[ŸCp+p[n+wG"pF!a<ǀ#d S3x /ExW^j^zxx+o"o}  |#IO"9cp0(!VJ-"zG`DFFG`"0¸u"0^`B֍zI LL t 3,̌ Ba6 D`S`6'n<@,$"#07,D`H`qD%" #@t'(D, l-#U6W"mjk!;F` `n3{`|3ka?` Dߊa8<G|;GF(c#p\c ߍI89D|?EgG8+?!I~  k<| Bpa. !C\,\+ ~~k7~[k#p] #:ip-[mnpG3w:qO/uPbHx4Yx<OD5SUgk*x`x ^ ?#5 77!xx xx; |k|\,cHST'`Hja*XJE`RZXX 0B`:1R`TF*XqXS'Ƈ`uCD u`J L0NL*Y'U0+VF!x)`i ̮5W'*Y[HTA ̋, -( [XGԁD[mΤn TGWT%*wmC_~hxJ?;͝0xÏ*wYO-~7v:Θpn&ݱ/qtzo|x\+7gt9 ntv{ι[p}[?^>{v{\}I_1x_˨ڷ.7r+FǯOm۱7-[z񾱛˂}b_x;]e_mQ{7ܷ{Xm~Bv}Uw>|^^;ti߇_?B?kϟm1}sO\y rvx{ ^0z>pw].~G]ѯ1h39)w樇DZҗ޸V0.' ]|t{?T׍r>wћ]rуU7'>=f]kytk{Rw*`Ey3{G_GuK|_?:TR_,9ݮ\\?|oCU=vϿ;>}6ˋ۲s*svl*yj9_Uٻ+R>_s`oz=%?.UkW~~RWmr* c/bknO}_U_<Ͽu&"<<(kb9}[o/].73߻eWE?\wi!ޒz38x^7+|[>|ˬSTn׶\yrDTwt6xʡyw96;%Ϛosܴg_s]v?+ۣ3_t1%D-|]OR}d?2՜1*?}T&Mxco+N_轭F+RG߫ x*WW^)KG=;)/}-ڿN7 {.)x+u߾(ϚOr;{۫*~Hs~oMrT=寫zO۫Z"$ÿ*n-{Osrk|JѠs wx}~uG]:KEF1^gył-ݧ],oܓsoǩbl;~NRV;ջ;prÕ7'ye//SV;o+ /_W77>Ǐsr[z6Xiy*(ESomev|:\i W !~?<<=iB^'Ub~y}ཿ=sjAƿVy\?0LW9HzOrX!o %aA=]n$rgK1h=Z廵^?.qےo|_賃Pe,~%<^挢h^b>}T7 ǧ^K{~ofV8䓢iyoܲvA.S?Ts~tr3sU$=~h]#;kW{4-#Uz'Ck;/A}!OG}jbg|Wcg`+SE*yN)2s>L!z[˯s6W/O_Ƴ#r9o4?~f~eW~]y =ێ|e,A>cFMnga*Tc[oQwя,wb]ߧd([; |2z۠O\??b֏!K>&c|h5A~?>_gUnS+ڿ*K2ׯ=5l&Ki\Xa=UƯL*{!ϻ[~ga7YJy[YS kN\藎^Py4ė/':F[e7Z+9`y聊+ͷsYsϜZ @yG4ywi;ע;tT/tpF<ۋі;~Fk~W}wv{m!<`xKvD)+޸_ r>0m;3ޫr/qq{"C8j\n볏LM:nm"_ βwŸGG?<,V3T~w=ϲW 0ڿ΁'߸gs=Ӹ{Wwˌ>s\v?.G|ן3e_KAmr wY~)~Br;u~[^X]=/CEsxwqSo4E<;wʏ1`$8㑗?Q^rqԊӞϾ?|L11?Ûާ,CЮ6_2Ëѯ_)*?un_nQQ8COVE_{^)9t*oan:{(m;/*98lyZUNϳ,ng?g{lmm~{G|=/x5=^'}(~7SsFiq _y>!Y_Aix\t<xs:^IחQ/f;Y;YGN~zhksOXq'>7ޓXO)_'$h?xG:j9~+_!Goxj_k#f?|;tsN܇X{T7Uԟq z. zqM;BIXk=^2yq'r֊C8ߦǃT!Vк֐3ȯ3a7myZ>b~g]?Wޖ[WQOF;юoC\[Pqosݒ/ɵe]Rwn7swwرܙy 1& 3۷u }G {\Z/buؕ&u/J@/į9R*kGiP]Gc^1qqȧWSW9-><lu<ɕt wYNCWK?¶^X@W=/#G_Yا=tߴg!޹6ٶ~~1kO4zsZ|{3c1w*,e//>TBg ߛʟ~a!/Ao^"?a]%+e:k Zuڤo^_O;|d_ןuW1(#bh{ c;"ԎckYįs8wUKsXIqGfswG\<,x"CW:*Doqo^ۓ<ֽ?/a!`iI7E^B?Ί OO=Ry:^źK[zf=q3u~CmZq9xOO03#޵GP~l'L^6̺ g;JGoEBim'gn_u?~OmG_m;hWbω)1Q!r_?wkОg#ÃO̯:Q>!'򻽎f¬'a=M{-hr7_&_yBqS#Da}ooE{V%xcw󩢟((z*BhΒo2z%rg o~ߛ|B+um׳#oCL\ޒGߠz#Bq OWV<19_|R>:允oy|d8PNORr iH/R<z0o{0U7#y+L\TlOG FgE#@~$?#y{wx !Vn55<ʟj_h''CvMr*_v>"cCg<~6y (E!&e3-w/ŗ<<o-WCd_vo:BP^6ͣyۮy{iS3vO֭C< ZG%oP?x,۔nY(?Ο8@otm/փ+(>G^(^Nb}OOw~t>L^x/)bO=C;>L7,֎CSct S}/a+@jvtWwY[Y m3~^AЯ\wF}``U۟G̓}Aܔe񨈫žݦN~/3EA<<3 Ю N짦*j'|=ޥ센5qX;>.+i;@a]v9xdޞov=G}hը~ߦx2joCުE+V%<'z87v>֡xWyjO@Q3ϱ.gc:O RORY]HiH>`Be0c'c܀slu14~FN!/eaf4Wb3 zpmOa]'? { O4v7R~7@A7Ay$הIt~M|AEBK$&ʲ':G#ާu6뺊8R~G^[q"@܁⓶8{hXW<_;>u^9/a?.$~s. ;>g'3G)_·5ͺ3P|?[?v?SP97*f ?؜SW_v7[m8ar{7_LO1I?fi?-2ss~)#Oc˒B͠׏_C= wc5zَ~-F:?9w99z9)//3moj `?g^b9U4oM>,;b+[oa+k3:/YTsL^Ry^HE<ǜqBE^OyzC6iжOM~u)9vȯ<:?k/&됹'Wg3þB{ɬyGys7(j#!mǥ7z)_/aF|?!ߚ<-*/j4m_3g~-v9liS%; v]}M|5ecԯzqxP ~(?0~ ۤqb\OgsQ@^?SM5/V{;eOZJqsΨ_Pҟֹ8,W{||ҟy= #p>4FE3?X;/k8z>_<&g3ֹ &\MI)YC~퓀_n֡zù 9z?[U9*W}Kp=}^N[E.^nWG;? z@q }fx䭸}"WG|xX'~D%hOp˳8w=}.y.}h?p/Y@} m$?g~!/ͯ~?_q*D}vF,<^WwM9/ ؏X?jsG}^6rIwL9i_rpNdNΡ*|gQ1Ish_zn s s\'6WS8ܣ=fstN#q^J:UX[{6$ X)+ nQƂO6k,Ż\s:~<ܢ/[!z6"{RhiOos 86S7V@|w-Ͻ8ދz/܋yloй-k32u)~H.υ3݈߁1~t\:fK8~?7p<|^g.>OwWMmrJQ=r7|}#u6ŴN?'2ֱaGw  X-w@ |}߫&ݦzWw-_|ߋ~= 뽸\'-w C1/T~baUmw`ON.~kS{XyE߄߻ByiRrt^h z7~_zi(\'~71y?m^-?C+㜋y51n֏&>b͗/dŋOz~&7 7.ǾrYM;=G@_nߊ[=snbgo c=~b# xHWyi"qN)/+?}t} -s} _q^~Mur(o6s/6i4l,?+`o!fw80zvFs:D k=Nw?9^ط~3_|BGȏsi>rOw <^!{no/v{GUagiXs;\U;υ>b{-98 ~RzuEgTX_P+?.X]=ߚø=>ErX67ѹjݮE0f.|#=5: >1}E~u2v^ R4}>fWhi?8ha;mW-G j*_ݠ\RXKC ™yGkͽo/&y4!ο%rI({wM6i};Bzz{q~t/!Eߐgo_W@|@/5=<cK/_uٚ߈OM})81W>~~;U/ցzbFܶ5bW~KKފCּG<<;^* HCt%s u^ݽV9WxޗG?籾VXv6λ-mXp*?vqQO|^ q«O~1Mm{9WDu<kYqYCsCI?:i:ߟ?S*ކZH­Q#S_vބgz;s>*֏8~`>ԜsG~̟sMŸk2|MyS {x<y{]Α*| IDzyGRxIarܛosyx"&q3!|=X:vo~ M<&'so w68ހq]yȟɟ|)[XWW~g>, =? [ 8g;,#';JCG.- ~T8U? ϕp^b? "k؏km?r6t [yyȻwM\x4eCRѹt}.Co~ ۝v~7oYVY?Ѻ;ltPZ/(`=`t 0Ϣ8 YIIx1~7w/{]酿k?Νn֛7+W.̄ ֵ+_^@ܬ͋ 'ay$u7M_F,?\VC:ЋwߋxQ/Z$Ccݼߵ(@?Ά݁-?rhm\L2Wϣ^O/;콨Vs^jLj'濋<{1y@n^K/O? 7qE~C;Dہ#kiOXr8ħOj#ӳiQ߬`G;'9si&{) ?V@^d_7_~*vv(}]44_PnKn ~Oywbytۯsf#ޘP~{Ӝg~:LZ_FP9Åx[zmƽ{븰_\C^Oz ?C~Y_iZW7Tئ h}W )Lvؕ/ ֹaf} /t?WkǹsWi#EyO?~arַF^qΒɷ^~ nSxRwcR>d/ρrܯq.wU=E^]ͺ/{aDy^UneGs}z7zaz_J/o/[Lz.OA3`ѿ-. ~S]k*.)S ͸,8WiߙzOF.78"sNvS]g---=Q8<g\&xɳ9?XiuKW嚉@=UL^ɗTj}ZuM@]&?EpDo r .k!\PMU@ݿH4ށ7_=%/IxRMi/ a2 6X[/@Ѵ@|2P(/ZԫA2P&-u__`Y !7XepOOjeWr4β/[/G4Ȇ ehr/:"Ek(ش괬pu\_TYE(b ^KME/b-7 %^l]Sz&>[EM(:~-3\<9]e9V|NߕESiƨlϺhTl$Q ,uij m+"cV E}JϚfz?u'6h*K7#Cf&y3'77%K)baŢߨIiLun}1~cx~ODʱy>K<C<º)p|QiYTGcxn\-(b J?͗szJIJDK\MsƛD}x4`k9W)41GPR[*RDig+9g&ω_7lbr*T%M,3Ơ*xVցis$2Kה7'Ohy;6F+ŧ'5yÛHݺ.>:~AuK\KHsxIJ5T8x&T3ۛ4mb"H2hmmb#P%18Av۳1~GD9k7%yGIʗ9HK"M,G$[ڑA5&E5UꐍEJ>&Grm~SحgOGNM>svS<}Njԅ>RVwxRȆqn&dDsC/W:7i?|t뤦rcC.Gds|BSKI,eJaoX%-DžL2A|Mߍs7n*Vz&tpg%I.c܈#_bLJs7&㶝H6 KߓJ(l7m!|W$[Ə8b!?AOMrKm&n⹿brin}O21k5!9$ޤjbl"Y7y:Wj&qd&{@mzUi7\" AϕfCzOIwq8˪́z8P~V\Q-WYa}W(2G\T#GV1mQL]]zx$Lպ'JvL_ZlZZM>kqDs峢l0 {?(yQ|(Tk˰{rt1%&jqI֖v֒Pg}Hʾglg=27g{mkq__O?WCE5.f5> ~kƲوNwtbCϫճlU1 գOUЈ;v[}V6mZ^~M ס7=fiwGOWid}YmBXT#|Ë/YaeCF4dE!X%!ht m!t+=!ȅ ́-BU Wm | N.v ׁB{=BO!88 a!8· !8FX ]-|8)Nt!83?1p69!Yεpp~...pI~"r W~:W7~ \#;ZCBppsnnn=wN wn>~Aa IS!;Xx xx% xHc?g5ACK^/5Cfx‡G'>>gp!PVV,*5B0R`kcq`u !88.p"=dMMk?5)S]S,1pgmmypԥNwnC#]WLNfskN\ͻE-n5לU?PN݇X;ޛ⧏V .%4-%S[љ9|K>i,y3nR 7F'\tmgn4eƹ}^PS~6m}jz=yؖZevǔjJ6gD7fd~zlE~KÔ--6 2\sVx{ -oFxMc]-u|ooq6V-]?o, .lC'PLr' nf;h9 횥V՚Z>Էnx!*uſ|scYs=ɃN+QFkan^o8ĕy _H>ەo5Cgp‡_m~].SxJM;蠕~ջ*~ ٟ|tn9jZ*gkٯp;=rO?꓃NQk9u~yMMxvoRKN<@_뭺^mOÅqLBustS&⟾Z0CoiZwr麭.6S~hy7+o:kUtܾ?Y_oxC.Om1ϧs6JgggCͻ|d^%~߻֏t] ſ)M!# yqm8vIgC^&<ɬ]<鿏{T)oz--[_mj2k8?I6?-9 C^Q?yծBgUO|OG}O{>JAҰ,/}Ѷݧ^3|pדrh9_vT~_eA?BW4('-yPoһcw1 oz.+ [Ԭf(U[oMYƱzY6rn=;n-+Կj]k\Xo^Vދ-V-DY?)>dw|U|/q9ώy}6GRduϪg;Ϻ޵@yv+\f[̀?۲6cS\gf_+:S79-6^nW-`%s hcy0g%ZW.כYzo[>ݮ.U.?]lf͗d}nǶ㗲[+跎uCz{gԊ}Rmr=fՒ8e?a_^R+]8HQŲ۬nSSʟ ¾c7_²lSV}};~I⍵7l<67 񗹖Y8j=/5[zZWe-5l/ݖY~b+HjʊYϛǭ}K +3zo/WekdZ /u]Dd=)g2}F_:/А{k%2YZKe/[u3YK?rZuWV=յZ6ڟ}3 Zu=uo_FmT&¾ju#rW3jͣzen_<4(ō;J뽮~!U>-Ig Wn{R¢LRBwE%ER_1\G?1O$ͳ?3bq)1e8 ǔ2ScpL)1e8 ה2\SkpM)5e ה2s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1R_;n`>|c kA\h:qI5pe?pUN\p,NNG- #}ux8c5xUx*ԉgs y //Ygx U'^5[uS'ޭՉu|(𑅏'u? p| Z+TJ5rX%։u`Uf:0:cX#0>,[&W:1̬ BqhxUG D $k`N̯E5ց訁@d@gtׁ*VA !(D65eت D+u`[kU5S \_-|=k`*ػ }k`*8 "pH:px]G m*8  uu^SBpj|iUpz0gT~G BpnW \P%UE\ZE\QWFU:* ~ µ?5pCpGBp=Up/p"q>8aP !XI` C50¸U0A`gaR&WL  !¬lCMCX" f!)0G`n`, E`IZ,Zh2!\ !L`laaK [E` _1;[E`Wv { },klCÀ-!pp1 #p |N} 8Kg[ #pnZX~aR \nJWWYC[k,\+pQnpn C.p/px#xBI M) O <#/x'*oo k | 𡅏>D? |A!P ++ $0 XY``U`5`u k F F X[`u$``tL Yl p<B%hR@, @/VWN.n7o #/?ppÁ#cc'N~ 8 8 SgyE%/Kˀˁ++_W~#'f6v.n{< <<<<<xxxQU-}c?'&?z*[n@OTe~rkT'Sxmյ |M~3Zpgn|Zx߾mbpwAoR[;f=ՒOq<ղϹAS->_֪I?xj-޴ݪm)۩x鲵?V Ę35GLl{5?vWfe5Em5t+zժT}Xn*fU"(S%Fj-OrWU{F<ڬڟ?כ:_3\z`R{@e6#%cf?*5J楛6zaJk*] U^wZ~j}/T[{v*jϢ9߫wVRۗ ^M?.> ۳^/GGkxy|K-F{Ow̿'UN_ҵktӞ?IkUo tU9%xJuMӅ~.û;AՃ{Џ=9bSoUsujް[}5']ΙV j S.5(/Zo+:eg-zO-sdϫ%ז -?;z=w{C&=GW~xUۺo~I@VTmË&ն(~}^0cՎ~hGTg-WUjr(E;飢d?#fTfmM9m'ܪ27ײrQ~ǝԶ/]y**MgE1k }*MqZϿAub^vge~CTmR@@S?,(. _Feo=-b,պwnlwg?Um9Rv랪1*ݾIJod*Ւb~dzWfvT-~o]?omKJ<_9Au~[dU|fJ?V'xKmQlֺ#%b][GyR:_?\~}"k8HxG^ꊗ~0[z-+ռs_be6).cJZEť{{HՆ{i߶?%A?د?-vi{bEW:>*MST$gުRf}JJE}Nqڏ23:/MYKL>P-P`%,9cUힶҴ{mV(xK }̗WUˋoKji*S-IJj- sEy,kQmJNQr~{~X`S%j17}%R|YzjIEƻPUo(xׇ>W4ݧ:;j)umk 5W)".MŰEw[~^zN}7w}ƯD:Bu|R|^KܘJOC2~.JSs_=a거VJ4ZM->Rⷵz>r#ү͑2>I}y;vtmW-X?LQ`>h)jny/VJ惟@T&vZ!9L>~:fNd@mRnǯKU6*;P%RE 4X. 3%U췶KE-_v!Ë=y=؂y {m;Ǵ=P4[lZnQ4VVj%}isIq^7Vm7 "z~HІ흎"m5Xt;RN`8OI{NO{n]Z5Wj!П.&\r[e0nh]9;m%m\-U2~G%G0vޢM-[|GK. jzDBɜOtd==[+S_R0+fMJfK٥羫br:Ts5RmRT];kקH^z*)Ǎ۪Hqit=yBGJ<_wT& A-ֿj{ v`u~aTj~MCOe3rhmt^ ru{Fh1va˿Ԋ~3 r׆8F; S򷜒;Qy߷}"u[񜖒~[RCW֘(Rr83 vg0g}?u~G0~>Rc~<[T/~a+mmwj98@(>y+:Q.-]`~?Z|ke|vJi9L\2hNq-zح7uzl+Ռe;)/뾩|s%u}#*dwLG̔S2_)JxZ\ÊJ㗹D.t0RAOc%^-ŕEtZU tb~nm]\ W)=wH_#nЁ8[:ΖX f})\wT?Rg]2/TiCҷ_`u'W+6mwǕGn-'j;~ݤP ~98VOwG;{+v"sȟB\xAPnZXQEY]`ivz>Y'̩v&oGz3R);8jOˠh[`em״U;₭୶aunN})ďm[rJᘇvxп ] I4lOkc՞:zpqi:?rR(ux\`5B~F- niYA'-hu[Kݾ8/b^r vD%lkk -j?秠xL;KM͸ h↩'j` ٲ⥈綾8>x)ڵ}ZjY߀<]NOaJv&t͚_Ku*;6E9ռ@O"ײ]mЎH;ہq#ߦ`aצK:tBt~0Bg`u'7NBO,S'*Oa~,FduO^QO2/?7;vC{ x.N)u~FWW2,WVmX?l]q6j6igTSl؝3Ts>gb{W?֑2Xڵ讽qzS!t`;>JNy7}l(5D۽пɒX(5 OwXׅ䔢^ )pzwL_dwD|e:B;;HU2T|/2R{?-^B9Џ}㣝>8}.Im).U)#QjE{ N=i\G։8k'.nҍo.NƘ%;)fq̓~_R ^7݈c`}_o[T.ݰ{=h0 /z#EY?;`?P9}`iViP)BN#*`#AZqi/^tf/Wt/zXu_ΥUim2e/z6, Uoߺ;i3?14!/_:wօvwqU7=Ȗ?H@[go|b= qv8p;||&N]wc&=X'ɂ?;D.)?2WGzŵ]v΋iwa7c{툇v.ML/OJ#:񋱎؆|%u@h$C=_zZPś8b_tn]XOW77=73;?]x>A>Dvx]𷻰؎xY_C|" M2'{u^L^t`:ƺ a 9V2G[%j^ZGZwFm`w7/\O{́>{892v =; APCWt#܍~"Ozio'P#Cd+Ik,#]jz]73CXRS٠=kn{ZdgkʂXJA/{_ĺcq.nȁs23O3_'.ᮿi} ;V7H`]y]XBi7=5x/BBaq6s;OmwP"RXgLwЍy>KLJ;W">$56s;vtJRXu.;Ž>Jn {a}42^3q=ӍȃX}@X"{$ݐn[]݁|4i;k,42w". v[7>]l@Ńq*uй=~:܎ QAZUCܩvBߴKyA܏ elA<y-n?mz|;gG#G=);F?7w"4q5zw7ś ]~zKY1 |6 ;zA뚝.sI_ݧ׳2ב;ءw!? z_X?B?=ډ.g|v_+z>܃ q4r<Ї]31qh[m,֯xNKa_[z4%<4|dl'r;!7v֙vD]B.}u.uC`}3VWĹ:auR3Yi:|ˢٓt ]n؏ż^WOr%tjQ?ky@ l?ߤMc?E9X:l7' qg|-_v]h75@NH>:H!#? 8y;AZh_K6mC߶BڰцvS o3}V۝n_yU7| A-Xj=Ԇ>.k~|`='nQS+h^5Znl߁<9BƼyu~_Ku}W_ {!}X.@;Ѕ򛖠Ÿo o#oa Q[?JQx_"EqnF _!NPېw?WBv1A?uvB 6 [ x:XI!:s]PܽmG7f -:ikzu+5m[M;F+忥GHc}P$ƾ$=8e.oN_]/&{~V r|3'o_~"=3X_c+~@=?븫lGlr ^؏r7M)J5NrKE;JwҾ_ȞVuT2?D j>xXA,O;C;H`^ch췆_;]JŶu+lmہ+)'Riv/@wauAKS}3(Ing`wb*}1/}cAl'6]O~9߉>F>z!M{/0ۻSe_- Uj. QqŨG2E~?A:B|7*0;n :JcG4)o q:|~QRidMg;)3HmZvjjkP{//:}iC1Oy%s7 1WQ Hqx9~Oc3ؿzC'L]}'X8t6E=2ȻHR'z yh;hW wB x2N{]vft2sudfXeGȷ|y<ցxa 3}ey)I QCS~O v7m;~J4Hv#^5n)nՂh+]M.~ h:Džu$G'.tß5;O2/ȧ[ua ^Eȇh<3-;`?v9)k{ҴgWtb>1Q =ٍ<f.gډW:G!s9Q/iPK7{ WY׈뒾@u!цuvC'.׃}/2dO ylφ:`/_ƾE7cmA]!wt"n3}G'֟`?t#q.Ѻ57!. ׍%'[>S$؅{S^٣݈vC_iE;W v Ԭϣ='kK9AB5 #^7@.Iy,ߧ`7/ۅ}dR=) .sV:/${yJH~:_AQ:Fh_؃l`gyӥ<'/KX^Iidځ)ivwh_ljuCOP^q>º}\ʋDt/zx< |<>4 m/(_:#s5hU|5y>󱿰@͐; yXdG~S;؉|.̿n)#8Pk o[q_vf[z}2|(Ay]9[h(zf#Qfv+EF7"ƬW/L4I xe.։/,búR'}'Ӯu^_':΍is yA֍unĭրT'o]װO݈CQ ~D{S7/>y|}iFF|-[tn ՜0T|]ȫF|=;DTe 3#Bz9]n m9<ǓƺS'Ι}ºa8] ŷ# (O4(r5/D^1;?1=>G K7}@-_NGojn1ns(q4s۵:߃s`ށ|#/iNV z EJ/|: K)t42XNoс4]a_jyCz q6&J7q E`3 ?mhI$u"ԅs!Ӹ.MrF%W4x!C|/B牚<DZz 뺱)Ľh@efa_&~R ;0ݸO!c^|nAMn'H4 tKC>GB/^I/\;C\ƾ /7*:'!BovD'sIP؛&@,{ \'藺^ІxA;g/7a>.sH^QNҾAsnRjDHa^~)6s/a7ͦ.w9$;9Ts=Wӈfͺ9fؗy&_| "OY D;! ]/QW9Qg{ cC{ g=N$yBng^FtqCܤ^5,/U#0OGaX1US>Z)*0Ԩ`_з8|>!7I5 O`TqԈS_i$I۸4yza?5,jD۩&3| O~uaAjDpfj47LB^vTS5㾀HWr QMA{Gqut0\5&`{-K}+Sjt ?V!aN A|p󼷃[TWR`>m ޙq"'^oݣOK9!kԤx4 \>gNJk}~x·KҸC Ѽ9&~ɫj O ٿ5-|+8a3jXjtiRjJ )GKT9?A|~xUMrfyZoWi.0U5{MCh8NLiA<,52݂̈́y6E_Ai\a;xo~{<4!j|0Nϫ~?j*tg*応h|N0C09 y<=(H5=ZR<BFF {狕9)A[sρ\}Gy&o`x5)594,-rv ΁Fo~%j :T~^\ZC<05,8Q#gF^$4+YuVkG P =˳֋ J\ܯuA|.'#0}'~rS!Sr8`.aoox-nRca\@Tcx$Clx3|sՄ +Aa*x <*|]`=BO쟷y0b;r4 <2r}1o[o^Ã|i\ OMzm,x`e55=cGA7|4rA1BrϨxJ7o; LATs{鹆ziu5Er? c>yvG;> ξjZ Ì8[]y5sy>sO]LM jy$1>mXh훙<<۴{ n8?ߏ ڱM]9;o?ȳ`\,όxRPrzwQq &3v.]!_~_O| c̼OBǤ`{|?J:j?!uiz}>Opͺ^>VBIN@~Dd`\'A}i3I5zT_/4փ hDS7MP\fIx^s أ&{j,3&~\\Y?P\q2vRpd5Ka'`w>F}I~+?t~@AL1OQSm3$]avN{9űHP=tFsL7*|͊oq3>:Ad xS5k:pݨ#5(<m1AH5.؇ZGuTԇ(x\JٷG܍=zқ4ѿ%4>?Aч/FL{Z'?3SGkQdQ|7>^O3XW\&;J87ur_>KMfa`?_D;s|=x c%@+Ԧ+<>稧W&FuvѓaV ޛVn<>8ɬ v&BO`)u<#t+jhy709䷂7ҿka78?&ct5M.֛$+cfܯU: Aƾ'C=;` ?jH'<)NLv r#9x3 1]S\`ԏZ[_|?QۘoF.)c}n8+0X{׀uq%uxf} oPp.hZ0~Y_yA gr1vhXYGZ3oll:qSjķv Q'Vܖn}e qcox)*k4?~]J?u׉V!Ap.fO?wX߽FCN yÃ0ƟFbIkT/xYAP8^#GPǃ'wbLϡxKaYD ?R?q6-(oq(TѰhN'އ|֯|䷓FT?Qv֯\_x;sj#?xxm=;OV*ƙ%u0_l|>ς 50]'6_!?vy?/A dN '>uFd_hχ1cߜtVȡB\Wˮ7vG Fχz}̿1y'TƝTr9arZ7}Et/'gl+`[ <~.7yatӃ}O1O r~[k=܏gjKSo}&hvJ֙o7xN?@~R@,XRk>)_ l;N=),֛,{Kܕˁ47hy$lO&OzW1/ҌrihΟ"X>?M\w~I>OGG\ʓU'dXnp(+(.N]OqvŸ6xo# ?$x_at;~;5Rv2ɿ䟑3E͸)zK܏X1yAx^2ֲs 91qAX?ߴ_ D+vpNFS0!!}gA#(}?y_1!KjS)~@ Uro'S>fofW}=5+h_&k??Sޓ#rjմn4%O ? 8ghT}^ G4W)Ίxz8f*Ǜ=k̺Ta.ɖGcNަA:Ӕ`Wȅ5`]?mmy4N$d?n:?'bX"8K |FAY7~RNJX'n?'ޛ㰕rG ۬OQ}p ڇOz]#)~<kZ#8_A5 `j` ?A \̃Ki9?F}x'.~~ϥ8n?|2K׏95LrבS9#;?{VOp nCyU,1n=AOtZ;8׎eg?AwWsW&n[+y^-O&Ok̫՚bd`~Ҽ͓9g竼Qq=Ѓ~6s݈8ǩ1^W4 V?oǑhkM{]x|??OX[B>|}Ή/sn_ێh>S9+gۭ8H&덤=1Aʴᄁp/;IܱeGCG;3ksZ߯A ~R+|~q`uKklY+V<Qg?i2NO c7y /cs^ 䙌(ϟ0v;2.&m_!cun_~sΧP+!5L6?(AvR;q:Ȯ7'{|T q%5F_OD;򸈱}nch{}x\?xl0~Wp(~Mk?ǁ YOa<5ߪ 2׿,qyqA@A wZss o 5^7q"?P#|=%<^4-uv|YPϜC?_Ucz*_OrNOz̧;_zh|>Fc~F41zry<Y5>X;$\Vye<{3}:Ś 7> ~x6?Gg +'c"uIOrpoqPk1 @A` 9o3W]=7?G[ng^\xS{=켑I+F[^Wǹ_5V;Fn>ϡln?(?,f c9,'}GG~PY? oKz8=9RέR+59a>RnO9Ntp^+ܯO.稕,_|ER~.Z ?-qWe?_e޿*f~Y_i/3/:|?$y~dך_ c?zt@ Iay _lǬT _ș~ ~PScpp.{-iPyģ> 3os< mԠ`9ϦCeɊϊ7.+6~Hy<\A%n,)_ɲ+w@_L'~..~K+^ .yiosJw>9˼>XWbz7穞 Qeoyp38ļ35 fyo_DuS8xLiaDXQ@6C01V`a?R'&4K=rR7:6ցq5PHԚ3Fָ}_h}:Qo_LjXV'։U`(a:Q/W1xdx5ggYw6l#@cP3ա֘+?Q}QQ'b;Tjs?rꕡz z.JJw>S&@XZu3BPD J֪-Q+avDc Z6K-n(;z*g7o걹yVjף=Un|qΣjQB5՗Rƫ-QKjH-~WوC}ZcBum5άǮ :MT5٩V)a:PKרZ6S:dj\#"As-ϢFx @%}T6 ͪ;;?q5P6K~H"dxSո7$sָɱnv ԲU6Qvl52) TMո*QzBH 9|ZvQXny&SF1QzUHD=+Jkť]ȾǺZ<~6?6RWa2SM|qyahtnT& PE=H.Ya2<٧au js–kt Y.ӲacsV'lk˰([1 7j H~~\@l[v0#[|[J._0J),_ɱhdkɄ'^{>RJ֣Z (& 9ķ`˞g8;sk[{d T/ s H$ E{)4f-DɶVq !djWB@>vn7aY7_O*9J>Wʔl0!ʣeݩ\ish9v;$4wj%kujG_LC*Gc)GGGԇTGzƜGOe?5M!=)zѳi4Omt}o˝wR[T?XQwl;غm{2 P_Pv'qƎ>FLQy| so9=^>T0ۑh6@mYXA .v/kYco_}YoҞ3"_,[:mq}/64fKCޗ%]n[3@K s_ժ( ˚.u`}_K،BZe߿Fe/*s޷e3SN=oEGyFwiI#o"}lo[/._=C(xh4n_4] QxK#*{)ዔ㨱$ d9ܯ՟K_ \~9Eߥ/o>2ei:, t_|6_VcE___V7RN_4r~i{3P2slKeytiUF忞.Eɲ&R,2Vֳ^gL+ KS[UqtRHYk|\Zue>:ҐéDrn5!}YOoVFRjh/rz,Q#uyjw UjG#Q,Tfou^E]#Kԧϗ2UzG#sW[3]k_G_e\md#튊EVǑMU[oͧjTlQm_ԩ<\u_Ǧ66*-+WW u6\|]qy藍Cl _o/ I,1hKzd.fx)nwM5!:8(45UvJE hg9 auiMMAҟ!v'VW{]#}\3}d]z^mC~/RvggS]J}Um9V&!Mg˰zS8RaLZrAtKM3+5r@yPͥjz_Q='F/߰׆>u/Ո իޟTO[뵕hs_ٰg4:V)Eq~_8RԪK?{_=vy=ϫ{;Vyߗ9hj/,Pަ{g__dV0$ڰyhi~ח?]^[;jՖj_/՞.(7רhY}F6&l{l9ϫdST㉰()plC9%bF_=6otX_x0*U~#Ԩ.iǽSMM2W={& z1Q}T\%W/ש%t-MMe4Qeʲk}Q{Պ_T]Jj5#CaTkwtSseuFtOԺ!~}Q󲞾3G8RVfgWEqST9K6jUFZ#}Qh0۪޾oVeWe7W>.+ߩ?(٨'Vd?JUF%sKWKzF1y-]K0[ͦDyx_9f%&'Q0:ًQ:(. ƝIggQ)zI\a:r\8ʿ9%/O>V(5jȰcCv2?w$/Q(*396v=W=;l|٥( kswQY/jW-+?OC80TQyծoɮsXQ튺>lg/\{q>>ߨWɾv]Tx<ZSQG.ۦ*۠{j]z]aHD}_s'm =ϭqg|ƿVzV3j,S__ ^ e۲?϶Ǽ/F^CCjWy7gDS}r}_qr#ȸ MSZovG9j|j}ۈ\TʆG}igL/J@?L)չZ6)rҲl^fD9vM5ZPoZ}]l+^Q}??l~Ft-0;#̶o_P͆@-=SVOגQrc=3jS9mz&afkGo=cU_5#ּO՞KQ>g5^8аbG}[Zz0hOlD}qk{\PP__+Lk͠ʩ5lgغցQvB=חq&'5N:y.jPb]_KFbd[:l\(yb_W/wè֫kSs5~G ͥk~I#vje'o=eDg=QP6ƵvUZ2U]0ҊFe-l|z/3^M~Qu=}a[x۶z^-_ziŪjXFu#853]H9Q6|=m ?z7o>ߨ_+64XR}Zv^Wjs?񯇷8ګ?vm5zn/uF4ǧ?Toizײ:.6mP}j+~_uK%9?﫼 6/KFƭ/Gpw9-KC7\,-ȽKa|6Psaip#9v`#׺fisfzpY>gi/ˆ46fڎYvZ"ĨB6Wd4lץu@rͲf4_}k=[F탥=־^EضKno]3@|x6*WOhK\>e}iY5V==Y%g2۟jM} y]k{#e~}RFoݾz XYϺˉxmoϩZY>׷{ lGzF۵˩w<>5__yUMe^uϣeҒ@<5x_=eLϭ~֣v5g1~Q|Poy _zD_A5}kxk?vϳ_- y_>K9.o9_?:>֟o>ʮ_|Squ^_ i d.%}ZzwjOTץsk |A|}復׺y~o>}>Yw4羴8:[v|N_kI_k}Wn:`gv(Y夏~գ׆[?@09맾j@:yS}t;*ʏx{\YQ0{ ?z4 :`}K+/sxG+_h{/,< 75,_r]/S}{N-z^k `j~[eeUzFkҖ끒=qzҖ/{~ Q=kT%wM]E@~ZΗK{yz:K= ըg_]Z~==^i^o}^oZ_X_QݾF7]E祝_yQM ~߲3Sz4tpSϋ)}JЦ+d{7›!3}~ ݉5iwśw<`}wޝo[۾a{nPifCq?ǧ?qO76k6s\?7 ǔ2ScpL)1e8 ǔ2\SkpM)5e ה2\SkL)3ex ϔ2s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3%>s\3ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\c.1ĘKb%1sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3ęK%q8sI$\g.3$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\`.I0$K% sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I2$K%I$sI$\d.I.<ېI+1B_,m6rE͢fQn(Y,m:\GrQ#uD(:\Gr]Q+uE(庢\Wr]Q'D(z\Or=Q'D(\_r}Q/E(D1QnLD1QnLD1Qn\EqQn\EqQn\&D QnB&D QnB&D QnR&EIQnR&EIQnR+YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂_5 j|,YUfW͂W+G#|r_9W+G#|r_9W+G#|r_9W+G#|r_9W+G#|r_9W+G#|r_9W+G#|r_9W+G#|r_9W+G#|r_9W+G#|r_9W+G#|r_9W+G#|r_9W+G#| r_\W+W+| r_\W+W+| r_\W+W+| r_\W+W+| r_\W+W+| r_\W+W+| r_\W+W+| r_\W+W+| r_\W+W+| r_\W+W+| r_\W+W+| r_\W+W+| r_e"HL"F0`C ' V߆B9dOK2P%.4GlI4ߒןnE.ҙ'9BD ,#ؕ`O@?FȆJ3REױ^4f TP{qZ'ڏ?K&'Y F %F"5Kи@Z Z1g>'h\ U4=AOF%L' ~=MЏ`mrK1Iڋ"rJSƓܙ'u $F0h,aGx?O4(BtGK8",xGh"'>zDQ(A)`;Z(ZG ;l+^x1Ft; U hqC1N~>^J@4 ZM$/8RRD))c4Et">MQY~Y4,j'&ݑ}&{.ۯfOIޅia0Yh#B{9փt\tG(z]+F(Fc} amH.NIiDq8e!A!Az-Ar!=" ,[C3)ɂT>KHM@딢ˢ΢" Ƙu_5=X,!=4ے~!7!'a8 4LvFh0L & =R5d¤gôaeaЋ000Kۋ|"$"4U3Qj#J%zj(m=uʾ8m`{$ HFM}HH"ݐMZ8[\lAcmgCwZğa;!#43B㌐=!9!!ڎ^GX>E޶r?C! dGQZh2]tsQ(3Jr7J\ށuxʙ_K ҳaC fIIDžI/Ii"7#BGTiZǬ~o=ZC@d?yt/qdIFI6EҺ[ߗ YvdyI;s%9KlAYKZV˭/ \&,L'k aH<v8Aacᷡ/oEY_H6H7иwƸ JdѸIWeW.\gO&Br&>V]ôa1>ogXlٜZ-l>Gi-D[.f9%ҘQ'kַ4K#Y###_nGňnw' X%1'AjI_ƚvMzB'|lfuы|v&J Q&?!/!@=eߕѧ Y΅r!r:;`5|hĄHV>mmejxحm~ 9,kB4۱ޱmJfͱEi_"$Lܗ0 тtĶQYŶ񇓬u 'ĬDo`;c24'E|#L؍!.Bb|EIIIilPc{!k'U k= k%CrĐI_EHh&& Kw_bN,+fT+7'<~/0:oa/b}vO9@!͜UZFIF ?x:JrĘ߇Db{t98]'7M_~԰UKas`ګq8Ɂ8m ZɊɲdWՑ]Mphc } td5B$dlN;_ φi";`K8%\E_vxblq\tUt|'aZX]pFF7g+̹h.1btnN0rb 4ѹolnc߂mqUXqliP^X?̃$?kqa19K_ {lb$M bh 0m{"# ys$WM5Xe*9']/4(bdn,gi<ѳ'0k sp.FF$4$y)ao@94lZϜ>sɱVc敁!{Mkkxdbd+$Bf /YO=!9yD 7g,ɷ3&^#+c'JY2JP 5868٤ $GEZG?K?w[$rYM]GϼVX=`g}<:l- 9Hݱ?|6d{(Ds bliy9}"d)/>WZeerm,LÏ z#@M|e>&j8SX^{s0s,mq'܉̃XK@s;@NAx,?ؾ`LK1 ˂181 /!J4uGɆ6qG88 N9N㋗:41[;'cO_1$7"A [okf31!yqyVúgyɈ8stK./I>&HE|Fpn*5ަhR㜐3/Yx?ٶ tC|آQ6sb_.OY}̋!b pXji&_m|3̊lic_βu7o`. MimGkj|o;=yO]ƟeHkodOl"~cDkhIƏY-+hm)Ik$*I#I4\em?agX̹%'@~8}#y8- K?oply zʷ|nG<^f!'a[o΃:nf(No]ĩ8um v1>9[;jd/$iOhRG$Y>dXl!us69 ۾u߁>dcymiόOihkw' ľdYtBr34HIolm 仉-~`Ygf21#LcCvvsaD=[2ʲ(z9.JdԖ1Y- HI/nӚĉ/)A ]!~b苐8.1cld9^*?s0yL+@gޏ3Op{oɭl>B3EtEmpqV {k|!m j;1,vǩH/9NIPwiN.=T)=e >.> ǵ cDK1Z7sE{grVXM"UXw@3xn4o:l,$ǝN*"!Üf&ϕ}'&Mw+rx8x{2TWVOC.ucLԆw $sߜ$Y$O=g\noӭ\mysE吇,ܘ_g㳷طyXR[&|[ط&7h{ob_AVl/Ǿrxo˺}adG>|JkoP4]h7N9rYx9Sh͓/۸YkM'D N2,JmFwWל=K|ECsV)I#xw9|<ҿ&FαLNrl)lH ?Ŝᐛ|11&(z=?D>6H>81]!Vf!)|( V>D9>qĩ6c⳴e>xۆt#M|MPp6dtt.$c+!ΰhK}+`y o{obl8͂>'N"'dj(dXvELċy^dzq0u<#> Jgr׍M tA?˱(3!W/`?,?BK&W >7'ˡxa mdb8ZYmb]sv|>Ky(j'1 ;"׉d~}ƚxg$fRh-E|E$`K5g6?qAd~'}w8nȴBs Ys>d6S6Ǎb8^2߲bcawqlA_V%Vdr+ج9ag3p|7}gsr _"ݗjك))Ro<㿳Lc3'{=>_ɰö̢=3VWc~~ +ZGC)d۳4NsƴkhM5ǧ.mr l,Sqπi;^>b_Ĭgy.P|sl_ء#KӼDez KN&[Ԍ]"S/lGlែ3ym-?63gZ>Xm'c2iqϓO=!e>^h\au`l2Ty/G<`\??DtlbE{ql̍i&C<ɼ8  ukiӛ0tIJc|gğ&},olAX[ğ|ƉISdצDs9¶ Hx`:O`y=zf_>:S]hMn18,cٲ&g/&d3$m}ңK;X¹f0&>ucht a86sVv}18H+9Ү'6Ý#W2\|F:43F]o37]3ysZusN6-;&t!KhM|Ĭ/ص؆31$;͹;yizLdG6v1 `C;B='9br #o@knL~ĩ~yS伎.x:cwY@;r4dnFG2-v{,来]B{)|bP6ziO_3Xk0d6ژwbqq_i`㓬HP;Iz6Iz6d/E| qK|iHV\w6jh;W^LͷucaN2R{/ ĸ}Jc@|6g+$sD;pL2ۅ 1ylgs,~|;t?I{c޽Ѩϰ ?D&e)d;]bmT;D  rV-r#J6ɷ{,=uKM8 a9q9`;XG`062tk7Y=a"]qm >h-h3'9Lzka9^ʱ c76/C.,6+Si,h&ߝ7u #+}dryo%ڋZيg,niυϗYԼq; bDm#`jIfHow]sAs˴C㌟Ew8=~g䜰O&K0&^>&ǂɾ4$S7~HWrȶ x iM܁D_&>{q&9 }sk>G4B d9ZwNv^Vǚ<0^ϐCvgM> >#Q>2kw%2`&gmPCuOv(DOa_rBĜcAlks|Zƶ&&z~}\},>}ۗ|^m|>-Bc5gLhX9 䗘wYLg|!g^SZimxccX&sd~-jSdÁX =sĶ"R3s/1>{67Olw>8Cs=h/|0cJԟ'{oGX2gLwdKs;2bI샱g,iOcg9IpX0=9#uaZ_CAhMК1c0_1?&mPm|vblI~ d E }7¹ Ԍ)k=1$>f_}O@60/~X=d#i^9xkКyOY9x,Gdeq%9'g@'>eY& ۡ/hc8]o>o2VY2?}n1yp,}HÜunzB׿`К_/ ;c&|"ӑM{bAs2Ht{?KbЬ8;ws6K4j|f>x66c5=ȉ&9nZcD&-'}1l&C)Eu9: )e8+N:bx߱N]0ٛ`m px|I:uL+M@'w uisN<v9fK$[|{c59_iu!si)^=H&ןϑn4|&~l('c#(9'.I#Β⼕cNxwj!+"I=La⎷YT#?ErÏ'+>Cݡ59wwH'ۍy6!8o!y=Z0qt,vY|78;ɦ$% Ӝa,΅Ly]d}pv:ڐ-,/ |=1lN1zׇdɫOڶcBk@u0.8J3 =B6z_/Hߙx? !uz!>Z 0|~ 3уQj?qs^g#w[ˬ+К|Ckr|}T41g?jμ<}YѧyaNzk[^`y;SΧqX窚/wE||o5IGgm%}]|7a_h|_p~ŴB:ebsG/rgc޿Zw|03óH{b"yxnFvsFr,Ars*M3}dD 9[50k}!.D]ދ59zPh*dћs> 3Ma{^e?mv& ͹ a_73\.ގB2z&lx76=;/o[007z|o#'Z4`ۅ!n2Ǒ4_sʱ"M̔#lq%00~5?sc;O7+:x|τ51ߣ 3 !O䛰#YG=<|h7kY/r cŜGj,,}}Zt&. {䅱ٯ!!sq>|q//J:ʜ9ͮY/C염Zc]pChͻς/Xr|gl1>~ض<{cP59{A"C;*7|S4';x%e9Nlou]D:/֜ Ot}rc|F+|fki9gOc1O̔xN[3n ץuVy|l+rd\dK2NEsqFPxiNV]ރ/Aϫ⇶ῠ)tQ,JߢqKz/oM(xKukՓO{ ~@ ,'rC<ˮ{P>vz6`@3ĺ 'SP{aK\N r+v?ܟ߮mε, eg}*6v l]t? k˂xCJ{\A#qH=gaO2iOjKz벞/]G0o~ar_`]ѿ{f#gqI{R}mAO>egk.`qIK/>>i[_ԋz 礸[&Џ? XKYƵ`7Öޱ|#ؿ^9<$oUv\r])@#ϗp >ߠv^^2`/Xv/닭<_{%o4] g,9K`_(ϼBԟ{'eiF'"ߥю\f'^ 䍷YSdn+kqL 奖Ogl-X/]aa y Wa\U/o?z ߃pv>)Z/S?pMsl?"*9ԓS~V%W~ʰO_orڱ鰛Q92N`s0?>ew3aOuyh~b^0_ Kr0/a7KyKX[ۂ˄'հ{ ߲rQ-,_ ~1`\}y'y r||>s]xߎK\syXo]3S&b~'ט~OҘCDӈLo)9 7A;N>t;n7OwYc3R<`\y_0v]kvk$.|숳A;^v=zPp!gR?? zO])ϩn+eROsjҞ+=.ŮyN~, ~"  #3و#j;3rADą=o5G_Ov (xR/gz^ol{r}kb2]x_ǣ@3˄De'v# }c-}ejo$mcǣ@үͱR },Dq/a/kbgE|4v43`M~Dmr u< rcK3J;~o_ׅ)\bfK;cvC(;x>'-KWsW|vh{`2xn 쮋a1J߳Xu*9/>)S>b qB7q-;zi|UX_`iF=/S"9B δT8˴_ \-Ȏ0 ? dd~0q_<Փ?.\yI{szzyuyNy??ʁ9r8gJ\v7.xQtCKy*π'c]DGʂ$ݿ/LhB:uyik/]~N_W|q|T .cz߃$v Ɓvj"׋v,rtOlp:t;-;W[3B8r. 1c9)9r\ <5rFrzA)I?Ҿ3w;[2#vyz܉!,2ۿ ?@m~Ĺ)# g(jgKןy9<7wD~H ?ićҮܗydzޯ/u<~Ϟ8=rU߄EY2<5{'\s"C E;s ՘+N,Ule\~}^qM\_|"JwByRƍr},K>@N}qVʆ?W1 땈WV=i\%8/cѾ˨/gN7 Xz`c|z!~POYz*}srHkG+J 鍷"dRK*zPp9~W e¥x^qqwRqpy).8_gz.(㹠=)`n<>exn9 x: <\9'97γKjлXΧwy~~O9?9,"rN!RF]X-r?QI'3՗vKa}#7ūϨ/2;r/ vE'XΑ~jv!oR>^9j;)/#츥$?ٶ/yX m_I^D9ֳ;+%BK&v!obg-}˰n!ǃ-2GY%yr$z[xz % ;Ѷ}r(W G _9UO}/xn1)[zsɠЇ'N>iء.e{!֡[vEV͂;dԟ3Nӭ<FZ,-v6` 侴ח2{Uǽ< qE7~yv֋Bnq Y)hKʕ7.XߗJ!_.rP/`eR?"r]/? OD;8rfzY\x8YvrhSџ<' `_yK>z };(K=_.嵅;qT^xTaωxjd>ydOAu>qIYѾ`_ 9+DN|ғ]%uy?ؿ'xBA/G\=~,9|Ey_6\}u\ ~3q+OAzd*.E<侬Cli< XO5΀Kq^s>Ћr.a9U r>[ۑ}#9,HٟWyg.sq #XK08]e~;ui_/)\:/sO>ʹXyND{Ҏ_Ww9'z\χe|_oVo/q_z>~#U))}eO^!aC]F`.eQ'p[w=h7 /口Js>8ד~|׹/[: cC.Dk~ԎgدsRQ`\SO`GIAho+#*%KRa" 1Ű o/q^rg,KXm?W\!x)K>Ωp/q\\I9ig:-  xG>l #Ю85q\=LЯS"<hNA+Zq)qռɐWGE2.־ەOە%~=_;s2Nmw.}z{A}߰g5b7T<; >B{~^1`id1h^0;OYv~wWGg9)K?Rܗ \# {l>䍌#ysq[F:7\,קa,f!)S|Ў؏R&3t8-JY[~A^?s~;ROMM R/ ?zqSo8LřãmA%_{oA/IK╥p~<zx>DΈ6|=MR;0swv~#3Or#u9?>s!`_12O]/uA(zx~؟ce侼DyOG#:9'{ulR2_'XoGHʁ}{4Q{(;3vn/TeXK}NȮZ~/-`z堾~qvؒ?_ X!|R$]\-Gǹ̛φ,I~czr_RO]>寧Vog`/7=R_ύ_q-}'!~82 ŮrF~?UC?4~_=؏ ފ2 <3r]\.ga3r_Y|`/ unޯ/o)8wSJ5=Kg|N~{Q)Kg@hWT DawŸ+W{xXU)/[5~y+r489,9b!ȏ8 AftLNSa,kGJ=iWl]W^ߢf!r,\3{[zXoIYƇqUmn-E .G^O̓(oסr?}\ y?!:<3'I̱wK\|tۯ`g*)yLJY/L?$~zA9.k,-XW),åK ·ssϬbgNx~V}ٓ` 8u\0Q=R]A)o/,~K o ?C}~>J }ʶ+t#y_Q|cLc /L8)BoȾ \̂\~,߃.se觸/#[%8P=(Xڑq9iԯ'CWe\DYzrʅ^Y|Kn3Ag_4qVOAqh_p`^-u) < jA{OW@.셂[ Ιs=)? CKBTߏJYz| JpJ?.Ӹzy|Np'~p_/}>,]K^W=8CS|F~WA{SXkg1.,<e|Dn!$q0)y޻U$}:7iq,w,'9S$΋č`\>ٶ/XJ`2<DžwT_{P< e$p)۞z'F~.{mIO R+Ss|ǹe`V _MrU?;r=(c<~9pWDy[o:;w;w0A ~o-mE#,>ʵwXſ=}B=~נ7gzD8]C`9~2㾜 ^^E{*9,+; g>rFۿ<_|q9-SB|kw~V(pe_Iyx~t;9ժl+W@(US^"/ED˭|?@ 79rN$~,[fIX|aעxnBIy%̒#Kre9?>]pCu*TU՗z5CM`=GX|}؏r?bWJ=\/+]' \ X `^!ܢ/m-+r_bĕzKG(fCOͅ~w_Ν{wAy+b\[Y-rNVq |2؟> ]@?j|\C`k3R yRŸw}\:s޴8c~ø> k{8@G[zXo ?O/r9R΅8Z8AA//~jyD7\2Wa^ _0_w(ǰGfNl3yUWA=٢ X'X>/]<r2KF |W:)7bNG;SFX:Ӈs zK}`5# { ^X?bR.z ys}=y"+KA9/{3ώ+~|AY*U%@W`>%[8_3aM¶?bp+ },BYs"%\sCr}>uFץv?Ar_\&,K}0L82ry u(@=7x,⒒,y~徴#g幹%U򧃼 皻! qk~шo\7KA;lQyoo_Ïw7/8y]2Vl~ݤz\ÿ܇]'8gO\R#K`߂r?s~?6ހ|7h{w JY30GҞ`A7gc\Arϯw}ig2`']Le/?wk/:}F\;V/wyJX9迒7pN2?y|Wg=ۜ~fbb=f_uO: ek;H\;a]uGsuGNKSI/gO{zR'+%twZ_ߥd;_{Ǚ~''}u9)qj?]Cylu)K|;ў}, KObg]&ebUAJ9p}r;4H=3|og2^8w.D=L2iO~Y~YJ ~;Rů`Ў\G["v}߄CnCg~O1y'_G92~Y9=|/߂^q1ňӖT@el 9·Bu} ޱ4 p},@}[^ eaoŸ  ʶ2o]9?;7A{o{sҎ]R=C/!X/YXOtW/EOw eT2LU`yz$*zG{~Yӗ~3sO)@^Γ3:Sޖ|o^ N NT/xȮg~ t ػԓ8r䙼o|# q~\"ȻU/_$?:k9@NٶK;"p_.XDsO^E\by<#NY{Eb_ }'eO+Vz;,9N/e9ϟzYp=1ܟu)O $|.Z{G^YEyLWms7%a/ .DZE\:}b5ȵ z{wg>woB~1濇%A~H"4hWP/w.\._jk吴v#* O%8-8(H|v}{3?.` Lse?3[<9Uoo&<'{qR+?X [΁|G΃H΃8A>ipw=&神Ҟ(׎K?s~~\'Y_W1%zP/],\-γT]_®+./=_R#_\ ? ``;~ᰇafacW!m{yϔyOo: +T@IXUƍ`9G9'8+_5W(y/\}`K= 8W#i?=vvk=$N"eW6cڕL9r}>#X!88gOwF}KbN~˕}^*; E)/βZ!?B5qYkw;!]#{GAq@Nj z"g|,_ qγ7,>Se%;^wl)yX`|_h[^7;r-ZPc*/@m{u5~CjWcٔz ߯S[9~Ck2XX[ߍm#Ә3͡5ԿIݦܯNSx^}xk]˕>ոַChהm*dzX^,Gs5e gCƶ{ͥZ}5ƦosFs캐o}x1lci  E 鿮g|:ns))ꪓi\MP-W~cۨVv2ko]ijk_k,!%;YG{5>^Sllz]t![_Ceck lC^So1m4'M7NC\ZgNCemKCuo5e}jgꧾ ]LoگvGCױ!lH;i{uU[L}d곾< {k_c1U!tqfjg:ڮI}k|y1A# i7v]mU!Xj( G5ߦI]kS<# k.:L}֗^6m}ؘ» i'ӵPkXI7FF6f\ZlLZP:h:5L6dnA;J7O]kߺku齺l.9V߿gsSZPkޔȒLϬ14u~m(u.t=|O軩A][u););uW-7ͺ[J7GRW7?~;گ?_&ZsY|gИ_.[k]\[>LC|Yל>F}1m]\>7?_>Os9<޺[۸3W~Vw}im6&S=Xcck,=&S{Z/Vn4Cs[ ^߶[sWcx43#Ss>F]~Gci7q67BM纈4jscF% "?Zs"uϝ %GYYl=W@7/sd'ԈqB{S]ewj7oG֐Bā@ ˁ\ZZ9ցvttt] 0A q`;#[F;0&l ځ hZ` ```&``6`N-00߃Z P(ŀJer* KK8-`;v `wt`/ ? p;҃C=8 pG8ځc8ptc'O>|ҁoyG~ z X-$H<--jր6v&N.M=}`6 lr``[F`` $&800,l;:P(P (sJ@ KX6l =`;{ `W={`?8ЁV8܃#8ph1c8p'N3g9p6.AGP=OzlAg6=N?ן9I=cV雧`1A^7G?׃ޫCnv-.xs~;{K]0X-9POk n-'O;![UwTW9W/MY^w:?g_tA^VuOtSMG웳pIuV<޼#n7||ocGћ}9oɡm7qpǺooo^})J3^Gϩ+t =7={#8s뭯w}s=hAqwe;JzT;{'vyFzJ=?A3tUY$7ft|onvT6~WRݮM ]#>Gw6#coįK/缿v<~?mEjswؤ.K[ux]f_2w= OzE:)/y36"~Ct/hypf ŧO,_@=ٿp{9}D=uVV3zڶ?fj3pоAf7[zC}Xo^ٓVG~{~=jߪN}z̗4ӝ/oAǾuñЩtѭJi[CJ;POnkelQm/inӃ/lv8Gާ//H:/W?=|Ywo$bzDƟ='|xToYhǖ:l=yw_B=גw_nH=u'yh}]_Gn]w>==pj]BkfqSCxaTζ2jgڵz{t-Y ~zx~[=5;tGop'N>=ɳO8=˘t/ )уN?n_tnt{U9x>6y89Cw~ɴBՃ>lqau:v qgO?ڒgBZ\h&mmovzeWgm :q?zO ||#?:Q:}WzXiox-uWL2,"<9Gu$n'- *5lt3H}h#tiԝz)wcң?GXF|C{˦?x1=¨zǙM+0;"or{VGL%״Θa2pNmyA%;~{CtzgS8JVYVv>G|0LpZ}z:Mn"CW,N„t9/zD7dZ91ϱ'am7mwyfӯ=Y[_{(\n_NYKWڥ;!miY|<s]<|7}ב;I,VagGz|5'}.Yu +zz?aUDm$2R˷[M1|Zf{=+~zJK/]E{ W?z Q<;,6zfxȬz]Q[hKmbTEQt.i_;x:KmB {0ʡavsLwgɻuoӟ6?|g d},A?n5$֗s+e뾇Wn,"ݟxv6wxI/?=,^._213#wzHG {-L= \EDV?]`঳ԪG㧜gˆȅ41m~,ktN#/AO=˝vBϷП4[o ]˶?o{dׯv}m)qk]X;_70zॖ>kgk_|(v؃:'Xv}Q=s3a֣4?a~>c3C<ݞ<=t?XͯvX難w+BSA]0d[cokƑΆ<: uwk߈~:2޺Wl2Oֽj>/ڴ[>[ӟt?`V9||gmj ^f͖o /mR]|9gzK$3Oloۍ5.l)6)[m>r֞YF>֝wo"yXǦV^X.֟cX Wћdmݹb?9R Nʇj^_aeQ+݁f~^ۋ# ط?kko -ڸ&+mnO&Ց)fuߘ]YSw wrxg3N/zj럍]'|[dA~R'f=>ѽoIX!{Ȃ['5MHg1m~dǗΐ;![;Dݰ .}Ozl 651B!W?}`/-ѡ>? WY})k$).[N#jzO6mlHR,v'fh=hSKCYݺ&oߪ~-/3qW :"QOظI~{(k75Iɿ֓l#tVh1K'[bZ/q(m> ֟Oؠ?nJht(V~]{[ӟ#~i1sε[^nvx_ϸy.?3=뽹_kNz<{|q'Gﯺ[֮:h zdܭ4[[~5ڹ0FvYrßj O977H¸shm]y"e]2#Or>{=m:[} ڿs׳pOz=^#%Fl;3yW[#}!eC`-wѭz߹wޢ, uGz0vc=_6}No.0I滲áx\KA-7|>a76}#C_MiPJ΂*V(3r/0wCȌ=ctoHy;o23N֊rDg8vGX;^+&ޛ,RmY9;M[tȶ[}kOnK+#ڱ:cva$eI"顷|yqt/ğ|c=mPRW+,tߌ}WGe;;[ѱ|koG~DҘtZgq~E?go b8,T#/Gף^{~9SaM~,T=qcvOƗOmcskikwg}}Lkk1F?^mVE>d_82qm请[[_ִ~k[N׶V}צ;fj?eG&^חڣy]c2:GgM2[ֵ jAR]t6}PP]P6^ !~Km6A&]P[_6g+Sc}o۵ٛ4t [m4X]OhocۘƲ15zԗ'6ĺ:oc˦7w]i_2uCְ9e`sېcCtc\uA鿩<k^/zXsMW/Wsk[!sֱ eܟzb$k2*3YG յ@}PT3>)bvyb=\ Rmbmcg)|=_^ /~*umsm/data/bos3.rda0000644000176200001440000000604213051600620013310 0ustar liggesusers͛]t\Uǧ(T(g \ BB+ҦmmWMҴ T .\.<\bsl"i}(ss* 3}tѿM+,r,d/f1:?itJ3NCJ'NQ.SNS:]ݢޫtҙ)_YJ}HaEQD>t'D*}R<ѧW(]Y>'**+RETUXϋ ҥJҗD_]4G+J_U\ ה]%ZJ׈UjTh7E׉%w)]/A黢nݬ=QYi[E D t"(.C"Z,Z"j---ݥBRn*=JES_ԮhhC:zF&QfQQGWOihRҀhҠh!N!.ݢ=hhâJ=tP1JO)P#'RODO~*zFggE?BKs_)=koD/~+zQwJA菢E":]+lC_Y|ݓ/q4p>>uUrn/e4wGL|]vv+52C4XqpiܒB?xMO7uf]i\'xK4؈Mqё4pKߔdi~f}c|MWy9.َi[ƾ4poCi~NLrzMs~ϊGGxim7q䷥=y-Lz%YK:b_/b;f(#olE25uqias^4ߗԷQ8962>h^iOO]i=[d0[~i~y~sn73|i|y^W;9xǜ{qד$_ :kyf]wem6/9$?ԖL?W>>tjjw%oci$f4֐IMi={97ؐ+dXLs!Og^O4ɸ4SO9ݭiۼ޳|GMoٞ7cO#ކ4Ds:My4n7<mgĵ4^u86Ml,eM&nHslȜ̾=oJ\]V{&ͷ>e"aylҸ(c}Mh_K>6`?:jog8_7ϱlyn5&B_ϥo3פ: ׃}7~j8|lGH<智{41׶5ԵɜCh֘#xmefF;7uehkJ=i%C<+s﫥iYLvS#imQ?>y;Nwg}Oc?uc?zgs;uLy>`vYTs;a~c}o{Su^:o}c~ux({;LxMNT)Z?} O)sҞw3YbzYDx'-nnYp? 5?I-',m8eْ)iJO> IY&K8+ř3gX[\tqE,*.>⣋8..*k)b-](p Gk96ĵ! qmxwCt pQѥ]ʱr\[k+qm%VUUUJkDjFjFj=qjܣZcFXa1%L2L[Y f%`NQGey8x\ǵBeH92Fe Ápp,k 2p(ár0+ìPdEVE[T[o8TPCEVq· _{W,bZa1%LӀiSlQ%l.pW/p `Dq@9Ǝ0:@ Dq"88# pq _0C 90 ppC3䀓C 90C 90*} \f'prpp<ŃZч`>`>z tH tH t@G;(_rG 'g|e-ņw>msm/man/0000755000176200001440000000000014124277674011637 5ustar liggesusersmsm/man/odds.msm.Rd0000644000176200001440000000223113051600620013623 0ustar liggesusers\name{odds.msm} \title{Calculate tables of odds ratios for covariates on misclassification probabilities} \alias{odds.msm} \description{ Odds ratios are computed by exponentiating the estimated covariate effects on the logit-misclassification probabilities. } \usage{ odds.msm(x, odds.scale = 1, cl = 0.95) } \arguments{ \item{x}{Output from \code{\link{msm}} representing a fitted multi-state model.} \item{odds.scale}{Vector with same elements as number of covariates on misclassification probabilities. Corresponds to the increase in each covariate used to calculate its odds ratio. Defaults to all 1.} \item{cl}{Width of the symmetric confidence interval to present. Defaults to 0.95.} } \value{ A list of tables containing odds ratio estimates, one table for each covariate. Each table has three columns, containing the odds ratio, and an approximate upper 95\% and lower 95\% confidence limit respectively (assuming normality on the log scale), for each misclassification probability. } \seealso{ \code{\link{msm}}, \code{\link{hazard.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/surface.msm.Rd0000644000176200001440000000634413051600620014333 0ustar liggesusers\name{surface.msm} \alias{surface.msm} \alias{persp.msm} \alias{contour.msm} \alias{image.msm} \title{Explore the likelihood surface} \description{ Plot the log-likelihood surface with respect to two parameters. } \usage{ surface.msm(x, params=c(1,2), np=10, type=c("contour","filled.contour","persp","image"), point=NULL, xrange=NULL, yrange=NULL,...) \method{contour}{msm}(x, ...) \method{persp}{msm}(x, ...) \method{image}{msm}(x, ...) } \arguments{ \item{x}{Output from \code{\link{msm}}, representing a fitted msm model.} \item{params}{Integer vector with two elements, giving the indices of the parameters to vary. All other parameters will be fixed. Defaults to \code{c(1,2)}, representing the first two log transition intensities. See the \code{fixedpars} argument to \code{msm} for a definition of these indices.} \item{np}{Number of grid points to use in each direction, by default 10. An \code{np x np} grid will be used to evaluate the likelihood surface. If 100 likelihood function evaluations is slow, then reduce this. } \item{type}{Character string specifying the type of plot to produce. \tabular{ll}{ \code{"contour"} \tab Contour plot, using the R function \code{\link{contour}}. \cr \code{"filled.contour"} \tab Solid-color contour plot, using the R function \code{\link{filled.contour}}. \cr \code{"persp"} \tab Perspective plot, using the R function \code{\link{persp}}. \cr \code{"image"} \tab Grid color plot, using the R function \code{\link{image}}. \cr } } \item{point}{Vector of length \code{n}, where \code{n} is the number of parameters in the model, including the parameters that will be varied here. This specifies the point at which to fix the likelihood. By default, this is the maximum likelihood estimates stored in the fitted model \code{x}, \code{x$estimates}.} \item{xrange}{Range to plot for the first varied parameter. Defaults to plus and minus two standard errors, obtained from the Hessian at the maximum likelihood estimate.} \item{yrange}{Range to plot for the second varied parameter. Defaults to plus and minus two standard errors, obtained from the Hessian at the maximum likelihood estimate.} \item{...}{Further arguments to be passed to the plotting function.} } \details{ Draws a contour or perspective plot. Useful for diagnosing irregularities in the likelihood surface. If you want to use these plots before running the maximum likelihood estimation, then just run \code{msm} with all estimates fixed at their initial values. \code{contour.msm} just calls surface.msm with \code{type = "contour"}. \code{persp.msm} just calls surface.msm with \code{type = "persp"}. \code{image.msm} just calls surface.msm with \code{type = "image"}. As these three functions are methods of the generic functions \code{contour}, \code{persp} and \code{image}, they can be invoked as \code{contour(x)}, \code{persp(x)} or \code{image(x)}, where \code{x} is a fitted \code{msm} object. } \seealso{ \code{\link{msm}}, \code{\link{contour}}, \code{\link{filled.contour}}, \code{\link{persp}}, \code{\link{image}}. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/hmm-dists.Rd0000644000176200001440000002112513455632010014015 0ustar liggesusers\name{hmm-dists} \alias{hmm-dists} \alias{hmmCat} \alias{hmmIdent} \alias{hmmUnif} \alias{hmmNorm} \alias{hmmLNorm} \alias{hmmExp} \alias{hmmGamma} \alias{hmmWeibull} \alias{hmmPois} \alias{hmmBinom} \alias{hmmTNorm} \alias{hmmMETNorm} \alias{hmmMEUnif} \alias{hmmNBinom} \alias{hmmBetaBinom} \alias{hmmBeta} \alias{hmmT} \title{Hidden Markov model constructors} \description{ These functions are used to specify the distribution of the response conditionally on the underlying state in a hidden Markov model. A list of these function calls, with one component for each state, should be used for the \code{hmodel} argument to \code{msm}. The initial values for the parameters of the distribution should be given as arguments. Note the initial values should be supplied as literal values - supplying them as variables is currently not supported. } \usage{ hmmCat(prob, basecat) hmmIdent(x) hmmUnif(lower, upper) hmmNorm(mean, sd) hmmLNorm(meanlog, sdlog) hmmExp(rate) hmmGamma(shape, rate) hmmWeibull(shape, scale) hmmPois(rate) hmmBinom(size, prob) hmmTNorm(mean, sd, lower, upper) hmmMETNorm(mean, sd, lower, upper, sderr, meanerr=0) hmmMEUnif(lower, upper, sderr, meanerr=0) hmmNBinom(disp, prob) hmmBetaBinom(size, meanp, sdp) hmmBeta(shape1,shape2) hmmT(mean,scale,df) } \arguments{ \item{prob}{ (\code{hmmCat}) Vector of probabilities of observing category \code{1, 2, \dots, length(prob)} respectively. Or the probability governing a binomial or negative binomial distribution.} \item{basecat}{ (\code{hmmCat}) Category which is considered to be the "baseline", so that during estimation, the probabilities are parameterised as probabilities relative to this baseline category. By default, the category with the greatest probability is used as the baseline. } \item{x}{ (\code{hmmIdent}) Code in the data which denotes the exactly-observed state. } \item{mean}{ (\code{hmmNorm,hmmLNorm,hmmTNorm}) Mean defining a Normal, or truncated Normal distribution. } \item{sd}{ (\code{hmmNorm,hmmLNorm,hmmTNorm}) Standard deviation defining a Normal, or truncated Normal distribution. } \item{meanlog}{ (\code{hmmNorm,hmmLNorm,hmmTNorm}) Mean on the log scale, for a log Normal distribution. } \item{sdlog}{ (\code{hmmNorm,hmmLNorm,hmmTNorm}) Standard deviation on the log scale, for a log Normal distribution. } \item{rate}{ (\code{hmmPois,hmmExp,hmmGamma}) Rate of a Poisson, Exponential or Gamma distribution (see \code{\link{dpois}}, \code{\link{dexp}}, \code{\link{dgamma}}). } \item{shape}{ (\code{hmmPois,hmmExp,hmmGamma}) Shape parameter of a Gamma or Weibull distribution (see \code{\link{dgamma}}, \code{\link{dweibull}}). } \item{shape1,shape2}{First and second parameters of a beta distribution (see \code{\link{dbeta}}).} \item{scale}{ (\code{hmmGamma}) Scale parameter of a Gamma distribution (see \code{\link{dgamma}}), or unstandardised Student t distribution. } \item{df}{Degrees of freedom of the Student t distribution.} \item{size}{Order of a Binomial distribution (see \code{\link{dbinom}}).} \item{disp}{Dispersion parameter of a negative binomial distribution, also called \code{size} or \code{order}. (see \code{\link{dnbinom}}).} \item{meanp}{Mean outcome probability in a beta-binomial distribution} \item{sdp}{Standard deviation describing the overdispersion of the outcome probability in a beta-binomial distribution } \item{lower}{ (\code{hmmUnif,hmmTNorm,hmmMEUnif}) Lower limit for an Uniform or truncated Normal distribution. } \item{upper}{ (\code{hmmUnif,hmmTNorm,hmmMEUnif}) Upper limit for an Uniform or truncated Normal distribution. } \item{sderr}{ (\code{hmmMETNorm,hmmUnif}) Standard deviation of the Normal measurement error distribution. } \item{meanerr}{ (\code{hmmMETNorm,hmmUnif}) Additional shift in the measurement error, fixed to 0 by default. This may be modelled in terms of covariates. } } \value{ Each function returns an object of class \code{hmodel}, which is a list containing information about the model. The only component which may be useful to end users is \code{r}, a function of one argument \code{n} which returns a random sample of size \code{n} from the given distribution. } \details{ \code{hmmCat} represents a categorical response distribution on the set \code{1, 2, \dots, length(prob)}. The Markov model with misclassification is an example of this type of model. The categories in this case are (some subset of) the underlying states. The \code{hmmIdent} distribution is used for underlying states which are observed exactly without error. For hidden Markov models with multiple outcomes, (see \code{\link{hmmMV}}), the outcome in the data which takes the special \code{hmmIdent} value must be the first of the multiple outcomes. \code{hmmUnif}, \code{hmmNorm}, \code{hmmLNorm}, \code{hmmExp}, \code{hmmGamma}, \code{hmmWeibull}, \code{hmmPois}, \code{hmmBinom}, \code{hmmTNorm}, \code{hmmNBinom} and \code{hmmBeta} represent Uniform, Normal, log-Normal, exponential, Gamma, Weibull, Poisson, Binomial, truncated Normal, negative binomial and beta distributions, respectively, with parameterisations the same as the default parameterisations in the corresponding base R distribution functions. \code{hmmT} is the Student t distribution with general mean \eqn{\mu}{mu}, scale \eqn{\sigma}{sigma} and degrees of freedom \code{df}. The variance is \eqn{\sigma^2 df/(df + 2)}{sigma^2 df/(df + 2)}. Note the t distribution in base R \code{\link{dt}} is a standardised one with mean 0 and scale 1. These allow any positive (integer or non-integer) \code{df}. By default, all three parameters, including \code{df}, are estimated when fitting a hidden Markov model, but in practice, \code{df} might need to be fixed for identifiability - this can be done using the \code{fixedpars} argument to \code{\link{msm}}. The \code{hmmMETNorm} and \code{hmmMEUnif} distributions are truncated Normal and Uniform distributions, but with additional Normal measurement error on the response. These are generalisations of the distributions proposed by Satten and Longini (1996) for modelling the progression of CD4 cell counts in monitoring HIV disease. See \code{\link{medists}} for density, distribution, quantile and random generation functions for these distributions. See also \code{\link{tnorm}} for density, distribution, quantile and random generation functions for the truncated Normal distribution. See the PDF manual \file{msm-manual.pdf} in the \file{doc} subdirectory for algebraic definitions of all these distributions. New hidden Markov model response distributions can be added to \pkg{msm} by following the instructions in Section 2.17.1. Parameters which can be modelled in terms of covariates, on the scale of a link function, are as follows. \tabular{ll}{ PARAMETER NAME \tab LINK FUNCTION \cr \code{mean} \tab identity \cr \code{meanlog} \tab identity \cr \code{rate} \tab log \cr \code{scale} \tab log \cr \code{meanerr} \tab identity \cr \code{meanp} \tab logit \cr \code{prob} \tab logit or multinomial logit } Parameters \code{basecat, lower, upper, size, meanerr} are fixed at their initial values. All other parameters are estimated while fitting the hidden Markov model, unless the appropriate \code{fixedpars} argument is supplied to \code{msm}. For categorical response distributions \code{(hmmCat)} the outcome probabilities initialized to zero are fixed at zero, and the probability corresponding to \code{basecat} is fixed to one minus the sum of the remaining probabilities. These remaining probabilities are estimated, and can be modelled in terms of covariates via multinomial logistic regression (relative to \code{basecat}). } \references{ Satten, G.A. and Longini, I.M. Markov chains with measurement error: estimating the 'true' course of a marker of the progression of human immunodeficiency virus disease (with discussion) \emph{Applied Statistics} 45(3): 275-309 (1996). Jackson, C.H. and Sharples, L.D. Hidden Markov models for the onset and progresison of bronchiolitis obliterans syndrome in lung transplant recipients \emph{Statistics in Medicine}, 21(1): 113--128 (2002). Jackson, C.H., Sharples, L.D., Thompson, S.G. and Duffy, S.W. and Couto, E. Multi-state Markov models for disease progression with classification error. \emph{The Statistician}, 52(2): 193--209 (2003). } \seealso{ \code{\link{msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{distribution} msm/man/plotprog.msm.Rd0000644000176200001440000000403013051600620014537 0ustar liggesusers\name{plotprog.msm} \alias{plotprog.msm} \title{Kaplan Meier estimates of incidence} \description{ Compute and plot Kaplan-Meier estimates of the probability that each successive state has not occurred yet. } \usage{ plotprog.msm(formula, subject, data, legend.pos=NULL, xlab="Time", ylab="1 - incidence probability", lwd=1, xlim=NULL, mark.time=TRUE, ...) } \arguments{ \item{formula}{A formula giving the vectors containing the observed states and the corresponding observation times. For example, \code{state ~ time} Observed states should be in the set \code{1, \dots, n}, where \code{n} is the number of states.} \item{subject}{Vector of subject identification numbers for the data specified by \code{formula}. If missing, then all observations are assumed to be on the same subject. These must be sorted so that all observations on the same subject are adjacent.} \item{data}{An optional data frame in which the variables represented by \code{state}, \code{time} and \code{subject} can be found.} \item{legend.pos}{Vector of the \eqn{x} and \eqn{y} position, respectively, of the legend.} \item{xlab}{x axis label.} \item{ylab}{y axis label.} \item{lwd}{Line width. See \code{\link{par}}.} \item{xlim}{x axis limits, e.g. c(0,10) for an axis ranging from 0 to 10. Default is the range of observation times.} \item{mark.time}{Mark the empirical survival curve at each censoring point, see \code{\link{lines.survfit}}.} \item{...}{Other arguments to be passed to the \code{\link{plot}} and \code{\link[survival]{lines.survfit}} functions.} } \details{ If the data represent observations of the process at arbitrary times, then the first occurrence of the state in the data will usually be greater than the actual first transition time to that state. Therefore the probabilities plotted by \code{\link{plotprog.msm}} will be overestimates. } \seealso{\code{\link[survival]{survfit}}, \code{\link[survival]{plot.survfit}}} \keyword{models} msm/man/medists.Rd0000644000176200001440000001347413051600620013562 0ustar liggesusers\name{medists} \alias{medists} \alias{dmenorm} \alias{pmenorm} \alias{qmenorm} \alias{rmenorm} \alias{dmeunif} \alias{pmeunif} \alias{qmeunif} \alias{rmeunif} \title{Measurement error distributions} \concept{Measurement error} \description{ Truncated Normal and Uniform distributions, where the response is also subject to a Normally distributed measurement error. } \usage{ dmenorm(x, mean=0, sd=1, lower=-Inf, upper=Inf, sderr=0, meanerr=0, log = FALSE) pmenorm(q, mean=0, sd=1, lower=-Inf, upper=Inf, sderr=0, meanerr=0, lower.tail = TRUE, log.p = FALSE) qmenorm(p, mean=0, sd=1, lower=-Inf, upper=Inf, sderr=0, meanerr=0, lower.tail = TRUE, log.p = FALSE) rmenorm(n, mean=0, sd=1, lower=-Inf, upper=Inf, sderr=0, meanerr=0) dmeunif(x, lower=0, upper=1, sderr=0, meanerr=0, log = FALSE) pmeunif(q, lower=0, upper=1, sderr=0, meanerr=0, lower.tail = TRUE, log.p = FALSE) qmeunif(p, lower=0, upper=1, sderr=0, meanerr=0, lower.tail = TRUE, log.p = FALSE) rmeunif(n, lower=0, upper=1, sderr=0, meanerr=0) } \arguments{ \item{x,q}{vector of quantiles.} \item{p}{vector of probabilities.} \item{n}{number of observations. If \code{length(n) > 1}, the length is taken to be the number required.} \item{mean}{vector of means.} \item{sd}{vector of standard deviations.} \item{lower}{lower truncation point.} \item{upper}{upper truncation point.} \item{sderr}{Standard deviation of measurement error distribution.} \item{meanerr}{Optional shift for the measurement error distribution.} \item{log, log.p}{logical; if TRUE, probabilities \eqn{p} are given as \eqn{\log(p)}{log(p)}, or log density is returned.} \item{lower.tail}{logical; if TRUE (default), probabilities are \eqn{P[X <= x]}, otherwise, \eqn{P[X > x]}.} } \value{ \code{dmenorm}, \code{dmeunif} give the density, \code{pmenorm}, \code{pmeunif} give the distribution function, \code{qmenorm}, \code{qmeunif} give the quantile function, and \code{rmenorm}, \code{rmeunif} generate random deviates, for the Normal and Uniform versions respectively. } \details{ The normal distribution with measurement error has density \deqn{ \frac{\Phi(u, \mu_2, \sigma_3) - \Phi(l, \mu_2, \sigma_3)}{\Phi(u, \mu_0, \sigma_0) - \Phi(l, \mu_0, \sigma_0)} \phi(x, \mu_0 + \mu_\epsilon, \sigma_2) }{(Phi(upper, mu2, sigma3) - Phi(lower, mu2, sigma3)) / (Phi(upper, mean, sd) - Phi(lower, mean, sd)) * phi(x, mean + meanerr, sigma2)} where \deqn{\sigma_2^2 = \sigma_0^2 + \sigma_\epsilon^2,}{sigma2*sigma2 = sd*sd + sderr*sderr,} \deqn{\sigma_3 = \sigma_0 \sigma_\epsilon / \sigma_2,}{sigma3 = sd*sderr / sigma2,} \deqn{\mu_2 = (x - \mu_\epsilon) \sigma_0^2 + \mu_0 \sigma_\epsilon^2,}{mu2 = (x - meanerr)*sd*sd + mean*sderr*sderr,} \eqn{\mu_0}{mean} is the mean of the original Normal distribution before truncation, \cr \eqn{\sigma_0}{sd} is the corresponding standard deviation, \cr \eqn{u} is the upper truncation point, \cr \eqn{l} is the lower truncation point, \cr \eqn{\sigma_\epsilon}{sderr} is the standard deviation of the additional measurement error, \cr \eqn{\mu_\epsilon}{meanerr} is the mean of the measurement error (usually 0). \cr \eqn{\phi(x)}{phi(x)} is the density of the corresponding normal distribution, and \cr \eqn{\Phi(x)}{Phi(x)} is the distribution function of the corresponding normal distribution. The uniform distribution with measurement error has density \deqn{(\Phi(x, \mu_\epsilon+l, \sigma_\epsilon) - \Phi(x, \mu_\epsilon+u, \sigma_\epsilon)) / (u - l)}{(Phi(x, meanerr+l, sderr) - Phi(x, meanerr+u, sderr)) / (upper - lower)} These are calculated from the original truncated Normal or Uniform density functions \eqn{f(. | \mu, \sigma, l, u)}{f(. | mu, sd)} as \deqn{\int f(y | \mu, \sigma, l, u) \phi(x, y + \mu_\epsilon, \sigma_\epsilon) dy}{integral f(y | mu, sd, l, u) phi(x, y + meanerr, sderr) dy} If \code{sderr} and \code{meanerr} are not specified they assume the default values of 0, representing no measurement error variance, and no constant shift in the measurement error, respectively. Therefore, for example with no other arguments, \code{dmenorm(x)}, is simply equivalent to \code{dtnorm(x)}, which in turn is equivalent to \code{dnorm(x)}. These distributions were used by Satten and Longini (1996) for CD4 cell counts conditionally on hidden Markov states of HIV infection, and later by Jackson and Sharples (2002) for FEV1 measurements conditionally on states of chronic lung transplant rejection. These distribution functions are just provided for convenience, and are not optimised for numerical accuracy or speed. To fit a hidden Markov model with these response distributions, use a \code{\link{hmmMETNorm}} or \code{\link{hmmMEUnif}} constructor. See the \code{\link{hmm-dists}} help page for further details. } \seealso{ \code{\link{dnorm}}, \code{\link{dunif}}, \code{\link{dtnorm}} } \references{ Satten, G.A. and Longini, I.M. Markov chains with measurement error: estimating the 'true' course of a marker of the progression of human immunodeficiency virus disease (with discussion) \emph{Applied Statistics} 45(3): 275-309 (1996) Jackson, C.H. and Sharples, L.D. Hidden Markov models for the onset and progression of bronchiolitis obliterans syndrome in lung transplant recipients \emph{Statistics in Medicine}, 21(1): 113--128 (2002). } \examples{ ## what does the distribution look like? x <- seq(50, 90, by=1) plot(x, dnorm(x, 70, 10), type="l", ylim=c(0,0.06)) ## standard Normal lines(x, dtnorm(x, 70, 10, 60, 80), type="l") ## truncated Normal ## truncated Normal with small measurement error lines(x, dmenorm(x, 70, 10, 60, 80, sderr=3), type="l") } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{distribution} msm/man/statetable.msm.Rd0000644000176200001440000000311113051600620015020 0ustar liggesusers\name{statetable.msm} \alias{statetable.msm} \title{Table of transitions} \description{ Calculates a frequency table counting the number of times each pair of states were observed in successive observation times. This can be a useful way of summarising multi-state data. } \usage{ statetable.msm(state, subject, data=NULL) } \arguments{ \item{state}{Observed states, assumed to be ordered by time within each subject.} \item{subject}{Subject identification numbers corresponding to \code{state}. If not given, all observations are assumed to be on the same subject.} \item{data}{An optional data frame in which the variables represented by \code{subject} and \code{state} can be found.} } \value{ A frequency table with starting states as rows and finishing states as columns. } \details{ If the data are intermittently observed (panel data) this table should not be used to decide what transitions should be allowed in the \eqn{Q} matrix, which works in continuous time. This function counts the transitions between states over a time interval, not in real time. There can be observed transitions between state \eqn{r} and \eqn{s} over an interval even if \eqn{q_{rs}=0}, because the process may have passed through one or more intermediate states in the middle of the interval. } \seealso{ \code{\link{crudeinits.msm}} } \examples{ ## Heart transplant data data(cav) ## 148 deaths from state 1, 48 from state 2 and 55 from state 3. statetable.msm(state, PTNUM, data=cav) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/updatepars.msm.Rd0000644000176200001440000000242413212472403015053 0ustar liggesusers\name{updatepars.msm} \alias{updatepars.msm} \title{updatepars.msm} \description{ Update the maximum likelihood estimates in a fitted model object. Developer use only. } \usage{ updatepars.msm(x, pars) } \arguments{ \item{x}{A fitted multi-state model object, as returned by \code{\link{msm}}.} \item{pars}{Vector of new parameters, in their untransformed real-line parameterisations, to substitute for the maximum likelihood estimates corresponding to those in the \code{estimates} component of the fitted model object (\code{\link{msm.object}}). The order of the parameters is documented in \code{\link{msm}}, argument \code{fixedpars}.} } \value{ An updated \code{\link{msm}} model object with the updated maximum likelihood estimates, but with the covariances / standard errors unchanged. Point estimates from output functions such as \code{\link{qmatrix.msm}}, \code{\link{pmatrix.msm}}, or any related function, can then be evaluated with the new parameters, and at arbitrary covariate values. This function is used, for example, when computing confidence intervals from \code{\link{pmatrix.msm}}, and related functions, using the \code{ci="normal"} method. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/sim.msm.Rd0000644000176200001440000000447113051600620013472 0ustar liggesusers\name{sim.msm} \title{Simulate one individual trajectory from a continuous-time Markov model} \alias{sim.msm} \concept{Simulation} \description{Simulate one realisation from a continuous-time Markov process up to a given time. } \usage{ sim.msm(qmatrix, maxtime, covs=NULL, beta=NULL, obstimes=0, start=1, mintime=0) } \arguments{ \item{qmatrix}{ The transition intensity matrix of the Markov process. The diagonal of \code{qmatrix} is ignored, and computed as appropriate so that the rows sum to zero. For example, a possible \code{qmatrix} for a three state illness-death model with recovery is: \code{rbind( c( 0, 0.1, 0.02 ), c( 0.1, 0, 0.01 ), c( 0, 0, 0 ) )} } \item{maxtime}{ Maximum time for the simulated process. } \item{covs}{Matrix of time-dependent covariates, with one row for each observation time and one column for each covariate.} \item{beta}{Matrix of linear covariate effects on log transition intensities. The rows correspond to different covariates, and the columns to the transition intensities. The intensities are ordered by reading across rows of the intensity matrix, starting with the first, counting the positive off-diagonal elements of the matrix.} \item{obstimes}{Vector of times at which the covariates are observed.} \item{start}{Starting state of the process. Defaults to 1.} \item{mintime}{Starting time of the process. Defaults to 0.} } \value{ A list with components, \item{states}{Simulated states through which the process moves. This ends with either an absorption before \code{obstime}, or a transient state at \code{obstime}. } \item{times}{Exact times at which the process changes to the corresponding states} \item{qmatrix}{The given transition intensity matrix} } \details{ The effect of time-dependent covariates on the transition intensity matrix for an individual is determined by assuming that the covariate is a step function which remains constant in between the individual's observation times. } \seealso{ \code{\link{simmulti.msm}} } \examples{ qmatrix <- rbind( c(-0.2, 0.1, 0.1 ), c(0.5, -0.6, 0.1 ), c(0, 0, 0) ) sim.msm(qmatrix, 30) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{datagen} msm/man/tnorm.Rd0000644000176200001440000000712113051600620013241 0ustar liggesusers\name{tnorm} \alias{tnorm} \alias{dtnorm} \alias{ptnorm} \alias{qtnorm} \alias{rtnorm} \title{Truncated Normal distribution} \description{ Density, distribution function, quantile function and random generation for the truncated Normal distribution with mean equal to \code{mean} and standard deviation equal to \code{sd} before truncation, and truncated on the interval \code{[lower, upper]}. } \usage{ dtnorm(x, mean=0, sd=1, lower=-Inf, upper=Inf, log = FALSE) ptnorm(q, mean=0, sd=1, lower=-Inf, upper=Inf, lower.tail = TRUE, log.p = FALSE) qtnorm(p, mean=0, sd=1, lower=-Inf, upper=Inf, lower.tail = TRUE, log.p = FALSE) rtnorm(n, mean=0, sd=1, lower=-Inf, upper=Inf) } \arguments{ \item{x,q}{vector of quantiles.} \item{p}{vector of probabilities.} \item{n}{number of observations. If \code{length(n) > 1}, the length is taken to be the number required.} \item{mean}{vector of means.} \item{sd}{vector of standard deviations.} \item{lower}{lower truncation point.} \item{upper}{upper truncation point.} \item{log}{logical; if TRUE, return log density or log hazard.} \item{log.p}{logical; if TRUE, probabilities p are given as log(p).} \item{lower.tail}{logical; if TRUE (default), probabilities are P[X <= x], otherwise, P[X > x].} } \value{ \code{dtnorm} gives the density, \code{ptnorm} gives the distribution function, \code{qtnorm} gives the quantile function, and \code{rtnorm} generates random deviates. } \details{ The truncated normal distribution has density \deqn{ f(x, \mu, \sigma) = \phi(x, \mu, \sigma) / (\Phi(u, \mu, \sigma) - \Phi(l, \mu, \sigma)) }{ f(x, mu, sigma) = phi(x, mu, sigma) / (Phi(upper, mu, sigma) - Phi(lower, mu, sigma)) } for \eqn{l <= x <= u}{lower <= x <= upper}, and 0 otherwise. \eqn{\mu}{mean} is the mean of the original Normal distribution before truncation, \cr \eqn{\sigma}{sd} is the corresponding standard deviation, \cr \eqn{u} is the upper truncation point, \cr \eqn{l} is the lower truncation point, \cr \eqn{\phi(x)}{phi(x)} is the density of the corresponding normal distribution, and \cr \eqn{\Phi(x)}{Phi(x)} is the distribution function of the corresponding normal distribution. If \code{mean} or \code{sd} are not specified they assume the default values of \code{0} and \code{1}, respectively. If \code{lower} or \code{upper} are not specified they assume the default values of \code{-Inf} and \code{Inf}, respectively, corresponding to no lower or no upper truncation. Therefore, for example, \code{dtnorm(x)}, with no other arguments, is simply equivalent to \code{dnorm(x)}. Only \code{rtnorm} is used in the \code{msm} package, to simulate from hidden Markov models with truncated normal distributions. This uses the rejection sampling algorithms described by Robert (1995). These functions are merely provided for completion, and are not optimized for numerical stability or speed. To fit a hidden Markov model with a truncated Normal response distribution, use a \code{\link{hmmTNorm}} constructor. See the \code{\link{hmm-dists}} help page for further details. } \references{ Robert, C. P. Simulation of truncated normal variables. Statistics and Computing (1995) 5, 121--125 } \seealso{ \code{\link{dnorm}} } \examples{ x <- seq(50, 90, by=1) plot(x, dnorm(x, 70, 10), type="l", ylim=c(0,0.06)) ## standard Normal distribution lines(x, dtnorm(x, 70, 10, 60, 80), type="l") ## truncated Normal distribution } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{distribution} msm/man/qratio.msm.Rd0000644000176200001440000000645413051600620014204 0ustar liggesusers\name{qratio.msm} \alias{qratio.msm} \title{Estimated ratio of transition intensities} \description{ Compute the estimate and approximate standard error of the ratio of two estimated transition intensities from a fitted multi-state model at a given set of covariate values. } \usage{ qratio.msm(x, ind1, ind2, covariates = "mean", ci=c("delta","normal","bootstrap","none"), cl = 0.95, B=1000, cores=NULL) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}.} \item{ind1}{Pair of numbers giving the indices in the intensity matrix of the numerator of the ratio, for example, \code{c(1,2)}. } \item{ind2}{Pair of numbers giving the indices in the intensity matrix of the denominator of the ratio, for example, \code{c(2,1)}. } \item{covariates}{ The covariate values at which to estimate the intensities. This can either be:\cr the string \code{"mean"}, denoting the means of the covariates in the data (this is the default),\cr the number \code{0}, indicating that all the covariates should be set to zero,\cr or a list of values, with optional names. For example \code{list (60, 1)} where the order of the list follows the order of the covariates originally given in the model formula, or a named list, \code{list (age = 60, sex = 1)} } \item{ci}{ If \code{"delta"} (the default) then confidence intervals are calculated by the delta method. If \code{"normal"}, then calculate a confidence interval by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects, then transforming. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}.} \item{cl}{Width of the symmetric confidence interval to present. Defaults to 0.95.} \item{B}{Number of bootstrap replicates, or number of normal simulations from the distribution of the MLEs} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} } \value{ A named vector with elements \code{estimate}, \code{se}, \code{L} and \code{U} containing the estimate, standard error, lower and upper confidence limits, respectively, of the ratio of intensities. } \details{ For example, we might want to compute the ratio of the progression rate and recovery rate for a fitted model \code{disease.msm} with a health state (state 1) and a disease state (state 2). In this case, the progression rate is the (1,2) entry of the intensity matrix, and the recovery rate is the (2,1) entry. Thus to compute this ratio with covariates set to their means, we call \code{qratio.msm(disease.msm, c(1,2), c(2,1))} . Standard errors are estimated by the delta method. Confidence limits are estimated by assuming normality on the log scale. } \seealso{ \code{\link{qmatrix.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/boot.msm.Rd0000644000176200001440000001452413051600620013645 0ustar liggesusers\name{boot.msm} \alias{boot.msm} \title{Bootstrap resampling for multi-state models} \description{ Draw a number of bootstrap resamples, refit a \code{\link{msm}} model to the resamples, and calculate statistics on the refitted models. } \usage{ boot.msm(x, stat=pmatrix.msm, B=1000, file=NULL, cores=NULL) } \arguments{ \item{x}{A fitted msm model, as output by \code{\link{msm}}.} \item{stat}{A function to call on each refitted msm model. By default this is \code{\link{pmatrix.msm}}, returning the transition probability matrix in one time unit. If \code{NULL} then no function is computed.} \item{B}{Number of bootstrap resamples.} \item{file}{Name of a file in which to save partial results after each replicate. This is saved using \code{\link{save}} and can be restored using \code{\link{load}}, producing an object called \code{boot.list} containing the partial results. Not supported when using parallel processing.} \item{cores}{Number of processor cores to use for parallel processing. Requires the \pkg{doParallel} package to be installed. If not specified, parallel processing is not used. If \code{cores} is set to the string \code{"default"}, the default methods of \code{\link[parallel]{makeCluster}} (on Windows) or \code{\link[doParallel]{registerDoParallel}} (on Unix-like) are used. } } \details{ The bootstrap datasets are computed by resampling independent transitions between pairs of states (for non-hidden models without censoring), or independent individual series (for hidden models or models with censoring). Therefore this approach doesn't work if, for example, the data for a HMM consist of a series of observations from just one individual, and is inaccurate for small numbers of independent transitions or individuals. Confidence intervals or standard errors for the corresponding statistic can be calculated by summarising the returned list of \code{B} replicated outputs. This is currently implemented for most the output functions \code{\link{qmatrix.msm}}, \code{\link{ematrix.msm}}, \code{\link{qratio.msm}}, \code{\link{pmatrix.msm}}, \code{\link{pmatrix.piecewise.msm}}, \code{\link{totlos.msm}} and \code{\link{prevalence.msm}}. For other outputs, users will have to write their own code to summarise the output of \code{\link{boot.msm}}. Most of \pkg{msm}'s output functions present confidence intervals based on asymptotic standard errors calculated from the Hessian. These are expected to be underestimates of the true standard errors (Cramer-Rao lower bound). Some of these functions use a further approximation, the delta method (see \code{\link{deltamethod}}) to obtain standard errors of transformed parameters. Bootstrapping should give a more accurate estimate of the uncertainty. An alternative method which is less accurate though faster than bootstrapping, but more accurate than the delta method, is to draw a sample from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix), and summarise the transformed estimates. See \code{\link{pmatrix.msm}}. All objects used in the original call to \code{\link{msm}} which produced \code{x}, such as the \code{qmatrix}, should be in the working environment, or else \code{boot.msm} will produce an \dQuote{object not found} error. This enables \code{boot.msm} to refit the original model to the replicate datasets. However there is currently a limitation. In the original call to \code{msm}, the \code{"formula"} argument should be specified directly, as, for example, \code{msm(state ~ time, data = ...)} and not, for example, \code{form = data$state ~ data$time} \code{msm(formula=form, data = ...)} otherwise \code{boot.msm} will be unable to draw the replicate datasets. \code{boot.msm} will also fail with an incomprehensible error if the original call to msm used a used-defined object whose name is the same as a built-in R object, or an object in any other loaded package. For example, if you have called a Q matrix \code{q}, when \code{q()} is the built-in function for quitting R. If \code{stat} is \code{NULL}, then \code{B} different \code{msm} model objects will be stored in memory. This is unadvisable, as \code{msm} objects tend to be large, since they contain the original data used for the \code{msm} fit, so this will be wasteful of memory. To specify more than one statistic, write a function consisting of a list of different function calls, for example, \code{stat = function(x) list (pmatrix.msm(x, t=1), pmatrix.msm(x, t=2))} } \value{ A list with \code{B} components, containing the result of calling function \code{stat} on each of the refitted models. If \code{stat} is \code{NULL}, then each component just contains the refitted model. If one of the \code{B} model fits was unsuccessful and resulted in an error, then the corresponding list component will contain the error message. } \references{ Efron, B. and Tibshirani, R.J. (1993) \emph{An Introduction to the Bootstrap}, Chapman and Hall. } \seealso{ \code{\link{qmatrix.msm}}, \code{\link{qratio.msm}}, \code{\link{sojourn.msm}}, \code{\link{ematrix.msm}}, \code{\link{pmatrix.msm}}, \code{\link{pmatrix.piecewise.msm}}, \code{\link{totlos.msm}}, \code{\link{prevalence.msm}}. } \examples{ \dontrun{ ## Psoriatic arthritis example data(psor) psor.q <- rbind(c(0,0.1,0,0),c(0,0,0.1,0),c(0,0,0,0.1),c(0,0,0,0)) psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), control = list(REPORT=1,trace=2), method="BFGS") ## Bootstrap the baseline transition intensity matrix. This will take a long time. q.list <- boot.msm(psor.msm, function(x)x$Qmatrices$baseline) ## Manipulate the resulting list of matrices to calculate bootstrap standard errors. apply(array(unlist(q.list), dim=c(4,4,5)), c(1,2), sd) ## Similarly calculate a bootstrap 95\% confidence interval apply(array(unlist(q.list), dim=c(4,4,5)), c(1,2), function(x)quantile(x, c(0.025, 0.975))) ## Bootstrap standard errors are larger than the asymptotic standard ## errors calculated from the Hessian psor.msm$QmatricesSE$baseline } } \author{C.H.Jackson } \keyword{models} msm/man/crudeinits.msm.Rd0000644000176200001440000000565013051600620015053 0ustar liggesusers\name{crudeinits.msm} \alias{crudeinits.msm} \title{Calculate crude initial values for transition intensities} \description{ Calculates crude initial values for transition intensities by assuming that the data represent the exact transition times of the Markov process. } \usage{ crudeinits.msm(formula, subject, qmatrix, data=NULL, censor=NULL, censor.states=NULL) } \arguments{ \item{formula}{ A formula giving the vectors containing the observed states and the corresponding observation times. For example, \code{state ~ time} Observed states should be in the set \code{1, \dots, n}, where \code{n} is the number of states. Note hidden Markov models are not supported by this function. } \item{subject}{Vector of subject identification numbers for the data specified by \code{formula}. If missing, then all observations are assumed to be on the same subject. These must be sorted so that all observations on the same subject are adjacent.} \item{qmatrix}{Matrix of indicators for the allowed transitions. An initial value will be estimated for each value of qmatrix that is greater than zero. Transitions are taken as disallowed for each entry of \code{qmatrix} that is 0. } \item{data}{An optional data frame in which the variables represented by \code{subject} and \code{state} can be found.} \item{censor}{ A state, or vector of states, which indicates censoring. See \code{\link{msm}}. } \item{censor.states}{ Specifies the underlying states which censored observations can represent. See \code{\link{msm}}. } } \value{ The estimated transition intensity matrix. This can be used as the \code{qmatrix} argument to \code{\link{msm}}. } \details{ Suppose we want a crude estimate of the transition intensity \eqn{q_{rs}}{q_rs} from state \eqn{r} to state \eqn{s}. If we observe \eqn{n_{rs}}{n_rs} transitions from state \eqn{r} to state \eqn{s}, and a total of \eqn{n_r} transitions from state \eqn{r}, then \eqn{q_{rs} / q_{rr}}{q_rs / q_rr} can be estimated by \eqn{n_{rs} / n_r}{n_rs / n_r}. Then, given a total of \eqn{T_r} years spent in state \eqn{r}, the mean sojourn time \eqn{1 / q_{rr}}{1 / q_rr} can be estimated as \eqn{T_r / n_r}. Thus, \eqn{n_{rs} / T_r}{n_rs / T_r} is a crude estimate of \eqn{q_{rs}}{q_rs}. If the data do represent the exact transition times of the Markov process, then these are the exact maximum likelihood estimates. Observed transitions which are incompatible with the given \code{qmatrix} are ignored. Censored states are ignored. } \seealso{ \code{\link{statetable.msm}} } \examples{ data(cav) twoway4.q <- rbind(c(-0.5, 0.25, 0, 0.25), c(0.166, -0.498, 0.166, 0.166), c(0, 0.25, -0.5, 0.25), c(0, 0, 0, 0)) statetable.msm(state, PTNUM, data=cav) crudeinits.msm(state ~ years, PTNUM, data=cav, qmatrix=twoway4.q) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/hmmMV.Rd0000644000176200001440000001156513051600620013135 0ustar liggesusers\name{hmmMV} \alias{hmmMV} \title{Multivariate hidden Markov models} \description{ Constructor for a a multivariate hidden Markov model (HMM) where each of the \code{n} variables observed at the same time has a (potentially different) standard univariate distribution conditionally on the underlying state. The \code{n} outcomes are independent conditionally on the hidden state. If a particular state in a HMM has such an outcome distribution, then a call to \code{\link{hmmMV}} is supplied as the corresponding element of the \code{hmodel} argument to \code{\link{msm}}. See Example 2 below. A multivariate HMM where multiple outcomes at the same time are generated from the \emph{same} distribution is specified in the same way as the corresponding univariate model, so that \code{\link{hmmMV}} is not required. The outcome data are simply supplied as a matrix instead of a vector. See Example 1 below. The outcome data for such models are supplied as a matrix, with number of columns equal to the maximum number of arguments supplied to the \code{\link{hmmMV}} calls for each state. If some but not all of the variables are missing (\code{NA}) at a particular time, then the observed data at that time still contribute to the likelihood. The missing data are assumed to be missing at random. The Viterbi algorithm may be used to predict the missing values given the fitted model and the observed data. Typically the outcome model for each state will be from the same family or set of families, but with different parameters. Theoretically, different numbers of distributions may be supplied for different states. If a particular state has fewer outcomes than the maximum, then the data for that state are taken from the first columns of the response data matrix. However this is not likely to be a useful model, since the number of observations will probably give information about the underlying state, violating the missing at random assumption. Models with outcomes that are dependent conditionally on the hidden state (e.g. correlated multivariate normal observations) are not currently supported. } \usage{ hmmMV(\dots) } \arguments{ \item{...}{ The number of arguments supplied should equal the maximum number of observations made at one time. Each argument represents the univariate distribution of that outcome conditionally on the hidden state, and should be the result of calling a univariate hidden Markov model constructor (see \code{\link{hmm-dists}}). } } \value{A list of objects, each of class \code{hmmdist} as returned by the univariate HMM constructors documented in \code{\link{hmm-dists}}. The whole list has class \code{hmmMVdist}, which inherits from \code{hmmdist}. } \seealso{ \code{\link{hmm-dists}},\code{\link{msm}} } \examples{ ## Simulate data from a Markov model nsubj <- 30; nobspt <- 5 sim.df <- data.frame(subject = rep(1:nsubj, each=nobspt), time = seq(0, 20, length=nobspt)) set.seed(1) two.q <- rbind(c(-0.1, 0.1), c(0, 0)) dat <- simmulti.msm(sim.df[,1:2], qmatrix=two.q, drop.absorb=FALSE) ### EXAMPLE 1 ## Generate two observations at each time from the same outcome ## distribution: ## Bin(40, 0.1) for state 1, Bin(40, 0.5) for state 2 dat$obs1[dat$state==1] <- rbinom(sum(dat$state==1), 40, 0.1) dat$obs2[dat$state==1] <- rbinom(sum(dat$state==1), 40, 0.1) dat$obs1[dat$state==2] <- rbinom(sum(dat$state==2), 40, 0.5) dat$obs2[dat$state==2] <- rbinom(sum(dat$state==2), 40, 0.5) dat$obs <- cbind(obs1 = dat$obs1, obs2 = dat$obs2) ## Fitted model should approximately recover true parameters msm(obs ~ time, subject=subject, data=dat, qmatrix=two.q, hmodel = list(hmmBinom(size=40, prob=0.2), hmmBinom(size=40, prob=0.2))) ### EXAMPLE 2 ## Generate two observations at each time from different ## outcome distributions: ## Bin(40, 0.1) and Bin(40, 0.2) for state 1, dat$obs1 <- dat$obs2 <- NA dat$obs1[dat$state==1] <- rbinom(sum(dat$state==1), 40, 0.1) dat$obs2[dat$state==1] <- rbinom(sum(dat$state==1), 40, 0.2) ## Bin(40, 0.5) and Bin(40, 0.6) for state 2 dat$obs1[dat$state==2] <- rbinom(sum(dat$state==2), 40, 0.6) dat$obs2[dat$state==2] <- rbinom(sum(dat$state==2), 40, 0.5) dat$obs <- cbind(obs1 = dat$obs1, obs2 = dat$obs2) ## Fitted model should approximately recover true parameters msm(obs ~ time, subject=subject, data=dat, qmatrix=two.q, hmodel = list(hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3))), control=list(maxit=10000)) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \references{ Jackson, C. H., Su, L., Gladman, D. D. and Farewell, V. T. (2015) On modelling minimal disease activity. Arthritis Care and Research (early view). } \keyword{distribution} msm/man/lrtest.msm.Rd0000644000176200001440000000217013051600620014211 0ustar liggesusers\name{lrtest.msm} \alias{lrtest.msm} \title{Likelihood ratio test} \description{Likelihood ratio test between two or more fitted multi-state models} \usage{ lrtest.msm(...) } \arguments{ \item{...}{Two or more fitted multi-state models, as returned by \code{\link{msm}}, ordered by increasing numbers of parameters.} } \value{ A matrix with three columns, giving the likelihood ratio statistic, difference in degrees of freedom and the chi-squared p-value for a comparison of the first model supplied with each subsequent model. } \section{Warning}{ The comparison between models will only be valid if they are fitted to the same dataset. This may be a problem if there are missing values and R's default of 'na.action = na.omit' is used. The likelihood ratio statistic only has the indicated chi-squared distribution if the models are nested. An alternative for comparing non-nested models is Akaike's information criterion. This can be computed for one or more fitted \code{msm} models \code{x,y,...} using \code{\link{AIC}(x,y,...)}. } \seealso{\code{\link{logLik.msm}},\code{\link{msm}}} \keyword{models} msm/man/viterbi.msm.Rd0000644000176200001440000000342313122454500014345 0ustar liggesusers\name{viterbi.msm} \title{Calculate the probabilities of underlying states and the most likely path through them} \alias{viterbi.msm} \description{ For a fitted hidden Markov model, or a model with censored state observations, the Viterbi algorithm recursively constructs the path with the highest probability through the underlying states. The probability of each hidden state is also computed for hidden Markov models. } \usage{ viterbi.msm(x, normboot=FALSE) } \arguments{ \item{x}{A fitted hidden Markov multi-state model, or a model with censored state observations, as produced by \code{\link{msm}}} \item{normboot}{If \code{TRUE}, then before running the algorithm, the maximum likelihood estimates of the model parameters are replaced by an alternative set of parameters drawn randomly from the asymptotic multivariate normal distribution of the MLEs.} } \value{ A data frame with columns: \code{subject} = subject identification numbers \code{time} = times of observations \code{observed} = corresponding observed states \code{fitted} = corresponding fitted states found by Viterbi recursion. If the model is not a hidden Markov model and there are no censored state observations, this is just the observed states. For hidden Markov models, an additional matrix \code{pstate} is also returned inside the data frame, giving the probability of each hidden state at each point, conditionally on all the data. This is computed by the forward/backward algorithm. } \seealso{ \code{\link{msm}} } \references{ Durbin, R., Eddy, S., Krogh, A. and Mitchison, G. \emph{Biological sequence analysis}, Cambridge University Press, 1998. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/pmatrix.piecewise.msm.Rd0000644000176200001440000001236713051600620016345 0ustar liggesusers\name{pmatrix.piecewise.msm} \alias{pmatrix.piecewise.msm} \title{Transition probability matrix for processes with piecewise-constant intensities} \description{ Extract the estimated transition probability matrix from a fitted non-time-homogeneous multi-state model for a given time interval. This is a generalisation of \code{\link{pmatrix.msm}} to models with time-dependent covariates. Note that \code{\link{pmatrix.msm}} is sufficient to calculate transition probabilities for time-inhomogeneous models fitted using the \code{pci} argument to \code{\link{msm}}. } \usage{ pmatrix.piecewise.msm(x=NULL, t1, t2, times, covariates, ci=c("none","normal","bootstrap"), cl=0.95, B=1000, cores=NULL, qlist=NULL,...) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}. This should be a non-homogeneous model, whose transition intensity matrix depends on a time-dependent covariate. } \item{t1}{The start of the time interval to estimate the transition probabilities for.} \item{t2}{The end of the time interval to estimate the transition probabilities for.} \item{times}{Cut points at which the transition intensity matrix changes.} \item{covariates}{ A list with number of components one greater than the length of \code{times}. Each component of the list is specified in the same way as the \code{covariates} argument to \code{\link{pmatrix.msm}}. The components correspond to the covariate values in the intervals \code{(t1, times[1]], (times[1], times[2]], ..., (times[length(times)], t2]} (assuming that all elements of \code{times} are in the interval \code{(t1, t2)}). } \item{ci}{If \code{"normal"}, then calculate a confidence interval for the transition probabilities by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects, then calculating the resulting transition probability matrix for each replicate. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}. If \code{"none"} (the default) then no confidence interval is calculated.} \item{cl}{Width of the symmetric confidence interval, relative to 1.} \item{B}{Number of bootstrap replicates, or number of normal simulations from the distribution of the MLEs} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} \item{qlist}{A list of transition intensity matrices, of length one greater than the length of \code{times}. Either this or a fitted model \code{x} must be supplied. No confidence intervals are available if (just) \code{qlist} is supplied.} \item{...}{Optional arguments to be passed to \code{\link{MatrixExp}} to control the method of computing the matrix exponential.} } \details{ Suppose a multi-state model has been fitted, in which the transition intensity matrix \eqn{Q(x(t))} is modelled in terms of time-dependent covariates \eqn{x(t)}. The transition probability matrix \eqn{P(t_1, t_n)}{P(t1, tn)} for the time interval \eqn{(t_1, t_n)}{(t1, tn)} cannot be calculated from the estimated intensity matrix as \eqn{\exp((t_n - t_1) Q)}{exp((tn - t1) Q)}, because \eqn{Q} varies within the interval \eqn{t_1, t_n}{t1, tn}. However, if the covariates are piecewise-constant, or can be approximated as piecewise-constant, then we can calculate \eqn{P(t_1, t_n)}{P(t1, tn)} by multiplying together individual matrices \eqn{P(t_i, t_{i+1}) = \exp((t_{i+1} - t_i) Q)}{P(t_i, t_{i+1}) = exp((t_{i+1} - t_i) Q)}, calculated over intervals where Q is constant: \deqn{P(t_1, t_n) = P(t_1, t_2) P(t_2, t_3)\ldots P(t_{n-1}, t_n)}{P(t1, tn) = P(t1, t2) P(t2, t3)\ldotsP(tn-1, tn)} } \value{ The matrix of estimated transition probabilities \eqn{P(t)} for the time interval \code{[t1, tn]}. That is, the probabilities of occupying state \eqn{s} at time \eqn{t_n}{tn} conditionally on occupying state \eqn{r} at time \eqn{t_1}{t1}. Rows correspond to "from-state" and columns to "to-state". } \seealso{ \code{\link{pmatrix.msm}} } \examples{ \dontrun{ ## In a clinical study, suppose patients are given a placebo in the ## first 5 weeks, then they begin treatment 1 at 5 weeks, and ## a combination of treatments 1 and 2 from 10 weeks. ## Suppose a multi-state model x has been fitted for the patients' ## progress, with treat1 and treat2 as time dependent covariates. ## Cut points for when treatment covariate changes times <- c(0, 5, 10) ## Indicators for which treatments are active in the four intervals ## defined by the three cut points covariates <- list( list (treat1=0, treat2=0), list (treat1=0, treat2=0), list(treat1=1, treat2=0), list(treat1=1, treat2=1) ) ## Calculate transition probabilities from the start of the study to 15 weeks pmatrix.piecewise.msm(x, 0, 15, times, covariates) } } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/sojourn.msm.Rd0000644000176200001440000000612513051600620014377 0ustar liggesusers\name{sojourn.msm} \title{Mean sojourn times from a multi-state model} \alias{sojourn.msm} \description{ Estimate the mean sojourn times in the transient states of a multi-state model and their confidence limits. } \usage{ sojourn.msm(x, covariates="mean", ci=c("delta","normal","bootstrap","none"), cl=0.95, B=1000) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}.} \item{covariates}{ The covariate values at which to estimate the mean sojourn times. This can either be:\cr the string \code{"mean"}, denoting the means of the covariates in the data (this is the default),\cr the number \code{0}, indicating that all the covariates should be set to zero,\cr a list of values, with optional names. For example, \code{list(60, 1)}, where the order of the list follows the order of the covariates originally given in the model formula, or a named list, e.g. \code{list (age = 60, sex = 1)} } \item{ci}{ If \code{"delta"} (the default) then confidence intervals are calculated by the delta method, or by simple transformation of the Hessian in the very simplest cases. If \code{"normal"}, then calculate a confidence interval by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects, then transforming. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}.} \item{cl}{Width of the symmetric confidence interval to present. Defaults to 0.95.} \item{B}{Number of bootstrap replicates, or number of normal simulations from the distribution of the MLEs} } \value{ A data frame with components: \item{estimates}{Estimated mean sojourn times in the transient states.} \item{SE}{Corresponding standard errors.} \item{L}{Lower confidence limits.} \item{U}{Upper confidence limits.} } \details{ The mean sojourn time in a transient state \eqn{r} is estimated by \eqn{- 1 / q_{rr}}, where \eqn{q_{rr}} is the \eqn{r}th entry on the diagonal of the estimated transition intensity matrix. A continuous-time Markov model is fully specified by the mean sojourn times and the probability that each state is next (\code{\link{pnext.msm}}). This is a more intuitively meaningful description of a model than the transition intensity matrix (\code{\link{qmatrix.msm}}). Time dependent covariates, or time-inhomogeneous models, are not supported. This would require the mean of a piecewise exponential distribution, and the package author is not aware of any general analytic form for that. } \seealso{ \code{\link{msm}}, \code{\link{qmatrix.msm}}, \code{\link{deltamethod}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/simfitted.msm.Rd0000644000176200001440000000415413051600620014670 0ustar liggesusers\name{simfitted.msm} \alias{simfitted.msm} \title{Simulate from a Markov model fitted using msm} \concept{Simulation} \description{ Simulate a dataset from a Markov model fitted using \code{\link{msm}}, using the maximum likelihood estimates as parameters, and the same observation times as in the original data. } \usage{ simfitted.msm(x, drop.absorb=TRUE, drop.pci.imp=TRUE) } \arguments{ \item{x}{A fitted multi-state model object as returned by \code{\link{msm}}.} \item{drop.absorb}{Should repeated observations in an absorbing state be omitted. Use the default of \code{TRUE} to avoid warnings when using the simulated dataset for further \code{\link{msm}} fits. Or set to \code{FALSE} if exactly the same number of observations as the original data are needed.} \item{drop.pci.imp}{In time-inhomogeneous models fitted using the \code{pci} option to \code{\link{msm}}, censored observations are inserted into the data by \code{\link{msm}} at the times where the intensity changes, but dropped by default when simulating from the fitted model using this function. Set this argument to \code{FALSE} to keep these observations and the corresponding indicator variable.} } \value{ A dataset with variables as described in \code{\link{simmulti.msm}}. } \details{ This function is a wrapper around \code{\link{simmulti.msm}}, and only simulates panel-observed data. To generate datasets with the exact times of transition, use the lower-level \code{\link{sim.msm}}. Markov models with misclassified states fitted through the \code{ematrix} option to \code{\link{msm}} are supported, but not general hidden Markov models with \code{hmodel}. For misclassification models, this function includes misclassification in the simulated states. This function is used for parametric bootstrapping to estimate the null distribution of the test statistic in \code{\link{pearson.msm}}. } \seealso{ \code{\link{simmulti.msm}}, \code{\link{sim.msm}}, \code{\link{pearson.msm}}, \code{\link{msm}}. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/aneur.Rd0000644000176200001440000000363313051600620013220 0ustar liggesusers\name{aneur} \docType{data} \alias{aneur} \title{Aortic aneurysm progression data} \description{ This dataset contains longitudinal measurements of grades of aortic aneurysms, measured by ultrasound examination of the diameter of the aorta. } \usage{aneur} \format{ A data frame containing 4337 rows, with each row corresponding to an ultrasound scan from one of 838 men over 65 years of age. \tabular{rll}{ \code{ptnum} \tab (numeric) \tab Patient identification number \cr \code{age} \tab (numeric) \tab Recipient age at examination (years) \cr \code{diam} \tab (numeric) \tab Aortic diameter\cr \code{state} \tab (numeric) \tab State of aneurysm. \cr } The states represent successive degrees of aneurysm severity, as indicated by the aortic diameter. \tabular{rll}{ State 1 \tab Aneurysm-free \tab < 30 cm \cr State 2 \tab Mild aneurysm \tab 30-44 cm \cr State 3 \tab Moderate aneurysm \tab 45-54 cm \cr State 4 \tab Severe aneurysm \tab > 55 cm \cr } 683 of these men were aneurysm-free at age 65 and were re-screened every two years. The remaining men were aneurysmal at entry and had successive screens with frequency depending on the state of the aneurysm. Severe aneurysms are repaired by surgery. } \source{ The Chichester, U.K. randomised controlled trial of screening for abdominal aortic aneurysms by ultrasonography. } \references{ Jackson, C.H., Sharples, L.D., Thompson, S.G. and Duffy, S.W. and Couto, E. Multi-state Markov models for disease progression with classification error. \emph{The Statistician}, 52(2): 193--209 (2003) Couto, E. and Duffy, S. W. and Ashton, H. A. and Walker, N. M. and Myles, J. P. and Scott, R. A. P. and Thompson, S. G. (2002) \emph{Probabilities of progression of aortic aneurysms: estimates and implications for screening policy} Journal of Medical Screening 9(1):40--42 } \keyword{datasets} msm/man/deltamethod.Rd0000644000176200001440000000643213051600620014400 0ustar liggesusers\name{deltamethod} \title{The delta method} \alias{deltamethod} \concept{Delta method} \description{ Delta method for approximating the standard error of a transformation \eqn{g(X)} of a random variable \eqn{X = (x_1, x_2, \ldots)}{X = (x1, x2, \ldots)}, given estimates of the mean and covariance matrix of \eqn{X}. } \usage{ deltamethod(g, mean, cov, ses=TRUE) } \arguments{ \item{g}{A formula representing the transformation. The variables must be labelled \code{x1, x2,\dots} For example, \code{~ 1 / (x1 + x2)} If the transformation returns a vector, then a list of formulae representing (\eqn{g_1, g_2, \ldots}{g1, g2, \ldots}) can be provided, for example \code{list( ~ x1 + x2, ~ x1 / (x1 + x2) )}} \item{mean}{The estimated mean of \eqn{X}} \item{cov}{The estimated covariance matrix of \eqn{X}} \item{ses}{If \code{TRUE}, then the standard errors of \eqn{g_1(X), g_2(X),\ldots}{g1(X), g2(X),\ldots} are returned. Otherwise the covariance matrix of \eqn{g(X)} is returned.} } \value{ A vector containing the standard errors of \eqn{g_1(X), g_2(X), \ldots}{g1(X), g2(X), \ldots} or a matrix containing the covariance of \eqn{g(X)}. } \details{ The delta method expands a differentiable function of a random variable about its mean, usually with a first-order Taylor approximation, and then takes the variance. For example, an approximation to the covariance matrix of \eqn{g(X)} is given by \deqn{ Cov(g(X)) = g'(\mu) Cov(X) [g'(\mu)]^T }{ Cov(g(X)) = g'(mu) Cov(X) [g'(mu)]^T } where \eqn{\mu}{mu} is an estimate of the mean of \eqn{X}. This function uses symbolic differentiation via \code{\link{deriv}}. A limitation of this function is that variables created by the user are not visible within the formula \code{g}. To work around this, it is necessary to build the formula as a string, using functions such as \code{sprintf}, then to convert the string to a formula using \code{as.formula}. See the example below. If you can spare the computational time, bootstrapping is a more accurate method of calculating confidence intervals or standard errors for transformations of parameters. See \code{\link{boot.msm}}. Simulation from the asymptotic distribution of the MLEs (see e.g. Mandel 2013) is also a convenient alternative. } \references{ Oehlert, G. W. (1992) \emph{A note on the delta method}. American Statistician 46(1). Mandel, M. (2013) \emph{Simulation based confidence intervals for functions with complicated derivatives.} The American Statistician 67(2):76-81. } \examples{ ## Simple linear regression, E(y) = alpha + beta x x <- 1:100 y <- rnorm(100, 4*x, 5) toy.lm <- lm(y ~ x) estmean <- coef(toy.lm) estvar <- summary(toy.lm)$cov.unscaled * summary(toy.lm)$sigma^2 ## Estimate of (1 / (alphahat + betahat)) 1 / (estmean[1] + estmean[2]) ## Approximate standard error deltamethod (~ 1 / (x1 + x2), estmean, estvar) ## We have a variable z we would like to use within the formula. z <- 1 ## deltamethod (~ z / (x1 + x2), estmean, estvar) will not work. ## Instead, build up the formula as a string, and convert to a formula. form <- sprintf("~ \%f / (x1 + x2)", z) form deltamethod(as.formula(form), estmean, estvar) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{math} msm/man/printold.msm.Rd0000644000176200001440000000115013051600620014524 0ustar liggesusers\name{printold.msm} \title{Print a fitted msm model object} \alias{printold.msm} \description{ Print a fitted msm model object (in old format, from msm 1.3.1 and earlier) } \usage{ printold.msm(x,\dots) } \arguments{ \item{x}{Output from \code{\link{msm}}, representing a fitted multi-state model object.} \item{...}{Other arguments to be passed to \code{\link{format}}.} } \seealso{ \code{\link{print.msm}} } \details{ See \code{\link{print.msm}} for a better and cleaner output format, and an explanation of the change. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/qmatrix.msm.Rd0000644000176200001440000001034013124671663014377 0ustar liggesusers\name{qmatrix.msm} \alias{qmatrix.msm} \title{Transition intensity matrix} \description{ Extract the estimated transition intensity matrix, and the corresponding standard errors, from a fitted multi-state model at a given set of covariate values. } \usage{ qmatrix.msm(x, covariates="mean", sojourn=FALSE, ci=c("delta","normal","bootstrap","none"), cl=0.95, B=1000, cores=NULL) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}.} \item{covariates}{ The covariate values at which to estimate the intensity matrix. This can either be:\cr the string \code{"mean"}, denoting the means of the covariates in the data (this is the default),\cr the number \code{0}, indicating that all the covariates should be set to zero,\cr or a list of values, with optional names. For example \code{list (60, 1)} where the order of the list follows the order of the covariates originally given in the model formula. Or more clearly, a named list, \code{list (age = 60, sex = 1)} If some covariates are specified but not others, the missing ones default to zero. With \code{covariates="mean"}, for factor / categorical variables, the mean of the 0/1 dummy variable for each factor level is used, representing an average over all values in the data, rather than a specific factor level. } \item{sojourn}{Set to TRUE if the estimated sojourn times and their standard errors should also be returned.} \item{ci}{ If \code{"delta"} (the default) then confidence intervals are calculated by the delta method, or by simple transformation of the Hessian in the very simplest cases. Normality on the log scale is assumed. If \code{"normal"}, then calculate a confidence interval by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects, then transforming. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}. } \item{cl}{Width of the symmetric confidence interval to present. Defaults to 0.95.} \item{B}{Number of bootstrap replicates, or number of normal simulations from the distribution of the MLEs.} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} } \value{ A list with components: \item{estimate}{Estimated transition intensity matrix.} \item{SE}{Corresponding approximate standard errors.} \item{L}{Lower confidence limits} \item{U}{Upper confidence limits} Or if \code{ci="none"}, then \code{qmatrix.msm} just returns the estimated transition intensity matrix. If \code{sojourn} is \code{TRUE}, extra components called \code{sojourn}, \code{sojournSE}, \code{sojournL} and \code{sojournU} are included, containing the estimates, standard errors and confidence limits, respectively, of the mean sojourn times in each transient state. The default print method for objects returned by \code{\link{qmatrix.msm}} presents estimates and confidence limits. To present estimates and standard errors, do something like \code{qmatrix.msm(x)[c("estimates","SE")]} } \details{ Transition intensities and covariate effects are estimated on the log scale by \code{\link{msm}}. A covariance matrix is estimated from the Hessian of the maximised log-likelihood. A more practically meaningful parameterisation of a continuous-time Markov model with transition intensities \eqn{q_{rs}} is in terms of the mean sojourn times \eqn{-1 / q_{rr}} in each state \eqn{r} and the probabilities that the next move of the process when in state \eqn{r} is to state \eqn{s}, \eqn{-q_{rs} / q_{rr}}. } \seealso{ \code{\link{pmatrix.msm}}, \code{\link{sojourn.msm}}, \code{\link{deltamethod}}, \code{\link{ematrix.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/ematrix.msm.Rd0000644000176200001440000000666513051600620014362 0ustar liggesusers\name{ematrix.msm} \alias{ematrix.msm} \title{Misclassification probability matrix} \description{ Extract the estimated misclassification probability matrix, and corresponding confidence intervals, from a fitted multi-state model at a given set of covariate values. } \usage{ ematrix.msm(x, covariates="mean", ci=c("delta","normal","bootstrap","none"), cl=0.95, B=1000, cores=NULL) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}}. \item{covariates}{ The covariate values for which to estimate the misclassification probability matrix. This can either be:\cr the string \code{"mean"}, denoting the means of the covariates in the data (this is the default),\cr the number \code{0}, indicating that all the covariates should be set to zero,\cr or a list of values, with optional names. For example \code{list (60, 1)} where the order of the list follows the order of the covariates originally given in the model formula, or a named list, \code{list (age = 60, sex = 1)} } \item{ci}{ If \code{"delta"} (the default) then confidence intervals are calculated by the delta method, or by simple transformation of the Hessian in the very simplest cases. If \code{"normal"}, then calculate a confidence interval by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the multinomial-logit-transformed misclassification probabilities and covariate effects, then transforming back. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}.} \item{cl}{Width of the symmetric confidence interval to present. Defaults to 0.95.} \item{B}{Number of bootstrap replicates, or number of normal simulations from the distribution of the MLEs} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} } \value{ A list with components: \item{estimate}{Estimated misclassification probability matrix. The rows correspond to true states, and columns observed states.} \item{SE}{Corresponding approximate standard errors.} \item{L}{Lower confidence limits.} \item{U}{Upper confidence limits.} Or if \code{ci="none"}, then \code{ematrix.msm} just returns the estimated misclassification probability matrix. The default print method for objects returned by \code{\link{ematrix.msm}} presents estimates and confidence limits. To present estimates and standard errors, do something like \code{ematrix.msm(x)[c("estimates","SE")]} } \details{ Misclassification probabilities and covariate effects are estimated on the multinomial-logit scale by \code{\link{msm}}. A covariance matrix is estimated from the Hessian of the maximised log-likelihood. From these, the delta method can be used to obtain standard errors of the probabilities on the natural scale at arbitrary covariate values. Confidence intervals are estimated by assuming normality on the multinomial-logit scale. } \seealso{ \code{\link{qmatrix.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/msm.form.qoutput.Rd0000644000176200001440000000325313051600620015362 0ustar liggesusers\name{msm.form.qoutput} \alias{msm.form.qoutput} \alias{msm.form.eoutput} \title{Extract msm model parameter estimates in compact format} \description{Extract estimates and confidence intervals for transition intensities (or misclassification probabilities), and their covariate effects, in a tidy matrix format with one row per transition. This is used by the print method (\code{\link{print.msm}}) for \code{msm} objects. Covariate effects are returned as hazard or odds ratios, not on the log scale. } \usage{ msm.form.qoutput(x, covariates="mean", cl=0.95, digits=4, ...) msm.form.eoutput(x, covariates="mean", cl=0.95, digits=4, ...) } \arguments{ \item{x}{A fitted multi-state model object, as returned by \code{\link{msm}}.} \item{covariates}{Covariate values defining the "baseline" parameters (see \code{\link{qmatrix.msm}}).} \item{cl}{Width of the symmetric confidence interval to present. Defaults to 0.95.} \item{digits}{Minimum number of significant digits for the formatted character matrix returned as an attribute. This is passed to \code{\link{format}}. Defaults to 4.} \item{...}{Other arguments to be passed to \code{\link{format}}.} } \value{ A numeric matrix with one row per transition, and one column for each estimate or confidence limit. The \code{"formatted"} attribute contains the same results formatted for pretty printing. \code{msm.form.qoutput} returns the transition intensities and their covariates, and \code{msm.form.eoutput} returns the misclassification probabilities and their covariates. } \seealso{ \code{\link{print.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/qgeneric.Rd0000644000176200001440000000475513051600620013711 0ustar liggesusers\name{qgeneric} \alias{qgeneric} \title{Generic function to find quantiles of a distribution} \description{ Generic function to find the quantiles of a distribution, given the equivalent probability distribution function. } \usage{ qgeneric(pdist, p, special=NULL, ...) } \arguments{ \item{pdist}{ Probability distribution function, for example, \code{\link{pnorm}} for the normal distribution, which must be defined in the current workspace. This should accept and return vectorised parameters and values. It should also return the correct values for the entire real line, for example a positive distribution should have \code{pdist(x)==0} for \eqn{x<0}. } \item{p}{ Vector of probabilities to find the quantiles for. } \item{special}{Vector of character strings naming arguments of the distribution function that should not be vectorised over. Used, for example, for the \code{rate} and \code{t} arguments in \code{\link{qpexp}}.} \item{...}{ The remaining arguments define parameters of the distribution \code{pdist}. These MUST be named explicitly. This may also contain the standard arguments \code{log.p} (logical; default \code{FALSE}, if \code{TRUE}, probabilities p are given as log(p)), and \code{lower.tail} (logical; if \code{TRUE} (default), probabilities are P[X <= x] otherwise, P[X > x].). If the distribution is bounded above or below, then this should contain arguments \code{lbound} and \code{ubound} respectively, and these will be returned if \code{p} is 0 or 1 respectively. Defaults to \code{-Inf} and \code{Inf} respectively. } } \value{ Vector of quantiles of the distribution at \code{p}. } \details{ This function is intended to enable users to define \code{"q"} functions for new distributions, in cases where the distribution function \code{pdist} is available analytically, but the quantile function is not. It works by finding the root of the equation \eqn{h(q) = pdist(q) - p = 0}. Starting from the interval \eqn{(-1, 1)}, the interval width is expanded by 50\% until \eqn{h()} is of opposite sign at either end. The root is then found using \code{\link{uniroot}}. This assumes a suitably smooth, continuous distribution. An identical function is provided in the \pkg{flexsurv} package. } \examples{ qnorm(c(0.025, 0.975), 0, 1) qgeneric(pnorm, c(0.025, 0.975), mean=0, sd=1) # must name the arguments } \author{ Christopher Jackson } \keyword{distribution} msm/man/pmatrix.msm.Rd0000644000176200001440000001247313647241675014415 0ustar liggesusers\name{pmatrix.msm} \alias{pmatrix.msm} \title{Transition probability matrix} \description{ Extract the estimated transition probability matrix from a fitted continuous-time multi-state model for a given time interval, at a given set of covariate values. } \usage{ pmatrix.msm(x=NULL, t=1, t1=0, covariates="mean", ci=c("none","normal","bootstrap"), cl=0.95, B=1000, cores=NULL, qmatrix=NULL, ...) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}.} \item{t}{The time interval to estimate the transition probabilities for, by default one unit. } \item{t1}{The starting time of the interval. Used for models \code{x} with piecewise-constant intensities fitted using the \code{pci} option to \code{\link{msm}}. The probabilities will be computed on the interval [t1, t1+t].} \item{covariates}{ The covariate values at which to estimate the transition probabilities. This can either be:\cr the string \code{"mean"}, denoting the means of the covariates in the data (this is the default),\cr the number \code{0}, indicating that all the covariates should be set to zero,\cr or a list of values, with optional names. For example \code{list (60, 1)} where the order of the list follows the order of the covariates originally given in the model formula, or a named list, \code{list (age = 60, sex = 1)} If some covariates are specified but not others, the missing ones default to zero. For time-inhomogeneous models fitted using the \code{pci} option to \code{\link{msm}}, "covariates" here include only those specified using the \code{covariates} argument to \code{\link{msm}}, and exclude the artificial covariates representing the time period. For time-inhomogeneous models fitted "by hand" by using a time-dependent covariate in the \code{covariates} argument to \code{\link{msm}}, the function \code{\link{pmatrix.piecewise.msm}} should be used to to calculate transition probabilities. } \item{ci}{If \code{"normal"}, then calculate a confidence interval for the transition probabilities by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects, then calculating the resulting transition probability matrix for each replicate. See, e.g. Mandel (2013) for a discussion of this approach. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}. If \code{"none"} (the default) then no confidence interval is calculated.} \item{cl}{Width of the symmetric confidence interval, relative to 1.} \item{B}{Number of bootstrap replicates, or number of normal simulations from the distribution of the MLEs} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} \item{qmatrix}{A transition intensity matrix. Either this or a fitted model \code{x} must be supplied. No confidence intervals are available if \code{qmatrix} is supplied.} \item{...}{Optional arguments to be passed to \code{\link{MatrixExp}} to control the method of computing the matrix exponential.} } \value{ The matrix of estimated transition probabilities \eqn{P(t)} in the given time. Rows correspond to "from-state" and columns to "to-state". Or if \code{ci="normal"} or \code{ci="bootstrap"}, \code{pmatrix.msm} returns a list with components \code{estimates} and \code{ci}, where \code{estimates} is the matrix of estimated transition probabilities, and \code{ci} is a list of two matrices containing the upper and lower confidence limits. } \details{ For a continuous-time homogeneous Markov process with transition intensity matrix \eqn{Q}, the probability of occupying state \eqn{s} at time \eqn{u + t} conditionally on occupying state \eqn{r} at time \eqn{u} is given by the \eqn{(r,s)} entry of the matrix \eqn{P(t) = \exp(tQ)}{P(t) = exp(tQ)}, where \eqn{\exp()}{exp()} is the matrix exponential. For non-homogeneous processes, where covariates and hence the transition intensity matrix \eqn{Q} are piecewise-constant in time, the transition probability matrix is calculated as a product of matrices over a series of intervals, as explained in \code{\link{pmatrix.piecewise.msm}}. The \code{\link{pmatrix.piecewise.msm}} function is only necessary for models fitted using a time-dependent covariate in the \code{covariates} argument to \code{\link{msm}}. For time-inhomogeneous models fitted using "pci", \code{pmatrix.msm} can be used, with arguments \code{t} and \code{t1}, to calculate transition probabilities over any time period. } \references{ Mandel, M. (2013). "Simulation based confidence intervals for functions with complicated derivatives." The American Statistician 67(2):76-81 } \seealso{ \code{\link{qmatrix.msm}}, \code{\link{pmatrix.piecewise.msm}}, \code{\link{boot.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}.} \keyword{models} msm/man/summary.msm.Rd0000644000176200001440000000247213051600620014376 0ustar liggesusers\name{msm.summary} \title{Summarise a fitted multi-state model} \alias{summary.msm} \alias{print.summary.msm} \description{ Summary method for fitted \code{\link{msm}} models. This is simply a wrapper around \code{\link{prevalence.msm}} which produces a table of observed and expected state prevalences for each time, and for models with covariates, \code{\link{hazard.msm}} to print hazard ratios with 95\% confidence intervals for covariate effects. } \usage{ \method{summary}{msm}(object, hazard.scale=1, \dots) } \arguments{ \item{object}{A fitted multi-state model object, as returned by \code{\link{msm}}.} \item{hazard.scale}{Vector with same elements as number of covariates on transition rates. Corresponds to the increase in each covariate used to calculate its hazard ratio. Defaults to all 1.} \item{...}{Further arguments passed to \code{\link{prevalence.msm}}. } } \value{ A list of class \code{summary.msm}, with components: \item{prevalences}{Output from \code{\link{prevalence.msm}}.} \item{hazard}{Output from \code{\link{hazard.msm}}.} \item{hazard.scale}{Value of the \code{hazard.scale} argument.} } \seealso{ \code{\link{msm}},\code{\link{prevalence.msm}}, \code{\link{hazard.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/msm2Surv.Rd0000644000176200001440000001433614124277127013664 0ustar liggesusers\name{msm2Surv} \alias{msm2Surv} \title{Convert data for `msm' to data for `survival', `mstate' or `flexsurv' analysis} \description{ Converts longitudinal data for a \code{\link{msm}} model fit, where observations represent the exact transition times of the process, to counting process data. This enables, for example, flexible parametric multi-state models to be fitted with \code{\link[flexsurv]{flexsurvreg}} from the \pkg{flexsurv} package, or semiparametric models to be implemented with \code{\link[survival]{coxph}} and the \pkg{mstate} package. } \usage{ msm2Surv(data, subject, time, state, covs, Q) } \arguments{ \item{data}{Data frame in the format expected by a \code{\link{msm}} model fit with \code{exacttimes=TRUE} or all \code{obstype=2}. Each row represents an observation of a state, and the time variable contains the exact and complete transition times of the underlying process. This is explained in more detail in the help page for \code{\link{msm}}, section \code{obstype=2}. } \item{subject}{Name of the subject ID in the data (character format, i.e. quoted).} \item{time}{Name of the time variable in the data (character).} \item{state}{Name of the state variable in the data (character).} \item{covs}{Vector of covariate names to carry through (character). If not supplied, this is taken to be all remaining variables in the data. } \item{Q}{Transition intensity matrix. This should have number of rows and number of columns both equal to the number of states. If an instantaneous transition is not allowed from state \eqn{r} to state \eqn{s}, then \code{Q} should have \eqn{(r,s)} entry 0, otherwise it should be non-zero. The diagonal entries are ignored.} } \value{ A data frame of class \code{"msdata"}, with rows representing observed or censored transitions. There will be one row for each observed transition in the original data, and additional rows for every potential transition that could have occurred out of each observed state. The data frame will have columns called: \item{id}{Subject ID} \item{from}{Starting state of the transition} \item{to}{Finishing state of the transition} \item{Tstart}{The starting time of the transition} \item{Tstop}{The finishing time of the transition} \item{time}{The time difference = \code{Tstop} - \code{Tstart}} \item{status}{Event or censoring indicator, with 1 indicating an observed transition, and 0 indicating censoring} \item{trans}{Transition number} and any remaining columns will represent covariates. Any covariates whose names clash with the standard variables in the returned data (\code{"id"}, \code{"from"}, \code{"to"}, \code{"Tstart"}, \code{"Tstop"}, \code{"time"}, \code{"status"} or \code{"trans"}) have \code{".2"} appended to their names. The transition matrix in \pkg{mstate} format is stored in the \code{trans} attribute of the returned object. See the example code below. } \details{ For example, if the data supplied to \code{\link{msm}} look like this: \tabular{lllll}{ \code{subj} \tab \code{days} \tab \code{status} \tab \code{age} \tab \code{treat} \cr 1\tab 0\tab 1 \tab 66\tab 1\cr 1\tab 27\tab 2 \tab 66\tab 1\cr 1\tab 75\tab 3 \tab 66\tab 1\cr 1\tab 97\tab 4 \tab 66\tab 1\cr 1\tab 1106\tab 4 \tab 69\tab 1\cr 2\tab 0\tab 1 \tab 49\tab 0\cr 2\tab 90\tab 2 \tab 49\tab 0\cr 2\tab 1037\tab 2 \tab 51\tab 0\cr } then the output of \code{\link{msm2Surv}} will be a data frame looking like this: \tabular{lllllllllll}{ \code{id} \tab \code{from} \tab \code{to} \tab \code{Tstart} \tab \code{Tstop} \tab \code{time} \tab \code{status} \tab \code{age} \tab \code{treat} \tab \code{trans}\cr 1 \tab 1 \tab 2 \tab 0 \tab 27 \tab 27 \tab 1 \tab 66 \tab 1 \tab 1\cr 1 \tab 1 \tab 4 \tab 0 \tab 27 \tab 27 \tab 0 \tab 66 \tab 1 \tab 2\cr 1 \tab 2 \tab 3 \tab 27 \tab 75 \tab 48 \tab 1 \tab 66 \tab 1 \tab 3\cr 1 \tab 2 \tab 4 \tab 27 \tab 75 \tab 48 \tab 0 \tab 66 \tab 1 \tab 4\cr 1 \tab 3 \tab 4 \tab 75 \tab 97 \tab 22 \tab 1 \tab 69 \tab 1 \tab 5\cr 2 \tab 1 \tab 2 \tab 0 \tab 90 \tab 90 \tab 1 \tab 49 \tab 0 \tab 1\cr 2 \tab 1 \tab 4 \tab 0 \tab 90 \tab 90 \tab 0 \tab 49 \tab 0 \tab 2\cr 2 \tab 2 \tab 3 \tab 90 \tab 1037 \tab 947 \tab 0 \tab 49 \tab 0 \tab 3\cr 2 \tab 2 \tab 4 \tab 90 \tab 1037 \tab 947 \tab 0\tab 49 \tab 0 \tab 4\cr } At 27 days, subject 1 is observed to move from state 1 to state 2 (first row, status 1), which means that their potential transition from state 1 to state 4 is censored (second row, status 0). See the \pkg{mstate} package and the references below for more details of this data format and using it for semi-parametric multi-state modelling. } \references{ Putter H, Fiocco M, Geskus RB (2007). Tutorial in biostatistics: Competing risks and multi-state models. \emph{Statistics in Medicine} 26: 2389-2430. Liesbeth C. de Wreede, Marta Fiocco, Hein Putter (2011). \pkg{mstate}: An R Package for the Analysis of Competing Risks and Multi-State Models. \emph{Journal of Statistical Software}, 38(7), 1-30. \url{https://www.jstatsoft.org/v38/i07} Jackson, C. H. (2014). flexsurv: Flexible parametric survival and multi-state models. R package version 0.5. } \seealso{ \code{\link[mstate]{msprep}}, in \pkg{mstate}, which produces data in a similar format, given data in "wide" format with one row per subject. } \examples{ msmdat <- data.frame( subj = c(1, 1, 1, 1, 1, 2, 2, 2), days = c(0, 27, 75, 97, 1106, 0, 90, 1037), status = c(1, 2, 3, 4, 4, 1, 2, 2), age = c(66, 66, 66, 66, 69, 49, 49, 51), treat = c(1, 1, 1, 1, 1, 0, 0, 0) ) # transitions only allowed to next state up or state 4 Q <- rbind(c(1, 1, 0, 1), c(0, 1, 1, 1), c(0, 0, 1, 1), c(0, 0, 0, 0)) dat <- msm2Surv(data=msmdat, subject="subj", time="days", state="status", Q=Q) dat attr(dat, "trans") } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} msm/man/efpt.msm.Rd0000644000176200001440000001335213051600620013636 0ustar liggesusers\name{efpt.msm} \alias{efpt.msm} \title{Expected first passage time} \description{ Expected time until first reaching a particular state or set of states in a Markov model. } \usage{ efpt.msm(x=NULL, qmatrix=NULL, tostate, start="all", covariates="mean", ci=c("none","normal","bootstrap"), cl=0.95, B=1000, cores=NULL, \dots) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}. } \item{qmatrix}{Instead of \code{x}, you can simply supply a transition intensity matrix in \code{qmatrix}.} \item{tostate}{State, or set of states supplied as a vector, for which to estimate the first passage time into. Can be integer, or character matched to the row names of the Q matrix.} \item{start}{Starting state (integer). By default (\code{start="all"}), this will return a vector of expected passage times from each state in turn. Alternatively, this can be used to obtain the expected first passage time from a \emph{set} of states, rather than single states. To achieve this, \code{state} is set to a vector of weights, with length equal to the number of states in the model. These weights should be proportional to the probability of starting in each of the states in the desired set, so that weights of zero are supplied for other states. The function will calculate the weighted average of the expected passage times from each of the corresponding states. } \item{covariates}{Covariate values defining the intensity matrix for the fitted model \code{x}, as supplied to \code{\link{qmatrix.msm}}.} \item{ci}{If \code{"normal"}, then calculate a confidence interval by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}. If \code{"none"} (the default) then no confidence interval is calculated.} \item{cl}{Width of the symmetric confidence interval, relative to 1.} \item{B}{Number of bootstrap replicates.} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} \item{...}{Arguments to pass to \code{\link{MatrixExp}}.} } \value{ A vector of expected first passage times, or "hitting times", from each state to the desired state. } \details{ The expected first passage times from each of a set of states \eqn{\mathbf{i}}{i} to to the remaining set of states \eqn{\overline{\mathbf{i}}}{ibar} in the state space, for a model with transition intensity matrix \eqn{Q}, are \deqn{-Q_{\mathbf{i},\mathbf{i}}^{-1} \mathbf{1}}{-Q_{i,i}^{-1} 1} where \eqn{\mathbf{1}}{1} is a vector of ones, and \eqn{Q_{\mathbf{i},\mathbf{i}}}{Q_{i,i}} is the square subset of \eqn{Q} pertaining to states \eqn{\mathbf{i}}{i}. It is equal to the sum of mean sojourn times for all states between the "from" and "to" states in a unidirectional model. If there is non-zero chance of reaching an absorbing state before reaching \code{tostate}, then it is infinite. It is trivially zero if the "from" state equals \code{tostate}. This function currently only handles time-homogeneous Markov models. For time-inhomogeneous models it will assume that \eqn{Q} equals the average intensity matrix over all times and observed covariates. Simulation might be used to handle time dependence. Note this is the \emph{expectation} of first passage time, and the confidence intervals are CIs for this mean, not predictive intervals for the first passage time. The full distribution of the first passage time to a set of states can be obtained by setting the rows of the intensity matrix \eqn{Q} corresponding to that set of states to zero to make a model where those states are absorbing. The corresponding transition probability matrix \eqn{Exp(Qt)} then gives the probabilities of having hit or passed that state by a time \eqn{t} (see the example below). This is implemented in \code{\link{ppass.msm}}. } \references{ Norris, J. R. (1997) Markov Chains. Cambridge University Press. } \seealso{ \code{\link{sojourn.msm}}, \code{\link{totlos.msm}}, \code{\link{boot.msm}}. } \examples{ twoway4.q <- rbind(c(-0.5, 0.25, 0, 0.25), c(0.166, -0.498, 0.166, 0.166), c(0, 0.25, -0.5, 0.25), c(0, 0, 0, 0)) efpt.msm(qmatrix=twoway4.q, tostate=3) # given in state 1, expected time to reaching state 3 is infinite # since may die (state 4) before entering state 3 # If we remove the death state from the model, EFPTs become finite Q <- twoway4.q[1:3,1:3]; diag(Q) <- 0; diag(Q) <- -rowSums(Q) efpt.msm(qmatrix=Q, tostate=3) # Suppose we cannot die or regress while in state 2, can only go to state 3 Q <- twoway4.q; Q[2,4] <- Q[2,1] <- 0; diag(Q) <- 0; diag(Q) <- -rowSums(Q) efpt.msm(qmatrix=Q, tostate=3) # The expected time from 2 to 3 now equals the mean sojourn time in 2. -1/Q[2,2] # Calculate cumulative distribution of the first passage time # into state 3 for the following three-state model Q <- twoway4.q[1:3,1:3]; diag(Q) <- 0; diag(Q) <- -rowSums(Q) # Firstly form a model where the desired hitting state is absorbing Q[3,] <- 0 MatrixExp(Q, t=10)[,3] ppass.msm(qmatrix=Q, tot=10) # Given in state 1 at time 0, P(hit 3 by time 10) = 0.479 MatrixExp(Q, t=50)[,3] # P(hit 3 by time 50) = 0.98 ppass.msm(qmatrix=Q, tot=50) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/scoreresid.msm.Rd0000644000176200001440000000245713051600620015046 0ustar liggesusers\name{scoreresid.msm} \alias{scoreresid.msm} \title{Score residuals} \description{ Score residuals for detecting outlying subjects. } \usage{ scoreresid.msm(x, plot=FALSE) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}.} \item{plot}{If \code{TRUE}, display a simple plot of the residuals in subject order, labelled by subject identifiers} } \value{ Vector of the residuals, named by subject identifiers. } \details{ The score residual for a single subject is \deqn{U(\theta)^T I(\theta)^{-1} U(\theta)}{U(theta)^T I(theta)^{-1} U(theta)} where \eqn{U(\theta)}{U(theta)} is the vector of first derivatives of the log-likelihood for that subject at maximum likelihood estimates \eqn{\theta}{theta}, and \eqn{I(\theta)}{theta} is the observed Fisher information matrix, that is, the matrix of second derivatives of minus the log-likelihood for that subject at theta. Subjects with a higher influence on the maximum likelihood estimates will have higher score residuals. These are only available for models with analytic derivatives (which includes all non-hidden and most hidden Markov models). } \author{Andrew Titman \email{a.titman@lancaster.ac.uk} (theory), Chris Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk} (code)} \keyword{models}msm/man/cmodel.object.Rd0000644000176200001440000000152113051600620014610 0ustar liggesusers\name{cmodel.object} \alias{cmodel.object} \title{Developer documentation: censoring model object} \description{A list giving information about censored states, their labels in the data and what true states they represent.} \value{ \item{ncens}{The number of distinct values used for censored observations in the \code{state} data supplied to \code{\link{msm}}.} \item{censor}{A vector of length \code{ncens}, giving the labels used for censored states in the data.} \item{states}{A vector obtained by \code{unlist()}ing a list with \code{ncens} elements, each giving the set of true states that an observation with this label could be.} \item{index}{Index into \code{states} for the first state corresponding to each \code{censor}, plus an extra \code{length(states)+1}.} } \seealso{ \code{\link{msm.object}}. } msm/man/draic.msm.Rd0000644000176200001440000001473613051600620013771 0ustar liggesusers\name{draic.msm} \alias{draic.msm} \alias{drlcv.msm} \title{Criteria for comparing two multi-state models with nested state spaces} \description{ A modification of Akaike's information criterion, and a leave-one-out likelihood cross-validation criterion, for comparing the predictive ability of two Markov multi-state models with nested state spaces. This is evaluated based on the restricted or aggregated data which the models have in common. Note that standard AIC can be computed for one or more fitted \code{msm} models \code{x,y,...} using \code{\link{AIC}(x,y,...)}, and this can be used to compare models fitted to the same data. \code{draic.msm} and \code{drlcv.msm} are designed for models fitted to data with differently-aggregated state spaces. } \usage{ draic.msm(msm.full, msm.coarse, likelihood.only=FALSE, information=c("expected","observed"), tl=0.95) drlcv.msm(msm.full, msm.coarse, tl=0.95, cores=NULL, verbose=TRUE,outfile=NULL) } \arguments{ \item{msm.full}{Model on the bigger state space.} \item{msm.coarse}{Model on the smaller state space. The two models must both be non-hidden Markov models without censored states. The two models must be fitted to the same datasets, except that the state space of the coarse model must be an aggregated version of the state space of the full model. That is, every state in the full dataset must correspond to a unique state in the coarse dataset. For example, for the full state variable \code{c(1,1,2,2,3,4)}, the corresponding coarse states could be \code{c(1,1,2,2,2,3)}, but not \code{c(1,2,3,4,4,4)}. The structure of allowed transitions in the coarse model must also be a collapsed version of the big model structure, but no check is currently made for this in the code. To use these functions, all objects which were used in the calls to fit \code{msm.full} and \code{msm.coarse} must be in the working environment, for example, datasets and definitions of transition matrices. } \item{likelihood.only}{Don't calculate Hessians and trace term (DRAIC).} \item{information}{Use observed or expected information in the DRAIC trace term. Expected is the default, and much faster, though is only available for models fitted to pure panel data (all \code{obstype=1} in the call to \code{\link{msm}}, thus not exact transition times or exact death times) } \item{tl}{Width of symmetric tracking interval, by default 0.95 for a 95\% interval.} \item{cores}{Number of processor cores to use in \code{drlcv} for cross-validation by parallel processing. Requires the \pkg{doParallel} package to be installed. If not specified, parallel processing is not used. If \code{cores} is set to the string \code{"default"}, the default methods of \code{\link[parallel]{makeCluster}} (on Windows) or \code{\link[doParallel]{registerDoParallel}} (on Unix-like) are used.} \item{verbose}{Print intermediate results of each iteration of cross-validation to the console while running. May not work with parallel processing. } \item{outfile}{Output file to print intermediate results of cross-validation. Useful to track execution speed when using parallel processing, where output to the console may not work.} } \value{ A list containing \eqn{D_{RAIC}}{D_RAIC} (\code{draic.msm}) or \eqn{D_{RLCV}}{D_RLCV} (\code{drlcv.msm}), its component terms, and tracking intervals. } \details{ The difference in restricted AIC (Liquet and Commenges, 2011), as computed by this function, is defined as \deqn{D_{RAIC} = l(\gamma_n |\mathbf{x}'' ) - l(\theta_n |\mathbf{x}'' ) + trace ( J(\theta_n |\mathbf{x}'')J(\theta_n |\mathbf{x})^{-1} - J(\gamma_n |\mathbf{x}'' )J(\gamma_n |\mathbf{x}' )^{-1})}{D_RAIC = l(gamma_n |x'' ) - l(theta_n |x'' ) + trace ( J(theta_n |x'')J(theta_n |x)^{-1} - J(gamma_n |x'' )J(gamma_n |x' )^{-1})} where \eqn{\gamma}{gamma} and \eqn{\theta}{theta} are the maximum likelihood estimates of the smaller and bigger models, fitted to the smaller and bigger data, respectively. \eqn{l(\gamma_n |x'')}{l(gamma_n |x'')} represents the likelihood of the simpler model evaluated on the restricted data. \eqn{l(\theta_n |x'')}{l(theta_n |x'')} represents the likelihood of the complex model evaluated on the restricted data. This is a hidden Markov model, with a misclassification matrix and initial state occupancy probabilities as described by Thom et al (2014). \eqn{J()} are the corresponding (expected or observed, as specified by the user) information matrices. \eqn{\mathbf{x}}{x} is the expanded data, to which the bigger model was originally fitted, and \eqn{\mathbf{x}'}{x'} is the data to which the smaller model was originally fitted. \eqn{\mathbf{x}''}{x''} is the restricted data which the two models have in common. \eqn{\mathbf{x}'' = \mathbf{x}'}{x'' = x} in this implementation, so the models are nested. The difference in likelihood cross-validatory criteria (Liquet and Commenges, 2011) is defined as \deqn{D_{RLCV} = 1/n \sum_{i=1}^n \log( h_{X''}(x_i'' | \gamma_{-i}) / g_{X''}(x_i''| \theta_{-i}))}{D_{RLCV} = 1/n \sum_{i=1}^n log( h_{X''}(x_i'' | gamma_{-i}) / g_{X''}(x_i''| theta_{-i}))} where \eqn{\gamma_{-i}} and \eqn{\theta_{-i}} are the maximum likelihood estimates from the smaller and bigger models fitted to datasets with subject \eqn{i} left out, \eqn{g()} and \eqn{h()} are the densities of the corresponding models, and \eqn{x_i''} is the restricted data from subject \eqn{i}. Tracking intervals are analogous to confidence intervals, but not strictly the same, since the quantity which D_RAIC aims to estimate, the difference in expected Kullback-Leibler discrepancy for predicting a replicate dataset, depends on the sample size. See the references. Positive values for these criteria indicate the coarse model is preferred, while negative values indicate the full model is preferred. } \references{ Thom, H. and Jackson, C. and Commenges, D. and Sharples, L. (2015) State selection in multistate models with application to quality of life in psoriatic arthritis. Statistics In Medicine 34(16) 2381 - 2480. Liquet, B. and Commenges D. (2011) Choice of estimators based on different observations: Modified AIC and LCV criteria. Scandinavian Journal of Statistics; 38:268-287. } \seealso{ \code{\link{logLik.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}, H. H. Z. Thom \email{howard.thom@bristol.ac.uk}} \keyword{models} msm/man/emodel.object.Rd0000644000176200001440000000410513051600620014613 0ustar liggesusers\name{emodel.object} \alias{emodel.object} \title{Developer documentation: misclassification model structure object} \description{ A list giving information about the misclassifications assumed in a multi-state model fitted with the \code{ematrix} argument of \code{\link{msm}}. Returned in a fitted \code{\link{msm}} model object. This information is converted internally to a \code{hmodel} object (see \code{\link{hmodel.object}}) for use in likelihood computations. } \value{ \item{nstates}{Number of states (same as \code{qmodel$nstates}).} \item{npars}{Number of allowed misclassifications, equal to \code{sum(imatrix)}.} \item{imatrix}{Indicator matrix for allowed misclassifications. This has \eqn{(r,s)} entry 1 if misclassification of true state \eqn{r} as observed state \eqn{s} is possible. diagonal entries are arbitrarily set to 0.} \item{ematrix}{Matrix of initial values for the misclassification probabilities, supplied as the \code{ematrix} argument of \code{\link{msm}}.} \item{inits}{Vector of these initial values, reading across rows of \code{qmatrix} and excluding the diagonal and disallowed transitions.} \item{constr}{Indicators for equality constraints on baseline misclassification probabilities, taken from the \code{econstraint} argument to \code{\link{msm}}, and mapped if necessary to the set (1,2,3,...)} \item{ndpars}{Number of distinct misclassification probabilities, after applying equality constraints.} \item{nipars}{Number of initial state occupancy probabilities being estimated. This is zero if \code{est.initprobs=FALSE}, otherwise equal to the number of states.} \item{initprobs}{Initial state occupancy probabilities, as supplied to \code{\link{msm}} (initial values before estimation, if \code{est.initprobs=TRUE}.)} \item{est.initprobs}{Are initial state occupancy probabilities estimated (\code{TRUE} or \code{FALSE}), as supplied in the \code{est.initprobs} argument of \code{\link{msm}}.} } \seealso{ \code{\link{msm.object}},\code{\link{qmodel.object}}, \code{\link{hmodel.object}}. }msm/man/plot.msm.Rd0000644000176200001440000000345013051600620013654 0ustar liggesusers\name{plot.msm} \title{Plots of multi-state models} \alias{plot.msm} \concept{Survival} \description{ This produces a plot of the expected probability of survival against time, from each transient state. Survival is defined as not entering an absorbing state. } \usage{ \method{plot}{msm}(x, from, to, range, covariates, legend.pos, xlab="Time", ylab="Fitted survival probability", lwd=1, ...) } \arguments{ \item{x}{Output from \code{\link{msm}}, representing a fitted multi-state model object.} \item{from}{States from which to consider survival. Defaults to the complete set of transient states. } \item{to}{Absorbing state to consider. Defaults to the highest-labelled absorbing state. } \item{range}{Vector of two elements, giving the range of times to plot for.} \item{covariates}{Covariate values for which to evaluate the expected probabilities. This can either be:\cr the string \code{"mean"}, denoting the means of the covariates in the data (this is the default),\cr the number \code{0}, indicating that all the covariates should be set to zero,\cr or a list of values, with optional names. For example \code{list (60, 1)} where the order of the list follows the order of the covariates originally given in the model formula, or a named list, \code{list (age = 60, sex = 1)} } \item{legend.pos}{Vector of the \eqn{x} and \eqn{y} position, respectively, of the legend.} \item{xlab}{x axis label.} \item{ylab}{y axis label.} \item{lwd}{Line width. See \code{\link{par}}.} \item{...}{Other arguments to be passed to the generic \code{\link{plot}} and \code{\link{lines}} functions.} } \seealso{ \code{\link{msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/simmulti.msm.Rd0000644000176200001440000001431713051600620014545 0ustar liggesusers\name{simmulti.msm} \title{Simulate multiple trajectories from a multi-state Markov model with arbitrary observation times} \alias{simmulti.msm} \concept{Simulation} \description{Simulate a number of individual realisations from a continuous-time Markov process. Observations of the process are made at specified arbitrary times for each individual, giving panel-observed data. } \usage{ simmulti.msm(data, qmatrix, covariates=NULL, death = FALSE, start, ematrix=NULL, misccovariates=NULL, hmodel=NULL, hcovariates=NULL, censor.states=NULL, drop.absorb=TRUE) } \arguments{ \item{data}{A data frame with a mandatory column named \code{time}, representing observation times. The optional column named \code{subject}, corresponds to subject identification numbers. If not given, all observations are assumed to be on the same individual. Observation times should be sorted within individuals. The optional column named \code{cens} indicates the times at which simulated states should be censored. If \code{cens==0} then the state is not censored, and if \code{cens==k}, say, then all simulated states at that time which are in the set \code{censor.states} are replaced by \code{k}. Other named columns of the data frame represent any covariates, which may be time-constant or time-dependent. Time-dependent covariates are assumed to be constant between the observation times. } \item{qmatrix}{ The transition intensity matrix of the Markov process, with any covariates set to zero. The diagonal of \code{qmatrix} is ignored, and computed as appropriate so that the rows sum to zero. For example, a possible \code{qmatrix} for a three state illness-death model with recovery is: \code{rbind( c( 0, 0.1, 0.02 ), c( 0.1, 0, 0.01 ), c( 0, 0, 0 ) )} } \item{covariates}{List of linear covariate effects on log transition intensities. Each element is a vector of the effects of one covariate on all the transition intensities. The intensities are ordered by reading across rows of the intensity matrix, starting with the first, counting the positive off-diagonal elements of the matrix. For example, for a multi-state model with three transition intensities, and two covariates \code{x} and \code{y} on each intensity, \code{covariates=list(x = c(-0.3,-0.3,-0.3), y=c(0.1, 0.1, 0.1))} } \item{death}{Vector of indices of the death states. A death state is an absorbing state whose time of entry is known exactly, but the individual is assumed to be in an unknown transient state ("alive") at the previous instant. This is the usual situation for times of death in chronic disease monitoring data. For example, if you specify \code{death = c(4, 5)} then states 4 and 5 are assumed to be death states. \code{death = TRUE} indicates that the final state is a death state, and \code{death = FALSE} (the default) indicates that there is no death state. } \item{start}{A vector with the same number of elements as there are distinct subjects in the data, giving the states in which each corresponding individual begins. Or a single number, if all of these are the same. Defaults to state 1 for each subject.} \item{ematrix}{An optional misclassification matrix for generating observed states conditionally on the simulated true states. As defined in \code{\link{msm}}.} \item{misccovariates}{Covariate effects on misclassification probabilities via multinomial logistic regression. Linear effects operate on the log of each probability relative to the probability of classification in the correct state. In same format as \code{covariates}.} \item{hmodel}{An optional hidden Markov model for generating observed outcomes conditionally on the simulated true states. As defined in \code{\link{msm}}.} \item{hcovariates}{List of the same length as \code{hmodel}, defining any covariates governing the hidden Markov outcome models. Unlike in the \code{msm} function, this should also define the values of the covariate effects. Each element of the list is a named vector of the initial values for each set of covariates for that state. For example, for a three-state hidden Markov model with two, one and no covariates on the state 1, 2 and 3 outcome models respectively, \code{ hcovariates = list (c(acute=-8, age=0), c(acute=-8), NULL) } } \item{censor.states}{Set of simulated states which should be replaced by a censoring indicator at censoring times. By default this is all transient states (representing alive, with unknown state).} \item{drop.absorb}{Drop repeated observations in the absorbing state, retaining only one.} } \value{A data frame with columns, \item{subject}{Subject identification indicators} \item{time}{Observation times} \item{state}{Simulated (true) state at the corresponding time} \item{obs}{Observed outcome at the corresponding time, if \code{ematrix} or \code{hmodel} was supplied} \item{keep}{Row numbers of the original data. Useful when \code{drop.absorb=TRUE}, to show which rows were not dropped} plus any supplied covariates. } \details{ \code{\link{sim.msm}} is called repeatedly to produce a simulated trajectory for each individual. The state at each specified observation time is then taken to produce a new column \code{state}. The effect of time-dependent covariates on the transition intensity matrix for an individual is determined by assuming that the covariate is a step function which remains constant in between the individual's observation times. If the subject enters an absorbing state, then only the first observation in that state is kept in the data frame. Rows corresponding to future observations are deleted. The entry times into states given in \code{death} are assumed to be known exactly. } \seealso{ \code{\link{sim.msm}} } \examples{ ### Simulate 100 individuals with common observation times sim.df <- data.frame(subject = rep(1:100, rep(13,100)), time = rep(seq(0, 24, 2), 100)) qmatrix <- rbind(c(-0.11, 0.1, 0.01 ), c(0.05, -0.15, 0.1 ), c(0.02, 0.07, -0.09)) simmulti.msm(sim.df, qmatrix) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{datagen} msm/man/pexp.Rd0000644000176200001440000000573313051600620013065 0ustar liggesusers\name{pexp} \alias{pexp} \alias{dpexp} \alias{ppexp} \alias{qpexp} \alias{rpexp} \title{Exponential distribution with piecewise-constant rate} \description{ Density, distribution function, quantile function and random generation for a generalisation of the exponential distribution, in which the rate changes at a series of times. } \usage{ dpexp(x, rate=1, t=0, log = FALSE) ppexp(q, rate=1, t=0, lower.tail = TRUE, log.p = FALSE) qpexp(p, rate=1, t=0, lower.tail = TRUE, log.p = FALSE) rpexp(n, rate=1, t=0) } \arguments{ \item{x,q}{vector of quantiles.} \item{p}{vector of probabilities.} \item{n}{number of observations. If \code{length(n) > 1}, the length is taken to be the number required.} \item{rate}{vector of rates.} \item{t}{vector of the same length as \code{rate}, giving the times at which the rate changes. The first element of \code{t} should be 0, and \code{t} should be in increasing order.} \item{log, log.p}{logical; if TRUE, probabilities p are given as log(p), or log density is returned.} \item{lower.tail}{logical; if TRUE (default), probabilities are P[X <= x], otherwise, P[X > x].} } \value{ \code{dpexp} gives the density, \code{ppexp} gives the distribution function, \code{qpexp} gives the quantile function, and \code{rpexp} generates random deviates. } \details{ Consider the exponential distribution with rates \eqn{r_1, \ldots, r_n}{r1,\dots, rn} changing at times \eqn{t_1, \ldots, t_n}{t1, \dots, tn}, with \eqn{t_1 = 0}{t1 = 0}. Suppose \eqn{t_k}{tk} is the maximum \eqn{t_i}{ti} such that \eqn{t_i < x}{ti < x}. The density of this distribution at \eqn{x > 0} is \eqn{f(x)} for \eqn{k = 1}, and \deqn{\prod_{i=1}^k (1 - F(t_{i} - t_{i-1}, r_i)) f(x - t_{k}, r_{k})}{\prod{i=1 \dots k} (1 - F(ti - t{i-1}, r{i-1})) f(x - tk, rk)} for k > 1. where \eqn{F()} and \eqn{f()} are the distribution and density functions of the standard exponential distribution. If \code{rate} is of length 1, this is just the standard exponential distribution. Therefore, for example, \code{dpexp(x)}, with no other arguments, is simply equivalent to \code{dexp(x)}. Only \code{rpexp} is used in the \code{msm} package, to simulate from Markov processes with piecewise-constant intensities depending on time-dependent covariates. These functions are merely provided for completion, and are not optimized for numerical stability or speed. } \seealso{ \code{\link{dexp}}, \code{\link{sim.msm}}. } \examples{ x <- seq(0.1, 50, by=0.1) rate <- c(0.1, 0.2, 0.05, 0.3) t <- c(0, 10, 20, 30) ## standard exponential distribution plot(x, dexp(x, 0.1), type="l") ## distribution with piecewise constant rate lines(x, dpexp(x, rate, t), type="l", lty=2) ## standard exponential distribution plot(x, pexp(x, 0.1), type="l") ## distribution with piecewise constant rate lines(x, ppexp(x, rate, t), type="l", lty=2) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{distribution} msm/man/coef.msm.Rd0000644000176200001440000000240413051600620013610 0ustar liggesusers\name{coef.msm} \alias{coef.msm} \title{Extract model coefficients} \description{ Extract the estimated log transition intensities and the corresponding linear effects of each covariate. } \usage{ \method{coef}{msm}(object, \dots) } \arguments{ \item{object}{A fitted multi-state model object, as returned by \code{\link{msm}}.} \item{...}{(unused) further arguments passed to or from other methods.} } \value{ If there is no misclassification, \code{coef.msm} returns a list of matrices. The first component, labelled \code{logbaseline}, is a matrix containing the estimated transition intensities on the log scale with any covariates fixed at their means in the data. Each remaining component is a matrix giving the linear effects of the labelled covariate on the matrix of log intensities. \cr For misclassification models, \code{coef.msm} returns a list of lists. The first component, \code{Qmatrices}, is a list of matrices as described in the previous paragraph. The additional component \code{Ematrices} is a list of similar format containing the logit-misclassification probabilities and any estimated covariate effects. } \seealso{ \code{\link{msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/qcmodel.object.Rd0000644000176200001440000000365513051600620015003 0ustar liggesusers\name{qcmodel.object} \alias{qcmodel.object} \title{Developer documentation: model for covariates on transition intensities} \description{A list representing the model for covariates on transition intensities} \value{ \item{npars}{Number of covariate effect parameters. This is defined as the number of covariates on intensities (with factors expanded as contrasts) multiplied by the number of allowed transitions in the model. Note if \code{\link{msm}} was called with \code{covariates} set to a list of different covariates for different intensities, then this will include covariate effects that are implicitly defined as zero by this list. The information in \code{\link[=paramdata.object]{paramdata}} objects can be used to identify wich ones are fixed at zero. This also includes any \code{timeperiod} covariates in a time-inhomogeneous model defined by the \code{pci} option to \code{\link{msm}}. } \item{ndpars}{Number of distinct covariate effect parameters, as \code{npars}, but after any equality constraints have been applied.} \item{ncovs}{Number of covariates on intensities, with factors expanded as contrasts.} \item{constr}{List of equality constraints on these covariate effects, as supplied in the \code{constraint} argument to \code{\link{msm}}.} \item{covlabels}{Names / labels of these covariates in the model matrix (see \code{\link{model.matrix.msm}}).} \item{inits}{Initial values for these covariate effects, as a vector formed from the \code{covinits} list supplied to \code{\link{msm}}.} \item{covmeans}{Means of these covariates in the data (excluding data not required to fit the model, such as observations with missing data in other elements or subjects' last observations). This includes means of 0/1 factor contrasts as well as continuous covariates (for historic reasons, which may not be sensible).} } \seealso{ \code{\link{msm.object}}. } msm/man/hmodel.object.Rd0000644000176200001440000001053513051600620014622 0ustar liggesusers\name{hmodel.object} \alias{hmodel.object} \title{Developer documentation: hidden Markov model structure object} \description{ A list giving information about the models for the outcome data conditionally on the states of a hidden Markov model. Used in internal computations, and returned in a fitted \code{\link{msm}} model object. } \value{ \item{hidden}{\code{TRUE} for hidden Markov models, \code{FALSE} otherwise.} \item{nstates}{Number of states, the same as \code{qmodel$nstates}.} \item{fitted}{\code{TRUE} if the parameter values in \code{pars} are the maximum likelihood estimates, \code{FALSE} if they are the initial values.} \item{models}{The outcome distribution for each hidden state. A vector of length \code{nstates} whose \eqn{r}th entry is the index of the state \eqn{r} outcome distributions in the vector of supported distributions. The vector of supported distributions is given in full by \code{msm:::.msm.HMODELS}: the first few are 1 for categorical outcome, 2 for identity, 3 for uniform and 4 for normal. } \item{labels}{String identifying each distribution in \code{models}.} \item{npars}{Vector of length \code{nstates} giving the number of parameters in each outcome distribution, excluding covariate effects.} \item{nipars}{Number of initial state occupancy probabilities being estimated. This is zero if \code{est.initprobs=FALSE}, otherwise equal to the number of states.} \item{totpars}{Total number of parameters, equal to \code{sum(npars)}. } \item{pars}{A vector of length \code{totpars}, made from concatenating a list of length \code{nstates} whose \eqn{r}th component is vector of the parameters for the state \eqn{r} outcome distribution. } \item{plabs}{List with the names of the parameters in \code{pars}.} \item{parstate}{A vector of length \code{totpars}, whose \eqn{i}th element is the state corresponding to the \eqn{i}th parameter.} \item{firstpar}{A vector of length \code{nstates} giving the index in \code{pars} of the first parameter for each state.} \item{locpars}{Index in \code{pars} of parameters which can have covariates on them. } \item{initprobs}{Initial state occupancy probabilities, as supplied to \code{\link{msm}} (initial values before estimation, if \code{est.initprobs=TRUE}.)} \item{est.initprobs}{Are initial state occupancy probabilities estimated (\code{TRUE} or \code{FALSE}), as supplied in the \code{est.initprobs} argument of \code{\link{msm}}.} \item{ncovs}{Number of covariate effects per parameter in \code{pars}, with, e.g. factor contrasts expanded.} \item{coveffect}{Vector of covariate effects, of length \code{sum(ncovs)}.} \item{covlabels}{Labels of these effects.} \item{coveffstate}{Vector indicating state corresponding to each element of \code{coveffect}.} \item{ncoveffs}{Number of covariate effects on HMM outcomes, equal to \code{sum(ncovs)}.} \item{nicovs}{Vector of length \code{nstates-1} giving the number of covariate effects on each initial state occupancy probability (log relative to the baseline probability).} \item{icoveffect}{Vector of length \code{sum(nicovs)} giving covariate effects on initial state occupancy probabilities.} \item{nicoveffs}{Number of covariate effects on initial state occupancy probabilities, equal to \code{sum(nicovs)}.} \item{constr}{Constraints on (baseline) hidden Markov model outcome parameters, as supplied in the \code{hconstraint} argument of \code{\link{msm}}, excluding covariate effects, converted to a vector and mapped to the set 1,2,3,\ldots if necessary.} \item{covconstr}{Vector of constraints on covariate effects in hidden Markov outcome models, as supplied in the \code{hconstraint} argument of \code{\link{msm}}, excluding baseline parameters, converted to a vector and mapped to the set 1,2,3,\ldots if necessary.} \item{ranges}{Matrix of range restrictions for HMM parameters, including those given to the \code{hranges} argument to \code{\link{msm}}.} \item{foundse}{\code{TRUE} if standard errors are available for the estimates.} \item{initpmat}{Matrix of initial state occupancy probabilities with one row for each subject (estimated if \code{est.initprobs=TRUE}).} \item{ci}{Confidence intervals for baseline HMM outcome parameters.} \item{covci}{Confidence intervals for covariate effects in HMM outcome models.} } \seealso{ \code{\link{msm.object}},\code{\link{qmodel.object}}, \code{\link{emodel.object}}. } msm/man/ppass.msm.Rd0000644000176200001440000001157713051600620014035 0ustar liggesusers\name{ppass.msm} \alias{ppass.msm} \title{Passage probabilities} \description{ Probabilities of having visited each state by a particular time in a continuous time Markov model. } \usage{ ppass.msm(x=NULL, qmatrix=NULL, tot, start="all", covariates="mean", piecewise.times=NULL, piecewise.covariates=NULL, ci=c("none","normal","bootstrap"), cl=0.95, B=1000, cores=NULL, \dots) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}. } \item{qmatrix}{Instead of \code{x}, you can simply supply a transition intensity matrix in \code{qmatrix}.} \item{tot}{Finite time to forecast the passage probabilites for.} \item{start}{Starting state (integer). By default (\code{start="all"}), this will return a matrix one row for each starting state. Alternatively, this can be used to obtain passage probabilities from a \emph{set} of states, rather than single states. To achieve this, \code{state} is set to a vector of weights, with length equal to the number of states in the model. These weights should be proportional to the probability of starting in each of the states in the desired set, so that weights of zero are supplied for other states. The function will calculate the weighted average of the passage probabilities from each of the corresponding states. } \item{covariates}{Covariate values defining the intensity matrix for the fitted model \code{x}, as supplied to \code{\link{qmatrix.msm}}.} \item{piecewise.times}{Currently ignored: not implemented for time-inhomogeneous models.} \item{piecewise.covariates}{Currently ignored: not implemented for time-inhomogeneous models.} \item{ci}{If \code{"normal"}, then calculate a confidence interval by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}. If \code{"none"} (the default) then no confidence interval is calculated.} \item{cl}{Width of the symmetric confidence interval, relative to 1.} \item{B}{Number of bootstrap replicates.} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} \item{...}{Arguments to pass to \code{\link{MatrixExp}}.} } \value{ A matrix whose \eqn{r, s} entry is the probability of having visited state \eqn{s} at least once before time \eqn{t}, given the state at time \eqn{0} is \eqn{r}. The diagonal entries should all be 1. } \details{ The passage probabilities to state \eqn{s} are computed by setting the \eqn{s}th row of the transition intensity matrix \eqn{Q} to zero, giving an intensity matrix \eqn{Q*} for a simplified model structure where state \eqn{s} is absorbing. The probabilities of passage are then equivalent to row \eqn{s} of the transition probability matrix \eqn{Exp(tQ*)} under this simplified model for \eqn{t=}\code{tot}. Note this is different from the probability of occupying each state at exactly time \eqn{t}, given by \code{\link{pmatrix.msm}}. The passage probability allows for the possibility of having visited the state before \eqn{t}, but then occupying a different state at \eqn{t}. The mean of the passage distribution is the expected first passage time, \code{\link{efpt.msm}}. This function currently only handles time-homogeneous Markov models. For time-inhomogeneous models the covariates are held constant at the value supplied, by default the column means of the design matrix over all observations. } \references{ Norris, J. R. (1997) Markov Chains. Cambridge University Press. } \seealso{ \code{\link{efpt.msm}}, \code{\link{totlos.msm}}, \code{\link{boot.msm}}. } \examples{ Q <- rbind(c(-0.5, 0.25, 0, 0.25), c(0.166, -0.498, 0.166, 0.166), c(0, 0.25, -0.5, 0.25), c(0, 0, 0, 0)) ## ppass[1,2](t) converges to 0.5 with t, since given in state 1, the ## probability of going to the absorbing state 4 before visiting state ## 2 is 0.5, and the chance of still being in state 1 at t decreases. ppass.msm(qmatrix=Q, tot=2) ppass.msm(qmatrix=Q, tot=20) ppass.msm(qmatrix=Q, tot=100) Q <- Q[1:3,1:3]; diag(Q) <- 0; diag(Q) <- -rowSums(Q) ## Probability of about 1/2 of visiting state 3 by time 10.5, the ## median first passage time ppass.msm(qmatrix=Q, tot=10.5) ## Mean first passage time from state 2 to state 3 is 10.02: similar ## to the median efpt.msm(qmatrix=Q, tostate=3) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/transient.msm.Rd0000644000176200001440000000126313051600620014705 0ustar liggesusers\name{transient.msm} \alias{transient.msm} \alias{absorbing.msm} \title{Transient and absorbing states} \description{ Returns the transient and absorbing states of either a fitted model or a transition intensity matrix. } \usage{ transient.msm(x=NULL, qmatrix=NULL) absorbing.msm(x=NULL, qmatrix=NULL) } \arguments{ \item{x}{A fitted multi-state model as returned by \code{\link{msm}}.} \item{qmatrix}{A transition intensity matrix. The diagonal is ignored and taken to be minus the sum of the rest of the row.} } \value{ A vector of the ordinal indices of the transient or absorbing states. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/recreate.olddata.Rd0000644000176200001440000000170313051600620015303 0ustar liggesusers\name{recreate.olddata} \alias{recreate.olddata} \title{Convert data stored in msm object to old format} \description{ Converts the \code{data} element of msm objects to the old format. } \usage{ recreate.olddata(x) } \arguments{ \item{x}{Object returned by the \code{\link{msm}} function, representing a fitted multi-state model.} } \value{ A list of vectors and matrices in the undocumented ad-hoc format used for the \code{data} component of \code{msm} objects in \pkg{msm} versions 1.3.1 and earlier. } \details{ This is just provided for convenience and to illustrate the changes. It is not guaranteed to be complete, and is liable to be withdrawn. Users who were relying on the previous undocumented format are advised to upgrade their code to use the new format, which uses model frames and model design matrices in the standard format used in version 1.4, based on \code{\link{model.frame}} and \code{\link{model.matrix}}. } msm/man/pearson.msm.Rd0000644000176200001440000003101013051600620014336 0ustar liggesusers\name{pearson.msm} \alias{pearson.msm} \title{Pearson-type goodness-of-fit test} \description{Pearson-type goodness-of-fit test for multi-state models fitted to panel-observed data. } \usage{ pearson.msm(x, transitions=NULL, timegroups=3, intervalgroups=3, covgroups=3, groups=NULL, boot=FALSE, B=500, next.obstime=NULL, N=100, indep.cens=TRUE, maxtimes=NULL, pval=TRUE) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}.} \item{transitions}{This should be an integer vector indicating which interval transitions should be grouped together in the contingency table. Its length should be the number of allowed interval transitions, excluding transitions from absorbing states to absorbing states. The allowed interval transitions are the set of pairs of states \eqn{(a,b)} for which it is possible to observe \eqn{a} at one time and \eqn{b} at any later time. For example, in a "well-disease-death" model with allowed \emph{instantaneous} 1-2, 2-3 transitions, there are 5 allowed \emph{interval} transitions. In numerical order, these are 1-1, 1-2, 1-3, 2-2 and 2-3, excluding absorbing-absorbing transitions. Then, to group transitions 1-1,1-2 together, and transitions 2-2,2-3 together, specify \code{transitions = c(1,1,2,3,3)}. Only transitions from the same state may be grouped. By default, each interval transition forms a separate group. } \item{timegroups}{Number of groups based on quantiles of the time since the start of the process.} \item{intervalgroups}{Number of groups based on quantiles of the time interval between observations, within time groups} \item{covgroups}{Number of groups based on quantiles of \eqn{\sum_r q_{irr}}{sum_r q_{irr}}, where \eqn{q_{irr}} are the diagonal entries of the transition intensity matrix for the \emph{i}th transition. These are a function of the covariate effects and the covariate values at the \emph{i}th transition: \eqn{q_{irr}} is minus the sum of the off-diagonal entries \eqn{q_{rs}^{(0)} exp (\beta_{rs}^T z_i)} on the \emph{r}th row. Thus \code{covgroups} summarises the impact of covariates at each observation, by calculating the overall rate of progression through states at that observation. For time-inhomogeneous models specified using the \code{pci} argument to \code{\link{msm}}, if the only covariate is the time period, \code{covgroups} is set to 1, since \code{timegroups} ensures that transitions are grouped by time. } \item{groups}{A vector of arbitrary groups in which to categorise each transition. This can be an integer vector or a factor. This can be used to diagnose specific areas of poor fit. For example, the contingency table might be grouped by arbitrary combinations of covariates to detect types of individual for whom the model fits poorly. The length of \code{groups} should be \code{x$data$n}, the number of observations used in the model fit, which is the number of observations in the original dataset with any missing values excluded. The value of \code{groups} at observation \eqn{i} is used to categorise the transition which \emph{ends} at observation i. Values of \code{groups} at the first observation for each subject are ignored. } \item{boot}{Estimate an "exact" p-value using a parametric bootstrap. All objects used in the original call to \code{\link{msm}} which produced \code{x}, such as the \code{qmatrix}, should be in the working environment, or else an \dQuote{object not found} error will be given. This enables the original model to be refitted to the replicate datasets. Note that \code{groups} cannot be used with bootstrapping, as the simulated observations will not be in the same categories as the original observations. } \item{B}{Number of bootstrap replicates.} \item{next.obstime}{This is a vector of length \code{x$data$n} (the number of observations used in the model fit) giving the time to the next \emph{scheduled} observation following each time point. This is only used when times to death are known exactly. For individuals who died (entered an absorbing state) before the next scheduled observation, and the time of death is known exactly, \code{next.obstime} would be \emph{greater} than the observed death time. If the individual did not die, and a scheduled observation did follow that time point, \code{next.obstime} should just be the same as the time to that observation. \code{next.obstime} is used to determine a grouping of the time interval between observations, which should be based on scheduled observations. If exact times to death were used in the grouping, then shorter intervals would contain excess deaths, and the goodness-of-fit statistic would be biased. If \code{next.obstime} is unknown, it is multiply-imputed using a product-limit estimate based on the intervals to observations other than deaths. The resulting tables of transitions are averaged over these imputations. This may be slow. } \item{N}{Number of imputations for the estimation of the distribution of the next scheduled observation time, when there are exact death times.} \item{indep.cens}{If \code{TRUE}, then times to censoring are included in the estimation of the distribution to the next scheduled observation time. If \code{FALSE}, times to censoring are assumed to be systematically different from other observation times. } \item{maxtimes}{A vector of length \code{x$data$n}, or a common scalar, giving an upper bound for the next scheduled observation time. Used in the multiple imputation when times to death are known exactly. If a value greater than \code{maxtimes} is simulated, then the next scheduled observation is taken as censored. This should be supplied, if known. If not supplied, this is taken to be the maximum interval occurring in the data, plus one time unit. For observations which are not exact death times, this should be the time since the previous observation. } \item{pval}{Calculate a p-value using the improved approximation of Titman (2009). This is optional since it is not needed during bootstrapping, and it is computationally non-trivial. Only available currently for non-hidden Markov models for panel data without exact death times. Also not available for models with censoring, including time-homogeneous models fitted with the \code{pci} option to \code{\link{msm}}. } } \value{ A list whose first two elements are contingency tables of observed transitions \eqn{O} and expected transitions \eqn{E}, respectively, for each combination of groups. The third element is a table of the deviances \eqn{(O - E)^2 / E} multiplied by the sign of \eqn{O - E}. If the expected number of transitions is zero then the deviance is zero. Entries in the third matrix will be bigger in magnitude for groups for which the model fits poorly. \cr \item{\code{"test"}}{the fourth element of the list, is a data frame with one row containing the Pearson-type goodness-of-fit test statistic \code{stat}. The test statistic is the sum of the deviances. For panel-observed data without exact death times, misclassification or censored observations, \code{p} is the p-value for the test statistic calculated using the improved approximation of Titman (2009). For these models, for comparison with older versions of the package, \code{test} also presents \code{p.lower} and \code{p.upper}, which are theoretical lower and upper limits for the p-value of the test statistic, based on \ifelse{latex}{\eqn{\chi^2}}{chi-squared} distributions with \code{df.lower} and \code{df.upper} degrees of freedom, respectively. \code{df.upper} is the number of independent cells in the contingency table, and \code{df.lower} is \code{df.upper} minus the number of estimated parameters in the model.} \item{\code{"intervalq"}}{(not printed by default) contains the definition of the grouping of the intervals between observations. These groups are defined by quantiles within the groups corresponding to the time since the start of the process.} \item{\code{"sim"}}{If there are exact death times, this contains simulations of the contingency tables and test statistics for each imputation of the next scheduled sampling time. These are averaged over to produce the presented tables and test statistic. This element is not printed by default. With exact death times, the null variance of the test statistic (formed by taking mean of simulated test statistics) is less than twice the mean (Titman, 2008), and the null distribution is not \ifelse{latex}{\eqn{\chi^2}}{chi-squared}. In this case, \code{p.upper} is an upper limit for the true asymptotic p-value, but \code{p.lower} is not a lower limit, and is not presented.} \item{\code{"boot"}}{If the bootstrap has been used, the element will contain the bootstrap replicates of the test statistics (not printed by default).} \item{\code{"lambda"}}{If the Titman (2009) p-value has been calculated, this contains the weights defining the null distribution of the test statistic as a weighted sum of \ifelse{latex}{\eqn{\chi^2_1}}{chi-squared(1)} random variables (not printed by default).} } \details{ This method (Aguirre-Hernandez and Farewell, 2002) is intended for data which represent observations of the process at arbitrary times ("snapshots", or "panel-observed" data). For data which represent the exact transition times of the process, \code{\link{prevalence.msm}} can be used to assess fit, though without a formal test. When times of death are known exactly, states are misclassified, or an individual's final observation is a censored state, the modification by Titman and Sharples (2008) is used. The only form of censoring supported is a state at the end of an individual's series which represents an unknown transient state (i.e. the individual is only known to be alive at this time). Other types of censoring are omitted from the data before performing the test. See the references for further details of the methods. The method used for censored states is a modification of the method in the appendix to Titman and Sharples (2008), described at \url{http://www.mrc-bsu.cam.ac.uk/wp-content/uploads/robustcensoring.pdf} (Titman, 2007). Groupings of the time since initiation, the time interval and the impact of covariates are based on equally-spaced quantiles. The number of groups should be chosen that there are not many cells with small expected numbers of transitions, since the deviance statistic will be unstable for sparse contingency tables. Ideally, the expected numbers of transitions in each cell of the table should be no less than about 5. Conversely, the power of the test is reduced if there are too few groups. Therefore, some sensitivity analysis of the test results to the grouping is advisable. Saved model objects fitted with previous versions of R (versions less than 1.2) will need to be refitted under the current R for use with \code{pearson.msm}. } \references{ Aguirre-Hernandez, R. and Farewell, V. (2002) A Pearson-type goodness-of-fit test for stationary and time-continuous Markov regression models. \emph{Statistics in Medicine} 21:1899-1911. Titman, A. and Sharples, L. (2008) A general goodness-of-fit test for Markov and hidden Markov models. \emph{Statistics in Medicine} 27(12):2177-2195 Titman, A. (2009) Computation of the asymptotic null distribution of goodness-of-fit tests for multi-state models. \emph{Lifetime Data Analysis} 15(4):519-533. Titman, A. (2008) Model diagnostics in multi-state models of biological systems. PhD thesis, University of Cambridge. } \seealso{ \code{\link{msm}}, \code{\link{prevalence.msm}}, \code{\link{scoreresid.msm}}, } \examples{ psor.q <- rbind(c(0,0.1,0,0),c(0,0,0.1,0),c(0,0,0,0.1),c(0,0,0,0)) psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2))) pearson.msm(psor.msm, timegroups=2, intervalgroups=2, covgroups=2) # More 1-2, 1-3 and 1-4 observations than expected in shorter time # intervals - the model fits poorly. # A random effects model might accommodate such fast progressors. } \author{ Andrew Titman \email{a.titman@lancaster.ac.uk}, Chris Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk} } \keyword{models} msm/man/ecmodel.object.Rd0000644000176200001440000000273213051600620014762 0ustar liggesusers\name{ecmodel.object} \alias{ecmodel.object} \title{Developer documentation: model for covariates on misclassification probabilities} \description{A list representing the model for covariates on misclassification probabilities.} \value{ \item{npars}{Number of covariate effect parameters. This is defined as the number of covariates on misclassification (with factors expanded as contrasts) multiplied by the number of allowed misclassifications in the model. } \item{ndpars}{Number of distinct covariate effect parameters, as \code{npars}, but after any equality constraints have been applied.} \item{ncovs}{Number of covariates on misclassification, with factors expanded as contrasts.} \item{constr}{List of equality constraints on these covariate effects, as supplied in the \code{miscconstraint} argument to \code{\link{msm}}.} \item{covlabels}{Names / labels of these covariates in the model matrix (see \code{\link{model.matrix.msm}}).} \item{inits}{Initial values for these covariate effects, as a vector formed from the \code{misccovinits} list supplied to \code{\link{msm}}.} \item{covmeans}{Means of these covariates in the data (excluding data not required to fit the model, such as observations with missing data in other elements or subjects' last observations). This includes means of 0/1 factor contrasts as well as continuous covariates (for historic reasons, which may not be sensible).} } \seealso{ \code{\link{msm.object}}. } msm/man/msm.Rd0000644000176200001440000013566314042526712012725 0ustar liggesusers\name{msm} \title{Multi-state Markov and hidden Markov models in continuous time} \alias{msm} \description{ Fit a continuous-time Markov or hidden Markov multi-state model by maximum likelihood. Observations of the process can be made at arbitrary times, or the exact times of transition between states can be known. Covariates can be fitted to the Markov chain transition intensities or to the hidden Markov observation process. } \usage{ msm ( formula, subject=NULL, data = list(), qmatrix, gen.inits = FALSE, ematrix=NULL, hmodel=NULL, obstype=NULL, obstrue=NULL, covariates = NULL, covinits = NULL, constraint = NULL, misccovariates = NULL, misccovinits = NULL, miscconstraint = NULL, hcovariates = NULL, hcovinits = NULL, hconstraint = NULL, hranges=NULL, qconstraint=NULL, econstraint=NULL, initprobs = NULL, est.initprobs=FALSE, initcovariates = NULL, initcovinits = NULL, deathexact = NULL, death=NULL, exacttimes = FALSE, censor=NULL, censor.states=NULL, pci=NULL, phase.states=NULL, phase.inits=NULL, cl = 0.95, fixedpars = NULL, center=TRUE, opt.method="optim", hessian=NULL, use.deriv=TRUE, use.expm=TRUE, analyticp=TRUE, na.action=na.omit, ... ) } \arguments{ \item{formula}{ A formula giving the vectors containing the observed states and the corresponding observation times. For example, \code{state ~ time} Observed states should be numeric variables in the set \code{1, \dots, n}, where \code{n} is the number of states. Factors are allowed only if their levels are called \code{"1", \dots, "n"}. The times can indicate different types of observation scheme, so be careful to choose the correct \code{obstype}. For hidden Markov models, \code{state} refers to the outcome variable, which need not be a discrete state. It may also be a matrix, giving multiple observations at each time (see \code{\link{hmmMV}}). } \item{subject}{Vector of subject identification numbers for the data specified by \code{formula}. If missing, then all observations are assumed to be on the same subject. These must be sorted so that all observations on the same subject are adjacent.} \item{data}{Optional data frame in which to interpret the variables supplied in \code{formula}, \code{subject}, \code{covariates}, \code{misccovariates}, \code{hcovariates}, \code{obstype} and \code{obstrue}.} \item{qmatrix}{Matrix which indicates the allowed transitions in the continuous-time Markov chain, and optionally also the initial values of those transitions. If an instantaneous transition is not allowed from state \eqn{r} to state \eqn{s}, then \code{qmatrix} should have \eqn{(r,s)} entry 0, otherwise it should be non-zero. If supplying initial values yourself, then the non-zero entries should be those values. If using \code{gen.inits=TRUE} then the non-zero entries can be anything you like (conventionally 1). Any diagonal entry of \code{qmatrix} is ignored, as it is constrained to be equal to minus the sum of the rest of the row. For example,\cr \code{ rbind( c( 0, 0.1, 0.01 ), c( 0.1, 0, 0.2 ), c( 0, 0, 0 ) ) }\cr represents a 'health - disease - death' model, with initial transition intensities 0.1 from health to disease, 0.01 from health to death, 0.1 from disease to health, and 0.2 from disease to death. If the states represent ordered levels of severity of a disease, then this matrix should usually only allow transitions between adjacent states. For example, if someone was observed in state 1 ("mild") at their first observation, followed by state 3 ("severe") at their second observation, they are assumed to have passed through state 2 ("moderate") in between, and the 1,3 entry of \code{qmatrix} should be zero. The initial intensities given here are with any covariates set to their means in the data (or set to zero, if \code{center = FALSE}). If any intensities are constrained to be equal using \code{qconstraint}, then the initial value is taken from the first of these (reading across rows). } \item{gen.inits}{If \code{TRUE}, then initial values for the transition intensities are generated automatically using the method in \code{\link{crudeinits.msm}}. The non-zero entries of the supplied \code{qmatrix} are assumed to indicate the allowed transitions of the model. This is not available for hidden Markov models, including models with misclassified states.} \item{ematrix}{ If misclassification between states is to be modelled, this should be a matrix of initial values for the misclassification probabilities. The rows represent underlying states, and the columns represent observed states. If an observation of state \eqn{s} is not possible when the subject occupies underlying state \eqn{r}, then \code{ematrix} should have \eqn{(r,s)} entry 0. Otherwise \code{ematrix} should have \eqn{(r,s)} entry corresponding to the probability of observing \eqn{s} conditionally on occupying true state \eqn{r}. The diagonal of \code{ematrix} is ignored, as rows are constrained to sum to 1. For example, \cr \code{ rbind( c( 0, 0.1, 0 ), c( 0.1, 0, 0.1 ), c( 0, 0.1, 0 ) ) }\cr represents a model in which misclassifications are only permitted between adjacent states. If any probabilities are constrained to be equal using \code{econstraint}, then the initial value is taken from the first of these (reading across rows). For an alternative way of specifying misclassification models, see \code{hmodel}. } \item{hmodel}{ Specification of the hidden Markov model (HMM). This should be a list of return values from HMM constructor functions. Each element of the list corresponds to the outcome model conditionally on the corresponding underlying state. Univariate constructors are described in the\code{\link{hmm-dists}} help page. These may also be grouped together to specify a multivariate HMM with a set of conditionally independent univariate outcomes at each time, as described in \code{\link{hmmMV}}. For example, consider a three-state hidden Markov model. Suppose the observations in underlying state 1 are generated from a Normal distribution with mean 100 and standard deviation 16, while observations in underlying state 2 are Normal with mean 54 and standard deviation 18. Observations in state 3, representing death, are exactly observed, and coded as 999 in the data. This model is specified as \code{hmodel = list(hmmNorm(mean=100, sd=16), hmmNorm(mean=54, sd=18), hmmIdent(999))} The mean and standard deviation parameters are estimated starting from these initial values. If multiple parameters are constrained to be equal using \code{hconstraint}, then the initial value is taken from the value given on the first occasion that parameter appears in \code{hmodel}. See the \code{\link{hmm-dists}} help page for details of the constructor functions for each univariate distribution. A misclassification model, that is, a hidden Markov model where the outcomes are misclassified observations of the underlying states, can either be specified using a list of \code{\link{hmmCat}} or \code{\link{hmmIdent}} objects, or by using an \code{ematrix}. For example, \cr \code{ ematrix = rbind( c( 0, 0.1, 0, 0 ), c( 0.1, 0, 0.1, 0 ), c( 0, 0.1, 0, 0), c( 0, 0, 0, 0) ) }\cr is equivalent to \cr \code{hmodel = list( hmmCat(prob=c(0.9, 0.1, 0, 0)), hmmCat(prob=c(0.1, 0.8, 0.1, 0)), hmmCat(prob=c(0, 0.1, 0.9, 0)), hmmIdent()) }\cr } \item{obstype}{A vector specifying the observation scheme for each row of the data. This can be included in the data frame \code{data} along with the state, time, subject IDs and covariates. Its elements should be either 1, 2 or 3, meaning as follows: \describe{ \item{1}{An observation of the process at an arbitrary time (a "snapshot" of the process, or "panel-observed" data). The states are unknown between observation times.} \item{2}{An exact transition time, with the state at the previous observation retained until the current observation. An observation may represent a transition to a different state or a repeated observation of the same state (e.g. at the end of follow-up). Note that if all transition times are known, more flexible models could be fitted with packages other than \pkg{msm} - see the note under \code{exacttimes}. Note also that if the previous state was censored using \code{censor}, for example known only to be state 1 or state 2, then \code{obstype} 2 means that either state 1 is retained or state 2 is retained until the current observation - this does not allow for a change of state in the middle of the observation interval. } \item{3}{An exact transition time, but the state at the instant before entering this state is unknown. A common example is death times in studies of chronic diseases.} } If \code{obstype} is not specified, this defaults to all 1. If \code{obstype} is a single number, all observations are assumed to be of this type. The obstype value for the first observation from each subject is not used. This is a generalisation of the \code{deathexact} and \code{exacttimes} arguments to allow different schemes per observation. \code{obstype} overrides both \code{deathexact} and \code{exacttimes}. \code{exacttimes=TRUE} specifies that all observations are of obstype 2. \code{deathexact = death.states} specifies that all observations of \code{death.states} are of type 3. \code{deathexact = TRUE} specifies that all observations in the final absorbing state are of type 3. } \item{obstrue}{In misclassification models specified with \code{ematrix}, \code{obstrue} is a vector of logicals (\code{TRUE} or \code{FALSE}) or numerics (1 or 0) specifying which observations (\code{TRUE}, 1) are observations of the underlying state without error, and which (\code{FALSE}, 0) are realisations of a hidden Markov model. In HMMs specified with \code{hmodel}, where the hidden state is known at some times, if \code{obstrue} is supplied it is assumed to contain the actual true state data. Elements of \code{obstrue} at times when the hidden state is unknown are set to \code{NA}. This allows the information from HMM outcomes generated conditionally on the known state to be included in the model, thus improving the estimation of the HMM outcome distributions. In HMMs where there are also censored states, \code{obstrue} should be set to 1 for observed states which are \emph{censored} but not \emph{misclassified}. } \item{covariates}{A formula or a list of formulae representing the covariates on the transition intensities via a log-linear model. If a single formula is supplied, like \code{covariates = ~ age + sex + treatment} then these covariates are assumed to apply to all intensities. If a named list is supplied, then this defines a potentially different model for each named intensity. For example, \code{covariates = list("1-2" = ~ age, "2-3" = ~ age + treatment)} specifies an age effect on the state 1 - state 2 transition, additive age and treatment effects on the state 2 - state 3 transition, but no covariates on any other transitions that are allowed by the \code{qmatrix}. If covariates are time dependent, they are assumed to be constant in between the times they are observed, and the transition probability between a pair of times \eqn{(t1, t2)} is assumed to depend on the covariate value at \eqn{t1}. } \item{covinits}{Initial values for log-linear effects of covariates on the transition intensities. This should be a named list with each element corresponding to a covariate. A single element contains the initial values for that covariate on each transition intensity, reading across the rows in order. For a pair of effects constrained to be equal, the initial value for the first of the two effects is used. For example, for a model with the above \code{qmatrix} and age and sex covariates, the following initialises all covariate effects to zero apart from the age effect on the 2-1 transition, and the sex effect on the 1-3 transition. \code{ covinits = list(sex=c(0, 0, 0.1, 0), age=c(0, 0.1, 0, 0))} For factor covariates, name each level by concatenating the name of the covariate with the level name, quoting if necessary. For example, for a covariate \code{agegroup} with three levels \code{0-15, 15-60, 60-}, use something like \code{ covinits = list("agegroup15-60"=c(0, 0.1, 0, 0), "agegroup60-"=c(0.1, 0.1, 0, 0))} If not specified or wrongly specified, initial values are assumed to be zero. } \item{constraint}{ A list of one numeric vector for each named covariate. The vector indicates which covariate effects on intensities are constrained to be equal. Take, for example, a model with five transition intensities and two covariates. Specifying\cr \code{constraint = list (age = c(1,1,1,2,2), treatment = c(1,2,3,4,5))}\cr constrains the effect of age to be equal for the first three intensities, and equal for the fourth and fifth. The effect of treatment is assumed to be different for each intensity. Any vector of increasing numbers can be used as indicators. The intensity parameters are assumed to be ordered by reading across the rows of the transition matrix, starting at the first row, ignoring the diagonals. Negative elements of the vector can be used to indicate that particular covariate effects are constrained to be equal to minus some other effects. For example: \code{constraint = list (age = c(-1,1,1,2,-2), treatment = c(1,2,3,4,5)) }\cr constrains the second and third age effects to be equal, the first effect to be minus the second, and the fifth age effect to be minus the fourth. For example, it may be realisitic that the effect of a covariate on the "reverse" transition rate from state 2 to state 1 is minus the effect on the "forward" transition rate, state 1 to state 2. Note that it is not possible to specify exactly which of the covariate effects are constrained to be positive and which negative. The maximum likelihood estimation chooses the combination of signs which has the higher likelihood. For categorical covariates, defined as factors, specify constraints as follows:\cr \code{list(..., covnameVALUE1 = c(...), covnameVALUE2 = c(...), ...)}\cr where \code{covname} is the name of the factor, and \code{VALUE1}, \code{VALUE2}, ... are the labels of the factor levels (usually excluding the baseline, if using the default contrasts). Make sure the \code{contrasts} option is set appropriately, for example, the default \code{options(contrasts=c(contr.treatment, contr.poly))} sets the first (baseline) level of unordered factors to zero, then the baseline level is ignored in this specification. To assume no covariate effect on a certain transition, use the \code{fixedpars} argument to fix it at its initial value (which is zero by default) during the optimisation. } \item{misccovariates}{A formula representing the covariates on the misclassification probabilities, analogously to \code{covariates}, via multinomial logistic regression. Only used if the model is specified using \code{ematrix}, rather than \code{hmodel}. This must be a single formula - lists are not supported, unlike \code{covariates}. If a different model on each probability is required, include all covariates in this formula, and use \code{fixedpars} to fix some of their effects (for particular probabilities) at their default initial values of zero. } \item{misccovinits}{Initial values for the covariates on the misclassification probabilities, defined in the same way as \code{covinits}. Only used if the model is specified using \code{ematrix}. } \item{miscconstraint}{A list of one vector for each named covariate on misclassification probabilities. The vector indicates which covariate effects on misclassification probabilities are constrained to be equal, analogously to \code{constraint}. Only used if the model is specified using \code{ematrix}. } \item{hcovariates}{ List of formulae the same length as \code{hmodel}, defining any covariates governing the hidden Markov outcome models. The covariates operate on a suitably link-transformed linear scale, for example, log scale for a Poisson outcome model. If there are no covariates for a certain hidden state, then insert a NULL in the corresponding place in the list. For example, \code{hcovariates = list(~acute + age, ~acute, NULL).} } \item{hcovinits}{ Initial values for the hidden Markov model covariate effects. A list of the same length as \code{hcovariates}. Each element is a vector with initial values for the effect of each covariate on that state. For example, the above \code{hcovariates} can be initialised with \code{hcovariates = list(c(-8, 0), -8, NULL)}. Initial values must be given for all or no covariates, if none are given these are all set to zero. The initial value given in the \code{hmodel} constructor function for the corresponding baseline parameter is interpreted as the value of that parameter with any covariates fixed to their means in the data. If multiple effects are constrained to be equal using \code{hconstraint}, then the initial value is taken from the first of the multiple initial values supplied. } \item{hconstraint}{ A named list. Each element is a vector of constraints on the named hidden Markov model parameter. The vector has length equal to the number of times that class of parameter appears in the whole model. For example consider the three-state hidden Markov model described above, with normally-distributed outcomes for states 1 and 2. To constrain the outcome variance to be equal for states 1 and 2, and to also constrain the effect of \code{acute} on the outcome mean to be equal for states 1 and 2, specify \code{hconstraint = list(sd = c(1,1), acute=c(1,1))} Note this excludes initial state occupancy probabilities and covariate effects on those probabilities, which cannot be constrained. } \item{hranges}{Range constraints for hidden Markov model parameters. Supplied as a named list, with each element corresponding to the named hidden Markov model parameter. This element is itself a list with two elements, vectors named "lower" and "upper". These vectors each have length equal to the number of times that class of parameter appears in the whole model, and give the corresponding mininum amd maximum allowable values for that parameter. Maximum likelihood estimation is performed with these parameters constrained in these ranges (through a log or logit-type transformation). Lower bounds of \code{-Inf} and upper bounds of \code{Inf} can be given if the parameter is unbounded above or below. For example, in the three-state model above, to constrain the mean for state 1 to be between 0 and 6, and the mean of state 2 to be between 7 and 12, supply \code{hranges=list(mean=list(lower=c(0, 7), upper=c(6, 12)))} These default to the natural ranges, e.g. the positive real line for variance parameters, and [0,1] for probabilities. Therefore \code{hranges} need not be specified for such parameters unless an even stricter constraint is desired. If only one limit is supplied for a parameter, only the first occurrence of that parameter is constrained. Initial values should be strictly within any ranges, and not on the range boundary, otherwise optimisation will fail with a "non-finite value" error. } \item{qconstraint}{A vector of indicators specifying which baseline transition intensities are equal. For example, \code{qconstraint = c(1,2,3,3)} constrains the third and fourth intensities to be equal, in a model with four allowed instantaneous transitions. When there are covariates on the intensities and \code{center=TRUE} (the default), \code{qconstraint} is applied to the intensities with covariates taking the values of the means in the data. When \code{center=FALSE}, \code{qconstraint} is applied to the intensities with covariates set to zero. } \item{econstraint}{A similar vector of indicators specifying which baseline misclassification probabilities are constrained to be equal. Only used if the model is specified using \code{ematrix}, rather than \code{hmodel}. } \item{initprobs}{Only used in hidden Markov models. Underlying state occupancy probabilities at each subject's first observation. Can either be a vector of \eqn{nstates} elements with common probabilities to all subjects, or a \eqn{nsubjects} by \eqn{nstates} matrix of subject-specific probabilities. This refers to observations after missing data and subjects with only one observation have been excluded. If these are estimated (see \code{est.initprobs}), then this represents an initial value, and defaults to equal probability for each state. Otherwise this defaults to \code{c(1, rep(0, nstates-1))}, that is, in state 1 with a probability of 1. Scaled to sum to 1 if necessary. The state 1 occupancy probability should be non-zero. } \item{est.initprobs}{Only used in hidden Markov models. If \code{TRUE}, then the underlying state occupancy probabilities at the first observation will be estimated, starting from a vector of initial values supplied in the \code{initprobs} argument. Structural zeroes are allowed: if any of these initial values are zero they will be fixed at zero during optimisation, even if \code{est.initprobs=TRUE}, and no covariate effects on them are estimated. The exception is state 1, which should have non-zero occupancy probability. Note that the free parameters during this estimation exclude the state 1 occupancy probability, which is fixed at one minus the sum of the other probabilities. } \item{initcovariates}{ Formula representing covariates on the initial state occupancy probabilities, via multinomial logistic regression. The linear effects of these covariates, observed at the individual's first observation time, operate on the log ratio of the state \eqn{r} occupancy probability to the state 1 occupancy probability, for each \eqn{r = 2} to the number of states. Thus the state 1 occupancy probability should be non-zero. If \code{est.initprobs} is \code{TRUE}, these effects are estimated starting from their initial values. If \code{est.initprobs} is \code{FALSE}, these effects are fixed at theit initial values.} \item{initcovinits}{ Initial values for the covariate effects \code{initcovariates}. A named list with each element corresponding to a covariate, as in \code{covinits}. Each element is a vector with (1 - number of states) elements, containing the initial values for the linear effect of that covariate on the log odds of that state relative to state 1, from state 2 to the final state. If \code{initcovinits} is not specified, all covariate effects are initialised to zero.} \item{deathexact}{Vector of indices of absorbing states whose time of entry is known exactly, but the individual is assumed to be in an unknown transient state ("alive") at the previous instant. This is the usual situation for times of death in chronic disease monitoring data. For example, if you specify \code{deathexact = c(4, 5)} then states 4 and 5 are assumed to be exactly-observed death states. See the \code{obstype} argument. States of this kind correspond to \code{obstype=3}. \code{deathexact = TRUE} indicates that the final absorbing state is of this kind, and \code{deathexact = FALSE} or \code{deathexact = NULL} (the default) indicates that there is no state of this kind. The \code{deathexact} argument is overridden by \code{obstype} or \code{exacttimes}. Note that you do not always supply a \code{deathexact} argument, even if there are states that correspond to deaths, because they do not necessarily have \code{obstype=3}. If the state is known between the time of death and the previous observation, then you should specify \code{obstype=2} for the death times, or \code{exacttimes=TRUE} if the state is known at all times, and the \code{deathexact} argument is ignored. } \item{death}{Old name for the \code{deathexact} argument. Overridden by \code{deathexact} if both are supplied. Deprecated.} \item{censor}{ A state, or vector of states, which indicates censoring. Censoring means that the observed state is known only to be one of a particular set of states. For example, \code{censor=999} indicates that all observations of \code{999} in the vector of observed states are censored states. By default, this means that the true state could have been any of the transient (non-absorbing) states. To specify corresponding true states explicitly, use a \code{censor.states} argument. Note that in contrast to the usual terminology of survival analysis, here it is the \emph{state} which is considered to be censored, rather than the \emph{event time}. If at the end of a study, an individual has not died, but their true state is \emph{known}, then \code{censor} is unnecessary, since the standard multi-state model likelihood is applicable. Also a "censored" state here can be at any time, not just at the end. Note in particular that general time-inhomogeneous Markov models with piecewise constant transition intensities can be constructed using the \code{censor} facility. If the true state is unknown on occasions when a piecewise constant covariate is known to change, then censored states can be inserted in the data on those occasions. The covariate may represent time itself, in which case the \code{pci} option to msm can be used to perform this trick automatically, or some other time-dependent variable. } \item{censor.states}{ Specifies the underlying states which censored observations can represent. If \code{censor} is a single number (the default) this can be a vector, or a list with one element. If \code{censor} is a vector with more than one element, this should be a list, with each element a vector corresponding to the equivalent element of \code{censor}. For example \code{censor = c(99, 999), censor.states = list(c(2,3), c(3,4))} means that observations coded 99 represent either state 2 or state 3, while observations coded 999 are really either state 3 or state 4. } \item{pci}{Model for piecewise-constant intensities. Vector of cut points defining the times, since the start of the process, at which intensities change for all subjects. For example \code{pci = c(5, 10)} specifies that the intensity changes at time points 5 and 10. This will automatically construct a model with a categorical (factor) covariate called \code{timeperiod}, with levels \code{"[-Inf,5)"}, \code{"[5,10)"} and \code{"[10,Inf)"}, where the first level is the baseline. This covariate defines the time period in which the observation was made. Initial values and constraints on covariate effects are specified the same way as for a model with a covariate of this name, for example, \code{covinits = list("timeperiod[5,10)"=c(0.1,0.1), "timeperiod[10,Inf)"=c(0.1,0.1))} Thus if \code{pci} is supplied, you cannot have a previously-existing variable called \code{timeperiod} as a covariate in any part of a \code{msm} model. To assume piecewise constant intensities for some transitions but not others with \code{pci}, use the \code{fixedpars} argument to fix the appropriate covariate effects at their default initial values of zero. Internally, this works by inserting censored observations in the data at times when the intensity changes but the state is not observed. If the supplied times are outside the range of the time variable in the data, \code{pci} is ignored and a time-homogeneous model is fitted. After fitting a time-inhomogeneous model, \code{\link{qmatrix.msm}} can be used to obtain the fitted intensity matrices for each time period, for example, \code{qmatrix.msm(example.msm, covariates=list(timeperiod="[5,Inf)"))} This facility does not support interactions between time and other covariates. Such models need to be specified "by hand", using a state variable with censored observations inserted. Note that the \code{data} component of the \code{msm} object returned from a call to \code{msm} with \code{pci} supplied contains the states with inserted censored observations and time period indicators. These can be used to construct such models. Note that you do not need to use \code{pci} in order to model the effect of a time-dependent covariate in the data. \code{msm} will automatically assume that covariates are piecewise-constant and change at the times when they are observed. \code{pci} is for when you want all intensities to change at the same pre-specified times for all subjects. } \item{phase.states}{ Indices of states which have a two-phase sojourn distribution. This defines a semi-Markov model, in which the hazard of an onward transition depends on the time spent in the state. This uses the technique described by Titman and Sharples (2009). A hidden Markov model is automatically constructed on an expanded state space, where the phases correspond to the hidden states. The "tau" proportionality constraint described in this paper is currently not supported. Covariates, constraints, \code{deathexact} and \code{censor} are expressed with respect to the expanded state space. If not supplied by hand, \code{initprobs} is defined automatically so that subjects are assumed to begin in the first of the two phases. Hidden Markov models can additionally be given phased states. The user supplies an outcome distribution for each original state using \code{hmodel}, which is expanded internally so that it is assumed to be the same within each of the phased states. \code{initprobs} is interpreted on the expanded state space. Misclassification models defined using \code{ematrix} are not supported, and these must be defined using \code{hmmCat} or \code{hmmIdent} constructors, as described in the \code{hmodel} section of this help page. Or the HMM on the expanded state space can be defined by hand. Output functions are presented as it were a hidden Markov model on the expanded state space, for example, transition probabilities between states, covariate effects on transition rates, or prevalence counts, are not aggregated over the hidden phases. Numerical estimation will be unstable when there is weak evidence for a two-phase sojourn distribution, that is, if the model is close to Markov. See \code{\link{d2phase}} for the definition of the two-phase distribution and the interpretation of its parameters. This is an experimental feature, and some functions are not implemented. Please report any experiences of using this feature to the author! } \item{phase.inits}{ Initial values for phase-type models. A list with one component for each "two-phased" state. Each component is itself a list of two elements. The first of these elements is a scalar defining the transition intensity from phase 1 to phase 2. The second element is a matrix, with one row for each potential destination state from the two-phased state, and two columns. The first column is the transition rate from phase 1 to the destination state, and the second column is the transition rate from phase 2 to the destination state. If there is only one destination state, then this may be supplied as a vector. In phase type models, the initial values for transition rates out of non-phased states are taken from the \code{qmatrix} supplied to msm, and entries of this matrix corresponding to transitions out of phased states are ignored. } \item{exacttimes}{By default, the transitions of the Markov process are assumed to take place at unknown occasions in between the observation times. If \code{exacttimes} is set to \code{TRUE}, then the observation times are assumed to represent the exact times of transition of the process. The subject is assumed to be in the same state between these times. An observation may represent a transition to a different state or a repeated observation of the same state (e.g. at the end of follow-up). This is equivalent to every row of the data having \code{obstype = 2}. See the \code{obstype} argument. If both \code{obstype} and \code{exacttimes} are specified then \code{exacttimes} is ignored. Note that the complete history of the multi-state process is known with this type of data. The models which \pkg{msm} fits have the strong assumption of constant (or piecewise-constant) transition rates. Knowing the exact transition times allows more realistic models to be fitted with other packages. For example parametric models with sojourn distributions more flexible than the exponential can be fitted with the \pkg{flexsurv} package, or semi-parametric models can be implemented with \pkg{survival} in conjunction with \pkg{mstate}. } \item{cl}{Width of symmetric confidence intervals for maximum likelihood estimates, by default 0.95.} \item{fixedpars}{Vector of indices of parameters whose values will be fixed at their initial values during the optimisation. These are given in the order: transition intensities (reading across rows of the transition matrix), covariates on intensities (ordered by intensities within covariates), hidden Markov model parameters, including misclassification probabilities or parameters of HMM outcome distributions (ordered by parameters within states), hidden Markov model covariate parameters (ordered by covariates within parameters within states), initial state occupancy probabilities (excluding the first probability, which is fixed at one minus the sum of the others). If there are equality constraints on certain parameters, then \code{fixedpars} indexes the set of unique parameters, excluding those which are constrained to be equal to previous parameters. To fix all parameters, specify \code{fixedpars = TRUE}. This can be useful for profiling likelihoods, and building complex models stage by stage. } \item{center}{If \code{TRUE} (the default, unless \code{fixedpars=TRUE}) then covariates are centered at their means during the maximum likelihood estimation. This usually improves stability of the numerical optimisation. } \item{opt.method}{If "optim", "nlm" or "bobyqa", then the corresponding R function will be used for maximum likelihood estimation. \code{\link{optim}} is the default. "bobyqa" requires the package \pkg{minqa} to be installed. See the help of these functions for further details. Advanced users can also add their own optimisation methods, see the source for \code{optim.R} in msm for some examples. If "fisher", then a specialised Fisher scoring method is used (Kalbfleisch and Lawless, 1985) which can be faster than the generic methods, though less robust. This is only available for Markov models with panel data (\code{obstype=1}), that is, not for models with censored states, hidden Markov models, exact observation or exact death times (\code{obstype=2,3}).} \item{hessian}{If \code{TRUE} then standard errors and confidence intervals are obtained from a numerical estimate of the Hessian (the observed information matrix). This is the default when maximum likelihood estimation is performed. If all parameters are fixed at their initial values and no optimisation is performed, then this defaults to \code{FALSE}. If requested, the actual Hessian is returned in \code{x$paramdata$opt$hessian}, where \code{x} is the fitted model object. If \code{hessian} is set to \code{FALSE}, then standard errors and confidence intervals are obtained from the Fisher (expected) information matrix, if this is available. This may be preferable if the numerical estimation of the Hessian is computationally intensive, or if the resulting estimate is non-invertible or not positive definite.} \item{use.deriv}{If \code{TRUE} then analytic first derivatives are used in the optimisation of the likelihood, where available and an appropriate quasi-Newton optimisation method, such as BFGS, is being used. Analytic derivatives are not available for all models. } \item{use.expm}{If \code{TRUE} then any matrix exponentiation needed to calculate the likelihood is done using the \pkg{expm} package. Otherwise the original routines used in \pkg{msm} 1.2.4 and earlier are used. Set to \code{FALSE} for backward compatibility, and let the package maintainer know if this gives any substantive differences.} \item{analyticp}{By default, the likelihood for certain simpler 3, 4 and 5 state models is calculated using an analytic expression for the transition probability (P) matrix. For all other models, matrix exponentiation is used to obtain P. To revert to the original method of using the matrix exponential for all models, specify \code{analyticp=FALSE}. See the PDF manual for a list of the models for which analytic P matrices are implemented. } \item{na.action}{What to do with missing data: either \code{na.omit} to drop it and carry on, or \code{na.fail} to stop with an error. Missing data includes all NAs in the states, times, \code{subject} or \code{obstrue}, all NAs at the first observation for a subject for covariates in \code{initcovariates}, all NAs in other covariates (excluding the last observation for a subject), all NAs in \code{obstype} (excluding the first observation for a subject), and any subjects with only one observation (thus no observed transitions). } \item{...}{Optional arguments to the general-purpose \R optimisation routine, \code{\link{optim}} by default. For example \code{method="Nelder-Mead"} to change the optimisation algorithm from the \code{"BFGS"} method that msm calls by default. It is often worthwhile to normalize the optimisation using \code{control=list(fnscale = a)}, where \code{a} is the a number of the order of magnitude of the -2 log likelihood. If 'false' convergence is reported and the standard errors cannot be calculated due to a non-positive-definite Hessian, then consider tightening the tolerance criteria for convergence. If the optimisation takes a long time, intermediate steps can be printed using the \code{trace} argument of the control list. See \code{\link{optim}} for details. For the Fisher scoring method, a \code{control} list can be supplied in the same way, but the only supported options are \code{reltol}, \code{trace} and \code{damp}. The first two are used in the same way as for \code{\link{optim}}. If the algorithm fails with a singular information matrix, adjust \code{damp} from the default of zero (to, e.g. 1). This adds a constant identity matrix multiplied by \code{damp} to the information matrix during optimisation. } } \value{ To obtain summary information from models fitted by the \code{\link{msm}} function, it is recommended to use extractor functions such as \code{\link{qmatrix.msm}}, \code{\link{pmatrix.msm}}, \code{\link{sojourn.msm}}, \code{\link{msm.form.qoutput}}. These provide estimates and confidence intervals for quantities such as transition probabilities for given covariate values. For advanced use, it may be necessary to directly use information stored in the object returned by \code{\link{msm}}. This is documented in the help page \code{\link{msm.object}}. Printing a \code{msm} object by typing the object's name at the command line implicitly invokes \code{\link{print.msm}}. This formats and prints the important information in the model fit, and also returns that information in an R object. This includes estimates and confidence intervals for the transition intensities and (log) hazard ratios for the corresponding covariates. When there is a hidden Markov model, the chief information in the \code{hmodel} component is also formatted and printed. This includes estimates and confidence intervals for each parameter. } \details{ For full details about the methodology behind the \pkg{msm} package, refer to the PDF manual \file{msm-manual.pdf} in the \file{doc} subdirectory of the package. This includes a tutorial in the typical use of \pkg{msm}. The paper by Jackson (2011) in Journal of Statistical Software presents the material in this manual in a more concise form. \pkg{msm} was designed for fitting \emph{continuous-time} Markov models, processes where transitions can occur at any time. These models are defined by \emph{intensities}, which govern both the time spent in the current state and the probabilities of the next state. In \emph{discrete-time models}, transitions are known in advance to only occur at multiples of some time unit, and the model is purely governed by the probability distributions of the state at the next time point, conditionally on the state at the current time. These can also be fitted in \pkg{msm}, assuming that there is a continuous-time process underlying the data. Then the fitted transition probability matrix over one time period, as returned by \code{pmatrix.msm(...,t=1)} is equivalent to the matrix that governs the discrete-time model. However, these can be fitted more efficiently using multinomial logistic regression, for example, using \code{multinom} from the R package \pkg{nnet} (Venables and Ripley, 2002). For simple continuous-time multi-state Markov models, the likelihood is calculated in terms of the transition intensity matrix \eqn{Q}. When the data consist of observations of the Markov process at arbitrary times, the exact transition times are not known. Then the likelihood is calculated using the transition probability matrix \eqn{P(t) = \exp(tQ)}{P(t) = exp(tQ)}, where \eqn{\exp}{exp} is the matrix exponential. If state \eqn{i} is observed at time \eqn{t} and state \eqn{j} is observed at time \eqn{u}, then the contribution to the likelihood from this pair of observations is the \eqn{i,j} element of \eqn{P(u - t)}. See, for example, Kalbfleisch and Lawless (1985), Kay (1986), or Gentleman \emph{et al.} (1994). For hidden Markov models, the likelihood for an individual with \eqn{k} observations is calculated directly by summing over the unknown state at each time, producing a product of \eqn{k} matrices. The calculation is a generalisation of the method described by Satten and Longini (1996), and also by Jackson and Sharples (2002), and Jackson \emph{et al.} (2003). There must be enough information in the data on each state to estimate each transition rate, otherwise the likelihood will be flat and the maximum will not be found. It may be appropriate to reduce the number of states in the model, the number of allowed transitions, or the number of covariate effects, to ensure convergence. Hidden Markov models, and situations where the value of the process is only known at a series of snapshots, are particularly susceptible to non-identifiability, especially when combined with a complex transition matrix. Choosing an appropriate set of initial values for the optimisation can also be important. For flat likelihoods, 'informative' initial values will often be required. See the PDF manual for other tips. } \references{ Jackson, C.H. (2011). Multi-State Models for Panel Data: The msm Package for R., Journal of Statistical Software, 38(8), 1-29. URL http://www.jstatsoft.org/v38/i08/. Kalbfleisch, J., Lawless, J.F., The analysis of panel data under a Markov assumption \emph{Journal of the Americal Statistical Association} (1985) 80(392): 863--871. Kay, R. A Markov model for analysing cancer markers and disease states in survival studies. \emph{Biometrics} (1986) 42: 855--865. Gentleman, R.C., Lawless, J.F., Lindsey, J.C. and Yan, P. Multi-state Markov models for analysing incomplete disease history data with illustrations for HIV disease. \emph{Statistics in Medicine} (1994) 13(3): 805--821. Satten, G.A. and Longini, I.M. Markov chains with measurement error: estimating the 'true' course of a marker of the progression of human immunodeficiency virus disease (with discussion) \emph{Applied Statistics} 45(3): 275-309 (1996) Jackson, C.H. and Sharples, L.D. Hidden Markov models for the onset and progression of bronchiolitis obliterans syndrome in lung transplant recipients \emph{Statistics in Medicine}, 21(1): 113--128 (2002). Jackson, C.H., Sharples, L.D., Thompson, S.G. and Duffy, S.W. and Couto, E. Multi-state Markov models for disease progression with classification error. \emph{The Statistician}, 52(2): 193--209 (2003) Titman, A.C. and Sharples, L.D. Semi-Markov models with phase-type sojourn distributions. \emph{Biometrics} 66, 742-752 (2009). Venables, W.N. and Ripley, B.D. (2002) \emph{Modern Applied Statistics with S}, second edition. Springer. } \seealso{ \code{\link{simmulti.msm}}, \code{\link{plot.msm}}, \code{\link{summary.msm}}, \code{\link{qmatrix.msm}}, \code{\link{pmatrix.msm}}, \code{\link{sojourn.msm}}. } \examples{ ### Heart transplant data ### For further details and background to this example, see ### Jackson (2011) or the PDF manual in the doc directory. print(cav[1:10,]) twoway4.q <- rbind(c(-0.5, 0.25, 0, 0.25), c(0.166, -0.498, 0.166, 0.166), c(0, 0.25, -0.5, 0.25), c(0, 0, 0, 0)) statetable.msm(state, PTNUM, data=cav) crudeinits.msm(state ~ years, PTNUM, data=cav, qmatrix=twoway4.q) cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = 4, control = list ( trace = 2, REPORT = 1 ) ) cav.msm qmatrix.msm(cav.msm) pmatrix.msm(cav.msm, t=10) sojourn.msm(cav.msm) } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/cav.Rd0000644000176200001440000000376513051600620012665 0ustar liggesusers\name{cav} \docType{data} \alias{cav} \title{Heart transplant monitoring data} \description{ A series of approximately yearly angiographic examinations of heart transplant recipients. The state at each time is a grade of cardiac allograft vasculopathy (CAV), a deterioration of the arterial walls. } \usage{cav} \format{ A data frame containing 2846 rows. There are 622 patients, the rows are grouped by patient number and ordered by years after transplant, with each row representing an examination and containing additional covariates. \tabular{rll}{ \code{PTNUM} \tab (numeric) \tab Patient identification number \cr \code{age} \tab (numeric) \tab Recipient age at examination (years) \cr \code{years} \tab (numeric) \tab Examination time (years after transplant)\cr \code{dage} \tab (numeric) \tab Age of heart donor (years) \cr \code{sex} \tab (numeric) \tab sex (0=male, 1=female) \cr \code{pdiag} \tab (factor) \tab Primary diagnosis (reason for transplant) \cr \tab \tab IHD=ischaemic heart disease, IDC=idiopathic dilated cardiomyopathy. \cr \code{cumrej} \tab (numeric) \tab Cumulative number of acute rejection episodes \cr \code{state} \tab (numeric) \tab State at the examination. \cr \tab \tab State 1 represents no CAV, state 2 is mild/moderate CAV \cr \tab \tab and state 3 is severe CAV. State 4 indicates death. \cr \code{firstobs} \tab (numeric) \tab 0 = record represents an angiogram or date of death.\cr \tab \tab 1 = record represents transplant (patient's first observation) \cr \code{statemax} \tab (numeric) \tab Maximum observed state so far for this patient (added in version 1.5.1) }} \source{ Papworth Hospital, U.K. } \references{ Sharples, L.D. and Jackson, C.H. and Parameshwar, J. and Wallwork, J. and Large, S.R. (2003). Diagnostic accuracy of coronary angiopathy and risk factors for post-heart-transplant cardiac allograft vasculopathy. Transplantation 76(4):679-82 } \keyword{datasets} msm/man/logLik.msm.Rd0000644000176200001440000000160713051600620014121 0ustar liggesusers\name{logLik.msm} \alias{logLik.msm} \title{Extract model log-likelihood} \description{ Extract the log-likelihood and the number of parameters of a model fitted with \code{\link{msm}}. } \usage{ \method{logLik}{msm}(object, by.subject=FALSE, \dots) } \arguments{ \item{object}{A fitted multi-state model object, as returned by \code{\link{msm}}.} \item{by.subject}{Return vector of subject-specific log-likelihoods, which should sum to the total log-likelihood.} \item{...}{(unused) further arguments passed to or from other methods.} } \value{ The log-likelihood of the model represented by 'object' evaluated at the maximum likelihood estimates. Akaike's information criterion can also be computed using \code{\link{AIC}(object)}. } \seealso{ \code{\link{msm}},\code{\link{lrtest.msm}}. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/msm.object.Rd0000644000176200001440000001442613051600620014151 0ustar liggesusers\name{msm.object} \alias{msm.object} \title{Fitted msm model objects} \description{ The \code{\link{msm}} function returns a list with the following components. These are intended for developers and confident users. To extract results from fitted model objects, functions such as \code{\link{qmatrix.msm}} or \code{\link{print.msm}} should be used instead. } \value{ \item{call}{The original call to \code{\link{msm}}, as returned by \code{\link{match.call}}.} \item{Qmatrices}{A list of matrices. The first component, labelled \code{logbaseline}, is a matrix containing the estimated transition intensities on the log scale with any covariates fixed at their means in the data (or at zero, if \code{center=FALSE}). The component labelled \code{baseline} is the equivalent on the untransformed scale. Each remaining component is a matrix giving the linear effects of the labelled covariate on the matrix of log intensities. To extract an estimated intensity matrix on the natural scale, at an arbitrary combination of covariate values, use the function \code{\link{qmatrix.msm}}. } \item{QmatricesSE}{The standard error matrices corresponding to \code{Qmatrices}. } \item{QmatricesL,QmatricesU}{Corresponding lower and upper symmetric confidence limits, of width 0.95 unless specified otherwise by the \code{cl} argument. } \item{Ematrices}{A list of matrices. The first component, labelled \code{logitbaseline}, is the estimated misclassification probability matrix (expressed as as log odds relative to the probability of the true state) with any covariates fixed at their means in the data (or at zero, if \code{center=FALSE}). The component labelled \code{baseline} is the equivalent on the untransformed scale. Each remaining component is a matrix giving the linear effects of the labelled covariate on the matrix of logit misclassification probabilities. To extract an estimated misclassification probability matrix on the natural scale, at an arbitrary combination of covariate values, use the function \code{\link{ematrix.msm}}.} \item{EmatricesSE}{The standard error matrices corresponding to \code{Ematrices}.} \item{EmatricesL,EmatricesU}{Corresponding lower and upper symmetric confidence limits, of width 0.95 unless specified otherwise by the \code{cl} argument. } \item{minus2loglik}{Minus twice the maximised log-likelihood.} \item{deriv}{Derivatives of the minus twice log-likelihood at its maximum.} \item{estimates}{Vector of untransformed maximum likelihood estimates returned from \code{\link{optim}}. Transition intensities are on the log scale and misclassification probabilities are given as log odds relative to the probability of the true state.} \item{estimates.t}{Vector of transformed maximum likelihood estimates with intensities and probabilities on their natural scales.} \item{fixedpars}{Indices of \code{estimates} which were fixed during the maximum likelihood estimation.} \item{center}{Indicator for whether the estimation was performed with covariates centered on their means in the data.} \item{covmat}{Covariance matrix corresponding to \code{estimates}.} \item{ci}{Matrix of confidence intervals corresponding to \code{estimates.t}} \item{opt}{Return value from the optimisation routine (such as \code{\link{optim}} or \code{\link{nlm}}), giving information about the results of the optimisation.} \item{foundse}{Logical value indicating whether the Hessian was positive-definite at the supposed maximum of the likelihood. If not, the covariance matrix of the parameters is unavailable. In these cases the optimisation has probably not converged to a maximum. } \item{data}{A list giving the data used for the model fit, for use in post-processing. To extract it, use the methods \code{\link{model.frame.msm}} or \code{\link{model.matrix.msm}}. The format of this element changed in version 1.4 of \pkg{msm}, so that it now contains a \code{\link{model.frame}} object \code{mf} with all the variables used in the model. The previous format (an ad-hoc list of vectors and matrices) can be obtained with the function \code{recreate.olddata(msmobject)}, where \code{msmobject} is the object returned by \code{msm}. } \item{qmodel}{A list of objects representing the transition matrix structure and options for likelihood calculation. See \code{\link{qmodel.object}} for documentation of the components.} \item{emodel}{A list of objects representing the misclassification model structure, for models specified using the \code{ematrix} argument to \code{\link{msm}}. See \code{\link{emodel.object}}.} \item{qcmodel}{A list of objects representing the model for covariates on transition intensities. See \code{\link{qcmodel.object}}.} \item{ecmodel}{A list of objects representing the model for covariates on transition intensities. See \code{\link{ecmodel.object}}.} \item{hmodel}{A list of objects representing the hidden Markov model structure. See \code{\link{hmodel.object}}.} \item{cmodel}{A list giving information about censored states. See \code{\link{cmodel.object}}. } \item{pci}{Cut points for time-varying intensities, as supplied to \code{\link{msm}}, but excluding any that are outside the times observed in the data.} \item{paramdata}{A list giving information about the parameters of the multi-state model. See \code{\link{paramdata.object}}.} \item{cl}{Confidence interval width, as supplied to \code{\link{msm}}.} \item{covariates}{Formula for covariates on intensities, as supplied to \code{\link{msm}}.} \item{misccovariates}{Formula for covariates on misclassification probabilities, as supplied to \code{\link{msm}}.} \item{hcovariates}{Formula for covariates on hidden Markov model outcomes, as supplied to \code{\link{msm}}.} \item{initcovariates}{Formula for covariates on initial state occupancy probabilities in hidden Markov models, as supplied to \code{\link{msm}}.} \item{sojourn}{ A list as returned by \code{\link{sojourn.msm}}, with components: \code{mean} = estimated mean sojourn times in the transient states, with covariates fixed at their means (if center=TRUE) or at zero (if center=FALSE). \code{se} = corresponding standard errors. } } msm/man/plot.prevalence.msm.Rd0000644000176200001440000000771113051600620016003 0ustar liggesusers\name{plot.prevalence.msm} \alias{plot.prevalence.msm} \title{Plot of observed and expected prevalences} \description{ Provides a rough indication of goodness of fit of a multi-state model, by estimating the observed numbers of individuals occupying a state at a series of times, and plotting these against forecasts from the fitted model, for each state. Observed prevalences are indicated as solid lines, expected prevalences as dashed lines. } \usage{ \method{plot}{prevalence.msm}(x, mintime=NULL, maxtime=NULL, timezero=NULL, initstates=NULL, interp=c("start","midpoint"), censtime=Inf, subset=NULL, covariates="population", misccovariates="mean", piecewise.times=NULL, piecewise.covariates=NULL, xlab="Times",ylab="Prevalence (\%)", lwd.obs=1, lwd.exp=1, lty.obs=1, lty.exp=2, col.obs="blue", col.exp="red", legend.pos=NULL, ...) } \arguments{ \item{x}{A fitted multi-state model produced by \code{\link{msm}}.} \item{mintime}{Minimum time at which to compute the observed and expected prevalences of states.} \item{maxtime}{Maximum time at which to compute the observed and expected prevalences of states.} \item{timezero}{Initial time of the Markov process. Expected values are forecasted from here. Defaults to the minimum of the observation times given in the data. } \item{initstates}{Optional vector of the same length as the number of states. Gives the numbers of individuals occupying each state at the initial time, to be used for forecasting expected prevalences. The default is those observed in the data. These should add up to the actual number of people in the study at the start. } \item{interp}{Interpolation method for observed states, see \code{\link{prevalence.msm}}.} \item{censtime}{Subject-specific maximum follow-up times, see \code{\link{prevalence.msm}}.} \item{subset}{Vector of the subject identifiers to calculated observed prevalences for.} \item{covariates}{Covariate values for which to forecast expected state occupancy. See \code{\link{prevalence.msm}} --- if this function runs too slowly, as it may if there are continuous covariates, replace \code{covariates="population"} with \code{covariates="mean"}. } \item{misccovariates}{(Misclassification models only) Values of covariates on the misclassification probability matrix. See \code{\link{prevalence.msm}}. } \item{piecewise.times}{Times at which piecewise-constant intensities change. See \code{\link{prevalence.msm}}.} \item{piecewise.covariates}{Covariates on which the piecewise-constant intensities depend. See \code{\link{prevalence.msm}}.} \item{xlab}{x axis label.} \item{ylab}{y axis label.} \item{lwd.obs}{Line width for observed prevalences. See \code{\link{par}}.} \item{lwd.exp}{Line width for expected prevalences. See \code{\link{par}}.} \item{lty.obs}{Line type for observed prevalences. See \code{\link{par}}.} \item{lty.exp}{Line type for expected prevalences. See \code{\link{par}}.} \item{col.obs}{Line colour for observed prevalences. See \code{\link{par}}.} \item{col.exp}{Line colour for expected prevalences. See \code{\link{par}}.} \item{legend.pos}{Vector of the \eqn{x} and \eqn{y} position, respectively, of the legend.} \item{...}{Further arguments to be passed to the generic \code{\link{plot}} function.} } \details{ See \code{\link{prevalence.msm}} for details of the assumptions underlying this method. Observed prevalences are plotted with a solid line, and expected prevalences with a dotted line. } \references{ Gentleman, R.C., Lawless, J.F., Lindsey, J.C. and Yan, P. Multi-state Markov models for analysing incomplete disease history data with illustrations for HIV disease. \emph{Statistics in Medicine} (1994) 13(3): 805--821. } \seealso{ \code{\link{prevalence.msm}} } \keyword{models} msm/man/hazard.msm.Rd0000644000176200001440000000232113051600620014143 0ustar liggesusers\name{hazard.msm} \title{Calculate tables of hazard ratios for covariates on transition intensities} \alias{hazard.msm} \description{ Hazard ratios are computed by exponentiating the estimated covariate effects on the log-transition intensities. This function is called by \code{\link{summary.msm}}. } \usage{ hazard.msm(x, hazard.scale = 1, cl = 0.95) } \arguments{ \item{x}{Output from \code{\link{msm}} representing a fitted multi-state model.} \item{hazard.scale}{Vector with same elements as number of covariates on transition rates. Corresponds to the increase in each covariate used to calculate its hazard ratio. Defaults to all 1.} \item{cl}{Width of the symmetric confidence interval to present. Defaults to 0.95.} } \value{ A list of tables containing hazard ratio estimates, one table for each covariate. Each table has three columns, containing the hazard ratio, and an approximate upper and lower confidence limit respectively (assuming normality on the log scale), for each Markov chain transition intensity. } \seealso{ \code{\link{msm}}, \code{\link{summary.msm}}, \code{\link{odds.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/fev.Rd0000644000176200001440000000336513051600620012670 0ustar liggesusers\name{fev} \docType{data} \alias{fev} \title{FEV1 measurements from lung transplant recipients} \description{ A series of measurements of the forced expiratory volume in one second (FEV1) from lung transplant recipients, from six months onwards after their transplant. } \usage{fev} \format{ A data frame containing 5896 rows. There are 204 patients, the rows are grouped by patient number and ordered by days after transplant. Each row represents an examination and containing an additional covariate. \tabular{rll}{ \code{ptnum} \tab (numeric) \tab Patient identification number. \cr \code{days} \tab (numeric) \tab Examination time (days after transplant). \cr \code{fev} \tab (numeric) \tab Percentage of baseline FEV1. A code of 999 indicates the patient's date of death. \cr \code{acute} \tab (numeric) \tab 0/1 indicator for whether the patient suffered an acute infection or rejection \cr \tab \tab within 14 days of the visit. \cr }} \details{ A baseline "normal" FEV1 for each individual is calculated using measurements from the first six months after transplant. After six months, as presented in this dataset, FEV1 is expressed as a percentage of the baseline value. FEV1 is monitored to diagnose bronchiolitis obliterans syndrome (BOS), a long-term lung function decline, thought to be a form of chronic rejection. Acute rejections and infections also affect the lung function in the short term. } \source{ Papworth Hospital, U.K. } \keyword{datasets} \references{ Jackson, C.H. and Sharples, L.D. Hidden Markov models for the onset and progression of bronchiolitis obliterans syndrome in lung transplant recipients \emph{Statistics in Medicine}, 21(1): 113--128 (2002). } msm/man/MatrixExp.Rd0000644000176200001440000000731514124277102014037 0ustar liggesusers\name{MatrixExp} \title{Matrix exponential} \alias{MatrixExp} \concept{Matrix exponential} \description{ Calculates the exponential of a square matrix. } \usage{ MatrixExp(mat, t = 1, method=NULL, ...) } \arguments{ \item{mat}{A square matrix} \item{t}{An optional scaling factor for \code{mat}.} \item{method}{ Under the default of \code{NULL}, this simply wraps the \code{\link[expm]{expm}} function from the \pkg{expm} package. This is recommended. Options to \code{\link{expm}} can be supplied to \code{\link{MatrixExp}}, including \code{method}. Otherwise, for backwards compatibility, the following options, which use code in the \pkg{msm} package, are available: \code{"pade"} for a Pade approximation method, \code{"series"} for the power series approximation, or \code{"analytic"} for the analytic formulae for simpler Markov model intensity matrices (see below). These options are only used if \code{mat} has repeated eigenvalues, thus the usual eigen-decomposition method cannot be used. } \item{...}{Arguments to pass to \code{\link{expm}}.} } \value{ The exponentiated matrix \eqn{\exp(mat)}{exp(mat)}. Or, if \code{t} is a vector of length 2 or more, an array of exponentiated matrices. } \details{ See the \code{\link[expm]{expm}} documentation for details of the algorithms it uses. Generally the exponential \eqn{E} of a square matrix \eqn{M} can often be calculated as \deqn{E = U \exp(D) U^{-1}}{E = U exp(D) U^{-1}} where \eqn{D} is a diagonal matrix with the eigenvalues of \eqn{M} on the diagonal, \eqn{\exp(D)}{exp(D)} is a diagonal matrix with the exponentiated eigenvalues of \eqn{M} on the diagonal, and \eqn{U} is a matrix whose columns are the eigenvectors of \eqn{M}. This method of calculation is used if \code{"pade"} or \code{"series"} is supplied but \eqn{M} has distinct eigenvalues. I If \eqn{M} has repeated eigenvalues, then its eigenvector matrix may be non-invertible. In this case, the matrix exponential is calculated using the Pade approximation defined by Moler and van Loan (2003), or the less robust power series approximation, \deqn{\exp(M) = I + M + M^2/2 + M^3 / 3! + M^4 / 4! + ...}{exp(M) = I + M + M^2/2 + M^3 / 3! + M^4 / 4! + ...} For a continuous-time homogeneous Markov process with transition intensity matrix \eqn{Q}, the probability of occupying state \eqn{s} at time \eqn{u + t} conditional on occupying state \eqn{r} at time \eqn{u} is given by the \eqn{(r,s)} entry of the matrix \eqn{\exp(tQ)}{exp(tQ)}. If \code{mat} is a valid transition intensity matrix for a continuous-time Markov model (i.e. diagonal entries non-positive, off-diagonal entries non-negative, rows sum to zero), then for certain simpler model structures, there are analytic formulae for the individual entries of the exponential of \code{mat}. These structures are listed in the PDF manual and the formulae are coded in the \pkg{msm} source file \code{src/analyticp.c}. These formulae are only used if \code{method="analytic"}. This is more efficient, but it is not the default in \code{MatrixExp} because the code is not robust to extreme values. However it is the default when calculating likelihoods for models fitted by \code{\link{msm}}. The implementation of the Pade approximation used by \code{method="pade"} was taken from JAGS by Martyn Plummer (\url{https://mcmc-jags.sourceforge.io}). } \references{ Cox, D. R. and Miller, H. D. \emph{The theory of stochastic processes}, Chapman and Hall, London (1965) Moler, C and van Loan, C (2003). Nineteen dubious ways to compute the exponential of a matrix, twenty-five years later. \emph{SIAM Review} \bold{45}, 3--49. } \keyword{math} msm/man/totlos.msm.Rd0000644000176200001440000002063213051600620014223 0ustar liggesusers\name{totlos.msm} \alias{totlos.msm} \alias{envisits.msm} \title{Total length of stay, or expected number of visits} \description{ Estimate the expected total length of stay, or the expected number of visits, in each state, for an individual in a given period of evolution of a multi-state model. } \usage{ totlos.msm(x, start=1, end=NULL, fromt=0, tot=Inf, covariates="mean", piecewise.times=NULL, piecewise.covariates=NULL, num.integ=FALSE, discount=0, env=FALSE, ci=c("none","normal","bootstrap"), cl=0.95, B=1000, cores=NULL, ...) envisits.msm(x, start=1, end=NULL, fromt=0, tot=Inf, covariates="mean", piecewise.times=NULL, piecewise.covariates=NULL, num.integ=FALSE, discount=0, ci=c("none","normal","bootstrap"), cl=0.95, B=1000, cores=NULL, ...) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}. } \item{start}{Either a single number giving the state at the beginning of the period, or a vector of probabilities of being in each state at this time. } \item{end}{States to estimate the total length of stay (or number of visits) in. Defaults to all states. This is deprecated, since with the analytic solution (see "Details") it doesn't save any computation to only estimate for a subset of states.} \item{fromt}{Time from which to estimate. Defaults to 0, the beginning of the process.} \item{tot}{Time up to which the estimate is made. Defaults to infinity, giving the expected time spent in or number of visits to the state until absorption. However, the calculation will be much more efficient if a finite (potentially large) time is specified: see the "Details" section. For models without an absorbing state, \code{t} must be specified.} \item{covariates}{ The covariate values to estimate for. This can either be:\cr the string \code{"mean"}, denoting the means of the covariates in the data (this is the default),\cr the number \code{0}, indicating that all the covariates should be set to zero,\cr or a list of values, with optional names. For example \code{list (60, 1)} where the order of the list follows the order of the covariates originally given in the model formula, or a named list, \code{list (age = 60, sex = 1)} } \item{piecewise.times}{ Times at which piecewise-constant intensities change. See \code{\link{pmatrix.piecewise.msm}} for how to specify this. This is only required for time-inhomogeneous models specified using explicit time-dependent covariates, and should not be used for models specified using "pci".} \item{piecewise.covariates}{Covariates on which the piecewise-constant intensities depend. See \code{\link{pmatrix.piecewise.msm}} for how to specify this.} \item{num.integ}{Use numerical integration instead of analytic solution (see below).} \item{discount}{Discount rate in continuous time.} \item{env}{Supplied to \code{\link{totlos.msm}}. If \code{TRUE}, return the expected number of visits to each state. If \code{FALSE}, return the total length of stay in each state. \code{\link{envisits.msm}} simply calls \code{\link{totlos.msm}} with \code{env=TRUE}.} \item{ci}{If \code{"normal"}, then calculate a confidence interval by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects, then calculating the total length of stay for each replicate. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}. If \code{"none"} (the default) then no confidence interval is calculated.} \item{cl}{Width of the symmetric confidence interval, relative to 1} \item{B}{Number of bootstrap replicates} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} \item{...}{Further arguments to be passed to the \code{\link{integrate}} function to control the numerical integration.} } \value{ A vector of expected total lengths of stay (\code{\link{totlos.msm}}), or expected number of visits (\code{\link{envisits.msm}}), for each transient state. } \details{ The expected total length of stay in state \eqn{j} between times \eqn{t_1} and \eqn{t_2}, from the point of view of an individual in state \eqn{i} at time 0, is defined by the integral from \eqn{t_1} to \eqn{t_2} of the \eqn{i,j} entry of the transition probability matrix \eqn{P(t) = Exp(tQ)}, where \eqn{Q} is the transition intensity matrix. The corresponding expected number of visits to state \eqn{j} (excluding the stay in the current state at time 0) is \eqn{\sum_{i!=j} T_i Q_{i,j}}, where \eqn{T_i} is the expected amount of time spent in state \eqn{i}. More generally, suppose that \eqn{\pi_0}{pi_0} is the vector of probabilities of being in each state at time 0, supplied in \code{start}, and we want the vector \eqn{\mathbf{x}}{x} giving the expected lengths of stay in each state. The corresponding integral has the following solution (van Loan 1978; van Rosmalen et al. 2013) \deqn{\mathbf{x} = \left[\begin{array}{ll}1 & \mathbf{0}_K \end{array}\right] Exp(t Q') \left[\begin{array}{ll} \mathbf{0}_K\\I_K \end{array}\right]}{x = [1, 0_K] Exp(t Q') [0_K, I_K]'} where \deqn{Q' = \left[\begin{array}{ll} 0 & \mathbf{\pi}_0\\ \mathbf{0}_K & Q - rI_K\end{array}\right]}{Q' = rbind(c(0, pi_0), cbind(0_K, Q - r I_K)),} \eqn{\pi_0}{pi_0} is the row vector of initial state probabilities supplied in \code{start}, \eqn{\mathbf{0}_K}{0_K} is the row vector of K zeros, \eqn{r} is the discount rate, \eqn{I_K}{I_K} is the K x K identity matrix, and \eqn{Exp} is the matrix exponential. Alternatively, the integrals can be calculated numerically, using the \code{\link{integrate}} function. This may take a long time for models with many states where \eqn{P(t)} is expensive to calculate. This is required where \code{tot = Inf}, since the package author is not aware of any analytic expression for the limit of the above formula as \eqn{t} goes to infinity. With the argument \code{num.integ=TRUE}, numerical integration is used even where the analytic solution is available. This facility is just provided for checking results against versions 1.2.4 and earlier, and will be removed eventually. Please let the package maintainer know if any results are different. For a model where the individual has only one place to go from each state, and each state is visited only once, for example a progressive disease model with no recovery or death, these are equal to the mean sojourn time in each state. However, consider a three-state health-disease-death model with transitions from health to disease, health to death, and disease to death, where everybody starts healthy. In this case the mean sojourn time in the disease state will be greater than the expected length of stay in the disease state. This is because the mean sojourn time in a state is conditional on entering the state, whereas the expected total time diseased is a forecast for a healthy individual, who may die before getting the disease. In the above formulae, \eqn{Q} is assumed to be constant over time, but the results generalise easily to piecewise-constant intensities. This function automatically handles models fitted using the \code{pci} option to \code{\link{msm}}. For any other inhomogeneous models, the user must specify \code{piecewise.times} and \code{piecewise.covariates} arguments to \code{\link{totlos.msm}}. } \references{ C. van Loan (1978). Computing integrals involving the matrix exponential. IEEE Transactions on Automatic Control 23(3)395-404. J. van Rosmalen, M. Toy and J.F. O'Mahony (2013). A mathematical approach for evaluating Markov models in continuous time without discrete-event simulation. Medical Decision Making 33:767-779. } \seealso{ \code{\link{sojourn.msm}}, \code{\link{pmatrix.msm}}, \code{\link{integrate}}, \code{\link{boot.msm}}. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/plot.survfit.msm.Rd0000644000176200001440000001351513051600620015360 0ustar liggesusers\name{plot.survfit.msm} \alias{plot.survfit.msm} \title{Plot empirical and fitted survival curves} \description{ Plot a Kaplan-Meier estimate of the survival probability and compare it with the fitted survival probability from a \code{msm} model. } \usage{ \method{plot}{survfit.msm}(x, from=1, to=NULL, range=NULL, covariates="mean", interp=c("start","midpoint"), ci=c("none","normal","bootstrap"), B=100, legend.pos=NULL, xlab="Time", ylab="Survival probability", lty=1, lwd=1, col="red", lty.ci=2, lwd.ci=1, col.ci="red", mark.time=TRUE, col.surv="blue", lty.surv=2, lwd.surv=1, survdata=FALSE, ...) } \arguments{ \item{x}{Output from \code{\link{msm}}, representing a fitted multi-state model object.} \item{from}{Non-absorbing state from which to consider survival. Defaults to state 1. The fitted probabilities will then be calculated as the transition probabilities from this state to \code{to}. The empirical survival curve plots survival from the first observation of \code{from} (where this exists) to the first entry time into \code{to}. } \item{to}{Absorbing state to consider. Defaults to the highest-labelled absorbing state. } \item{range}{Vector of two elements, giving the range of times to plot for.} \item{covariates}{Covariate values for which to evaluate the expected probabilities. This can either be:\cr the string \code{"mean"}, denoting the means of the covariates in the data (this is the default),\cr the number \code{0}, indicating that all the covariates should be set to zero,\cr or a list of values, with optional names. For example \code{list (60, 1)} where the order of the list follows the order of the covariates originally given in the model formula, or a named list, \code{list (age = 60, sex = 1)} but note the empirical curve is plotted for the full population. To consider subsets for the empirical curve, set \code{survdata=TRUE} to extract the survival data and build a survival plot by hand using \code{\link[survival]{plot.survfit}}. } \item{ci}{If \code{"none"} (the default) no confidence intervals are plotted. If \code{"normal"} or \code{"bootstrap"}, confidence intervals are plotted based on the respective method in \code{\link{pmatrix.msm}}. This is very computationally-intensive, since intervals must be computed at a series of times.} \item{B}{Number of bootstrap or normal replicates for the confidence interval. The default is 100 rather than the usual 1000, since these plots are for rough diagnostic purposes.} \item{interp}{If \code{interp="start"} (the default) then the entry time into the absorbing state is assumed to be the time it is first observed in the data. If \code{interp="midpoint"} then the entry time into the absorbing state is assumed to be halfway between the time it is first observed and the previous observation time. This is generally more reasonable for "progressive" models with observations at arbitrary times. } \item{legend.pos}{Vector of the \eqn{x} and \eqn{y} position, respectively, of the legend.} \item{xlab}{x axis label.} \item{ylab}{y axis label.} \item{lty}{Line type for the fitted curve. See \code{\link{par}}.} \item{lwd}{Line width for the fitted curve. See \code{\link{par}}.} \item{col}{Colour for the fitted curve. See \code{\link{par}}.} \item{lty.ci}{Line type for the fitted curve confidence limits. See \code{\link{par}}.} \item{lwd.ci}{Line width for the fitted curve confidence limits. See \code{\link{par}}.} \item{col.ci}{Colour for the fitted curve confidence limits. See \code{\link{par}}.} \item{mark.time}{Mark the empirical survival curve at each censoring point, see \code{\link[survival]{lines.survfit}}.} \item{col.surv}{Colour for the empirical survival curve, passed to \code{\link[survival]{lines.survfit}}. See \code{\link{par}}.} \item{lty.surv}{Line type for the empirical survival curve, passed to \code{\link[survival]{lines.survfit}}. See \code{\link{par}}.} \item{lwd.surv}{Line width for the empirical survival curve, passed to \code{\link[survival]{lines.survfit}}. See \code{\link{par}}.} \item{survdata}{Set to \code{TRUE} to return the survival data frame constructed when plotting the empirical curve. This can be used for constructing survival plots by hand using \code{\link[survival]{plot.survfit}}.} \item{...}{Other arguments to be passed to the \code{\link{plot}} function which draws the fitted curve, or the \code{\link[survival]{lines.survfit}} function which draws the empirical curve. } } \details{ If the data represent observations of the process at arbitrary times, then the first occurrence of the absorbing state in the data will usually be greater than the actual first transition time to that state. Therefore the Kaplan-Meier estimate of the survival probability will be an overestimate. The method of Turnbull (1976) could be used to give a non-parametric estimate of the time to an interval-censored event, and compared to the equivalent estimate from a multi-state model. This is implemented in the CRAN package \pkg{interval} (Fay and Shaw 2010). This currently only handles time-homogeneous models. } \references{ Turnbull, B. W. (1976) The empirical distribution function with arbitrarily grouped, censored and truncated data. J. R. Statist. Soc. B 38, 290-295. Fay, MP and Shaw, PA (2010). Exact and Asymptotic Weighted Logrank Tests for Interval Censored Data: The interval R package. Journal of Statistical Software. http://www.jstatsoft.org/v36/ i02/. 36 (2):1-34. } \seealso{\code{\link[survival]{survfit}}, \code{\link[survival]{plot.survfit}}, \code{\link{plot.prevalence.msm}}} \keyword{models} msm/man/model.frame.msm.Rd0000644000176200001440000000603513051600620015071 0ustar liggesusers\name{model.frame.msm} \alias{model.frame.msm} \alias{model.matrix.msm} \title{Extract original data from \code{msm} objects.} \description{ Extract the data from a multi-state model fitted with \code{msm}. } \usage{ \method{model.frame}{msm}(formula, agg=FALSE, \dots) \method{model.matrix}{msm}(object, model="intens", state=1, \dots) } \arguments{ \item{formula}{A fitted multi-state model object, as returned by \code{\link{msm}}.} \item{agg}{Return the model frame in the efficient aggregated form used to calculate the likelihood internally for non-hidden Markov models. This has one row for each unique combination of from-state, to-state, time lag, covariate value and observation type. The variable named \code{"(nocc)"} counts how many observations of that combination there are in the original data. } \item{object}{A fitted multi-state model object, as returned by \code{\link{msm}}.} \item{model}{\code{"intens"} to return the design matrix for covariates on intensities, \code{"misc"} for misclassification probabilities, \code{"hmm"} for a general hidden Markov model, and \code{"inits"} for initial state probabilities in hidden Markov models.} \item{state}{State corresponding to the required covariate design matrix in a hidden Markov model.} \item{...}{Further arguments (not used).} } \value{ \code{model.frame} returns a data frame with all the original variables used for the model fit, with any missing data removed (see \code{na.action} in \code{\link{msm}}). The state, time, subject, \code{obstype} and \code{obstrue} variables are named \code{"(state)"}, \code{"(time)"}, \code{"(subject)"}, \code{"(obstype)"} and \code{"(obstrue)"} respectively (note the brackets). A variable called \code{"(obs)"} is the observation number from the original data before any missing data were dropped. The variable \code{"(pcomb)"} is used for computing the likelihood for hidden Markov models, and identifies which distinct time difference, \code{obstype} and covariate values (thus which distinct interval transition probability matrix) each observation corresponds to. The model frame object has some other useful attributes, including \code{"usernames"} giving the user's original names for these variables (used for model refitting, e.g. in bootstrapping or cross validation) and \code{"covnames"} identifying which ones are covariates. \code{model.matrix} returns a design matrix for a part of the model that includes covariates. The required part is indicated by the \code{"model"} argument. For time-inhomogeneous models fitted with \code{"pci"}, these datasets will have imputed observations at each time change point, indicated where the variable \code{"(pci.imp)"} in the model frame is 1. The model matrix for intensities will have factor contrasts for the \code{timeperiod} covariate. } \seealso{ \code{\link{msm}}, \code{\link{model.frame}}, \code{\link{model.matrix}}. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/qmodel.object.Rd0000644000176200001440000000516413051600620014635 0ustar liggesusers\name{qmodel.object} \alias{qmodel.object} \title{Developer documentation: transition model structure object} \description{ A list giving information about the structure of states and allowed transitions in a multi-state model, and options for likelihood calculation. Used in internal computations, and returned in a fitted \code{\link{msm}} model object. } \value{ \item{nstates}{Number of states} \item{iso}{Label for which basic structure the model is isomorphic to in the list of structures for which analytic formulae for the transition probabilities are implemented in the source file \code{src/analyticp.c}. This list is given by the internal object \code{msm:::.msm.graphs} which is defined and documented in the source file \code{R/constants.R}. \code{iso} is 0 if the analytic P matrix is not implemented for this structure, or if analytic P matrix calculations are disabled using \code{use.analyticp=FALSE} in the call to \code{\link{msm}}. } \item{perm}{Permutation required to convert the base isomorphism into the structure of this model. A vector of integers whose \eqn{r}th element is the state number in the base structure representing state \eqn{r} in the current structure. } \item{qperm}{Inverse permutation: vector whose \eqn{r}th element is the state number in the current structure representing the \eqn{r}th state in the base structure.} \item{npars}{Number of allowed instantaneous transitions, equal to \code{sum(imatrix)}.} \item{imatrix}{Indicator matrix for allowed instantaneous transitions. This has \eqn{(r,s)} entry 1 if the transition from \eqn{r} to \eqn{s} is permitted in continuous time, and 0 otherwise. The diagonal entries are arbitrarily set to 0.} \item{qmatrix}{Matrix of initial values for the transition intensities, supplied as the \code{qmatrix} argument of \code{\link{msm}}.} \item{inits}{Vector of these initial values, reading across rows of \code{qmatrix} and excluding the diagonal and disallowed transitions.} \item{constr}{Indicators for equality constraints on baseline intensities, taken from the \code{qconstraint} argument to \code{\link{msm}}, and mapped if necessary to the set (1,2,3,...).} \item{ndpars}{Number of distinct allowed instantaneous transitions, after applying equality constraints.} \item{expm}{Use \pkg{expm} package to calculate matrix exponentials for likelihoods, as supplied to the \code{use.expm} argument of \code{\link{msm}}. \code{TRUE} or \code{FALSE}.} } \seealso{ \code{\link{msm.object}},\code{\link{emodel.object}}, \code{\link{hmodel.object}}. }msm/man/pnext.msm.Rd0000644000176200001440000000651613051600620014042 0ustar liggesusers\name{pnext.msm} \alias{pnext.msm} \title{Probability of each state being next} \description{ Compute a matrix of the probability of each state \eqn{s} being the next state of the process after each state \eqn{r}. Together with the mean sojourn times in each state (\code{\link{sojourn.msm}}), these fully define a continuous-time Markov model. } \usage{ pnext.msm(x, covariates = "mean", ci=c("normal","bootstrap","delta","none"), cl = 0.95, B=1000, cores=NULL) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}.} \item{covariates}{ The covariate values at which to estimate the intensities. This can either be:\cr the string \code{"mean"}, denoting the means of the covariates in the data (this is the default),\cr the number \code{0}, indicating that all the covariates should be set to zero,\cr or a list of values, with optional names. For example \code{list (60, 1)} where the order of the list follows the order of the covariates originally given in the model formula, or a named list, \code{list (age = 60, sex = 1)} } \item{ci}{ If \code{"normal"} (the default) then calculate a confidence interval by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects, then transforming. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}. If \code{"delta"} then confidence intervals are calculated based on the delta method SEs of the log rates, but this is not recommended since it may not respect the constraint that probabilities are less than one. } \item{cl}{Width of the symmetric confidence interval to present. Defaults to 0.95.} \item{B}{Number of bootstrap replicates, or number of normal simulations from the distribution of the MLEs.} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} } \value{ The matrix of probabilities that the next move of a process in state \eqn{r} (rows) is to state \eqn{s} (columns). } \details{ For a continuous-time Markov process in state \eqn{r}, the probability that the next state is \eqn{s} is \eqn{-q_{rs} / q_{rr}}, where \eqn{q_{rs}} is the transition intensity (\code{\link{qmatrix.msm}}). A continuous-time Markov model is fully specified by these probabilities together with the mean sojourn times \eqn{-1/q_{rr}} in each state \eqn{r}. This gives a more intuitively meaningful description of a model than the intensity matrix. Remember that \pkg{msm} deals with continuous-time, not discrete-time models, so these are \emph{not} the same as the probability of observing state \eqn{s} at a fixed time in the future. Those probabilities are given by \code{\link{pmatrix.msm}}. } \seealso{ \code{\link{qmatrix.msm}},\code{\link{pmatrix.msm}},\code{\link{qratio.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/phasemeans.msm.Rd0000644000176200001440000000256313051600620015026 0ustar liggesusers\name{phasemeans.msm} \alias{phasemeans.msm} \title{Parameters of phase-type models in mixture form} \description{ Parameters of fitted two-phase models, in mixture model parameterisation. } \usage{ phasemeans.msm(x, covariates="mean", ci=c("none","normal","bootstrap"), cl=0.95, B=1000, cores=NULL) } \arguments{ \item{x}{A fitted multi-state model, as returned by \code{\link{msm}}.} \item{covariates}{Covariate values, see \code{\link{qmatrix.msm}}.} \item{ci}{ If \code{"none"} (the default) no confidence intervals are calculated. Otherwise \code{"normal"}, or \code{"boot"} as described by \code{\link{qmatrix.msm}}.} \item{cl}{Width of the symmetric confidence interval, relative to 1.} \item{B}{Number of bootstrap replicates, or number of normal simulations from the distribution of the MLEs.} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} } \value{ Matrix with one row for each state that has a two-phase distribution, and three columns: the short-stay mean, long-stay mean and long-stay probability. These are functions of the transition intensities of the expanded hidden Markov model, defined in \code{\link{d2phase}}. } \seealso{ \code{\link{d2phase}}. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/bos.Rd0000644000176200001440000000363613051600620012674 0ustar liggesusers\name{bos} \docType{data} \alias{bos} \alias{bos3} \alias{bos4} \title{Bronchiolitis obliterans syndrome after lung transplants} \description{ A dataset containing histories of bronchiolitis obliterans syndrome (BOS) from lung transplant recipients. BOS is a chronic decline in lung function, often observed after lung transplantation. The condition is classified into four stages of severity: none, mild, moderate and severe. } \usage{bos} \format{ A data frame containing 638 rows, grouped by patient, including histories of 204 patients. The first observation for each patient is defined to be stage 1, no BOS, at six months after transplant. Subsequent observations denote the entry times into stages 2, 3, 4, representing mild, moderate and severe BOS respectively, and stage 5, representing death. \tabular{rll}{ \code{ptnum} \tab (numeric) \tab Patient identification number \cr \code{time} \tab (numeric) \tab Months after transplant \cr \code{state} \tab (numeric) \tab BOS state entered at this time \cr }} \details{ The entry time of each patient into each stage of BOS was estimated by clinicians, based on their history of lung function measurements and acute rejection and infection episodes. BOS is only assumed to occur beyond six months after transplant. In the first six months the function of each patient's new lung stabilises. Subsequently BOS is diagnosed by comparing the lung function against the "baseline" value. The objects \code{bos3} and \code{bos4} contain the same data, but with mild/moderate/severe combined, and moderate/severe combined, to give 3 and 4-state representations respectively. } \source{ Papworth Hospital, U.K. } \references{ Heng. D. et al. (1998). Bronchiolitis Obliterans Syndrome: Incidence, Natural History, Prognosis, and Risk Factors. Journal of Heart and Lung Transplantation 17(12)1255--1263. } \keyword{datasets} msm/man/paramdata.object.Rd0000644000176200001440000000742513051600620015310 0ustar liggesusers\name{paramdata.object} \alias{paramdata.object} \title{Developer documentation: internal msm parameters object} \description{ An object giving information about the parameters of the multi-state model. Used internally during maximum likelihood estimation and arranging results. Returned as the \code{paramdata} component of a fitted \code{\link{msm}} model object. } \value{ \item{inits}{Vector of initial values for distinct parameters which are being estimated. These have been transformed to the real line (e.g. by log), and exclude parameters being fixed at their initial values, parameters defined to be always fixed (e.g. binomial denominators) and parameters constrained to equal previous ones.} \item{plabs}{Names of parameters in \code{allinits}.} \item{allinits}{Vector of parameter values before estimation, including those which are fixed or constrained to equal other parameters, and transformed to the real line.} \item{hmmpars}{Indices of \code{allinits} which represent baseline parameters of hidden Markov outcome models (thus excluding covariate effects in HMMs and initial state occupancy probabilities). } \item{fixed}{\code{TRUE} if all parameters are fixed, \code{FALSE} otherwise.} \item{fixedpars}{Indices of parameters in \code{allinits} which are fixed, either by definition or as requested by the user in the \code{fixedpars} argument to \code{\link{msm}}. Excludes parameters fixed by constraining to equal other parameters.} \item{notfixed}{Indices of parameters which are not fixed by the definition of \code{fixedpars}.} \item{optpars}{Indices of parameters in \code{allinits} being estimated, thus those included in \code{inits}.} \item{auxpars}{Indices of "auxiliary" parameters which are always fixed, for example, binomial denominators (\code{\link{hmmBinom}}) and the \code{which} parameter in \code{\link{hmmIdent}}.} \item{constr}{Vector of integers, of length \code{npars}, indicating which sets of parameters are constrained to be equal to each other. If two of these integers are equal the corresponding parameters are equal. A negative element indicates that parameter is defined to be minus some other parameter (this is used for covariate effects on transition intensities).} \item{npars}{Total number of parameters, equal to \code{length(allinits)}.} \item{nfix}{Number of fixed parameters, equal to \code{length(fixedpars)}. } \item{nopt}{Number of parameters being estimated, equal to \code{length(inits)} and \code{length(optpars)}.} \item{ndup}{Number of parameters defined as duplicates of previous parameters by equality constraints (currently unused).} \item{ranges}{Matrix of defined ranges for each parameter on the natural scale (e.g. 0 to infinity for rate parameters). } \item{opt}{Object returned by the optimisation routine (such as \code{\link{optim}}).} \item{foundse}{\code{TRUE} if standard errors are available after optimisation. If \code{FALSE} the optimisation probably hasn't converged. } \item{lik}{Minus twice the log likelihood at the parameter estimates.} \item{deriv}{Derivatives of the minus twice log likelihood at the parameter estimates, if available. } \item{information}{Corresponding expected information matrix at the parameter estimates, if available.} \item{params}{Vector of parameter values after maximum likelihood estimation, corresponding to \code{allinits}, still on the real-line transformed scale.} \item{covmat}{Covariance matrix corresponding to \code{params}.} \item{ci}{Matrix of confidence intervals corresponding to \code{params}, with nominal coverage (default 0.95) defined by the \code{cl} argument of \code{\link{msm}}. } \item{estimates.t}{Vector of parameter estimates, as \code{params} but with parameters on their natural scales.} } \seealso{ \code{\link{msm.object}} } msm/man/psor.Rd0000644000176200001440000000374613051600620013076 0ustar liggesusers\name{psor} \docType{data} \alias{psor} \title{Psoriatic arthritis data} \description{ A series of observations of grades of psoriatic arthritis, as indicated by numbers of damaged joints. } \usage{psor} \format{ A data frame containing 806 observations, representing visits to a psoriatic arthritis (PsA) clinic from 305 patients. The rows are grouped by patient number and ordered by examination time. Each row represents an examination and contains additional covariates. \tabular{rll}{ \code{ptnum} \tab (numeric) \tab Patient identification number \cr \code{months} \tab (numeric) \tab Examination time in months \cr \code{state} \tab (numeric) \tab Clinical state of PsA. Patients in states 1, 2, 3 and 4 \cr \tab \tab have 0, 1 to 4, 5 to 9 and 10 or more damaged joints, \cr \tab \tab respectively. \cr \code{hieffusn} \tab (numeric) \tab Presence of five or more effusions \cr \code{ollwsdrt} \tab (character) \tab Erythrocyte sedimentation rate of less than 15 mm/h \cr }} \references{ Gladman, D. D. and Farewell, V.T. (1999) Progression in psoriatic arthritis: role of time-varying clinical indicators. J. Rheumatol. 26(11):2409-13 } \examples{ ## Four-state progression-only model with high effusion and low ## sedimentation rate as covariates on the progression rates. High ## effusion is assumed to have the same effect on the 1-2, 2-3, and 3-4 ## progression rates, while low sedimentation rate has the same effect ## on the 1-2 and 2-3 intensities, but a different effect on the 3-4. data(psor) psor.q <- rbind(c(0,0.1,0,0),c(0,0,0.1,0),c(0,0,0,0.1),c(0,0,0,0)) psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), fixedpars=FALSE, control = list(REPORT=1,trace=2), method="BFGS") qmatrix.msm(psor.msm) sojourn.msm(psor.msm) hazard.msm(psor.msm) } \keyword{datasets} msm/man/prevalence.msm.Rd0000644000176200001440000002240013761410001015016 0ustar liggesusers \name{prevalence.msm} \title{Tables of observed and expected prevalences} \alias{prevalence.msm} \concept{Goodness of fit} \description{ This provides a rough indication of the goodness of fit of a multi-state model, by estimating the observed numbers of individuals occupying each state at a series of times, and comparing these with forecasts from the fitted model. } \usage{ prevalence.msm(x, times=NULL, timezero=NULL, initstates=NULL, covariates="population", misccovariates="mean", piecewise.times=NULL, piecewise.covariates=NULL, ci=c("none","normal","bootstrap"), cl=0.95, B=1000, cores=NULL, interp=c("start","midpoint"), censtime=Inf, subset=NULL, plot=FALSE, ...) } \arguments{ \item{x}{A fitted multi-state model produced by \code{\link{msm}}.} \item{times}{Series of times at which to compute the observed and expected prevalences of states.} \item{timezero}{Initial time of the Markov process. Expected values are forecasted from here. Defaults to the minimum of the observation times given in the data. } \item{initstates}{Optional vector of the same length as the number of states. Gives the numbers of individuals occupying each state at the initial time, to be used for forecasting expected prevalences. The default is those observed in the data. These should add up to the actual number of people in the study at the start. } \item{covariates}{Covariate values for which to forecast expected state occupancy. With the default \code{covariates="population"}, expected prevalences are produced by summing model predictions over the covariates observed in the original data, for a fair comparison with the observed prevalences. This may be slow, particularly with continuous covariates. Predictions for fixed covariates can be obtained by supplying covariate values in the standard way, as in \code{\link{qmatrix.msm}}. Therefore if \code{covariates="population"} is too slow, using the mean observed values through \code{covariates="mean"} may give a reasonable approximation. This argument is ignored if \code{piecewise.times} is specified. If there are a mixture of time-constant and time-dependent covariates, then the values for all covariates should be supplied in \code{piecewise.covariates}. } \item{misccovariates}{(Misclassification models only) Values of covariates on the misclassification probability matrix for converting expected true to expected misclassified states. Ignored if \code{covariates="population"}, otherwise defaults to the mean values of the covariates in the data set.} \item{piecewise.times}{Times at which piecewise-constant intensities change. See \code{\link{pmatrix.piecewise.msm}} for how to specify this. Ignored if \code{covariates="population"}. This is only required for time-inhomogeneous models specified using explicit time-dependent covariates, and should not be used for models specified using "pci". } \item{piecewise.covariates}{Covariates on which the piecewise-constant intensities depend. See \code{\link{pmatrix.piecewise.msm}} for how to specify this. Ignored if \code{covariates="population"}.} \item{ci}{If \code{"normal"}, then calculate a confidence interval for the expected prevalences by simulating \code{B} random vectors from the asymptotic multivariate normal distribution implied by the maximum likelihood estimates (and covariance matrix) of the log transition intensities and covariate effects, then calculating the expected prevalences for each replicate. If \code{"bootstrap"} then calculate a confidence interval by non-parametric bootstrap refitting. This is 1-2 orders of magnitude slower than the \code{"normal"} method, but is expected to be more accurate. See \code{\link{boot.msm}} for more details of bootstrapping in \pkg{msm}. If \code{"none"} (the default) then no confidence interval is calculated.} \item{cl}{Width of the symmetric confidence interval, relative to 1} \item{B}{Number of bootstrap replicates} \item{cores}{Number of cores to use for bootstrapping using parallel processing. See \code{\link{boot.msm}} for more details.} \item{interp}{Suppose an individual was observed in states \eqn{S_{r-1}} and \eqn{S_r} at two consecutive times \eqn{t_{r-1}} and \eqn{t_r}, and we want to estimate 'observed' prevalences at a time \eqn{t} between \eqn{t_{r-1}} and \eqn{t_r}. If \code{interp="start"}, then individuals are assumed to be in state \eqn{S_{r-1}} at time \eqn{t}, the same state as they were at \eqn{t_{r-1}}. If \code{interp="midpoint"} then if \eqn{t <= (t_{r-1} + t_r) / 2}, the midpoint of \eqn{t_{r-1}} and \eqn{t_r}, the state at \eqn{t} is assumed to be \eqn{S_{r-1}}, otherwise \eqn{S_{r}}. This is generally more reasonable for "progressive" models. } \item{censtime}{Adjustment to the observed prevalences to account for limited follow-up in the data. If the time is greater than \code{censtime} and the patient has reached an absorbing state, then that subject will be removed from the risk set. For example, if patients have died but would only have been observed up to this time, then this avoids overestimating the proportion of people who are dead at later times. This can be supplied as a single value, or as a vector with one element per subject (after any \code{subset} has been taken), in the same order as the original data. This vector also only includes subjects with complete data, thus it excludes for example subjects with only one observation (thus no observed transitions), and subjects for whom every observation has missing values. (Note, to help construct this, the complete data used for the model fit can be accessed with \code{model.frame(x)}, where \code{x} is the fitted model object) This is ignored if it is less than the subject's maximum observation time. } \item{subset}{Subset of subjects to calculate observed prevalences for.} \item{plot}{Generate a plot of observed against expected prevalences. See \code{\link{plot.prevalence.msm}}} \item{...}{Further arguments to pass to \code{\link{plot.prevalence.msm}}.} } \value{ A list of matrices, with components: \item{Observed}{Table of observed numbers of individuals in each state at each time} \item{Observed percentages}{Corresponding percentage of the individuals at risk at each time.} \item{Expected}{Table of corresponding expected numbers.} \item{Expected percentages}{Corresponding percentage of the individuals at risk at each time.} Or if \code{ci.boot = TRUE}, the component \code{Expected} is a list with components \code{estimates} and \code{ci}.\cr \code{estimates} is a matrix of the expected prevalences, and \code{ci} is a list of two matrices, containing the confidence limits. The component \code{Expected percentages} has a similar format. } \details{ The fitted transition probability matrix is used to forecast expected prevalences from the state occupancy at the initial time. To produce the expected number in state \eqn{j} at time \eqn{t} after the start, the number of individuals under observation at time \eqn{t} (including those who have died, but not those lost to follow-up) is multiplied by the product of the proportion of individuals in each state at the initial time and the transition probability matrix in the time interval \eqn{t}. The proportion of individuals in each state at the "initial" time is estimated, if necessary, in the same way as the observed prevalences. For misclassification models (fitted using an \code{ematrix}), this aims to assess the fit of the full model for the \emph{observed} states. That is, the combined Markov progression model for the true states and the misclassification model. Thus, expected prevalences of \emph{true} states are estimated from the assumed proportion occupying each state at the initial time using the fitted transition probabiliy matrix. The vector of expected prevalences of true states is then multiplied by the fitted misclassification probability matrix to obtain the expected prevalences of \emph{observed} states. For general hidden Markov models, the observed state is taken to be the predicted underlying state from the Viterbi algorithm (\code{\link{viterbi.msm}}). The goodness of fit of these states to the underlying Markov model is tested. In any model, if there are censored states, then these are replaced by imputed values of highest probability from the Viterbi algorithm in order to calculate the observed state prevalences. For an example of this approach, see Gentleman \emph{et al.} (1994). } \references{ Gentleman, R.C., Lawless, J.F., Lindsey, J.C. and Yan, P. Multi-state Markov models for analysing incomplete disease history data with illustrations for HIV disease. \emph{Statistics in Medicine} (1994) 13(3): 805--821. Titman, A.C., Sharples, L. D. Model diagnostics for multi-state models. \emph{Statistical Methods in Medical Research} (2010) 19(6):621-651. } \seealso{ \code{\link{msm}}, \code{\link{summary.msm}} } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/man/2phase.Rd0000644000176200001440000001413013051600620013262 0ustar liggesusers\name{2phase} \alias{d2phase} \alias{p2phase} \alias{q2phase} \alias{r2phase} \alias{h2phase} \title{Coxian phase-type distribution with two phases} \description{ Density, distribution, quantile functions and other utilities for the Coxian phase-type distribution with two phases. } \usage{ d2phase(x, l1, mu1, mu2, log=FALSE) p2phase(q, l1, mu1, mu2, lower.tail=TRUE, log.p=FALSE) q2phase(p, l1, mu1, mu2, lower.tail=TRUE, log.p=FALSE) r2phase(n, l1, mu1, mu2) h2phase(x, l1, mu1, mu2, log=FALSE) } \arguments{ \item{x,q}{vector of quantiles.} \item{p}{vector of probabilities.} \item{n}{number of observations. If \code{length(n) > 1}, the length is taken to be the number required.} \item{l1}{Intensity for transition between phase 1 and phase 2.} \item{mu1}{Intensity for transition from phase 1 to exit.} \item{mu2}{Intensity for transition from phase 2 to exit.} \item{log}{logical; if TRUE, return log density or log hazard.} \item{log.p}{logical; if TRUE, probabilities p are given as log(p).} \item{lower.tail}{logical; if TRUE (default), probabilities are P[X <= x], otherwise, P[X > x].} } \value{ \code{d2phase} gives the density, \code{p2phase} gives the distribution function, \code{q2phase} gives the quantile function, \code{r2phase} generates random deviates, and \code{h2phase} gives the hazard. } \details{ This is the distribution of the time to reach state 3 in a continuous-time Markov model with three states and transitions permitted from state 1 to state 2 (with intensity \eqn{\lambda_1}{lambda1}) state 1 to state 3 (intensity \eqn{\mu_1}{mu1}) and state 2 to state 3 (intensity \eqn{\mu_2}{mu2}). States 1 and 2 are the two "phases" and state 3 is the "exit" state. The density is \deqn{f(t | \lambda_1, \mu_1) = e^{-(\lambda_1+\mu_1)t}(\mu_1 + (\lambda_1+\mu_1)\lambda_1 t)}{f(t | l1, mu1) = exp(-(l1+mu1)*t)*(mu1 + (l1+mu1)*l1*t)} if \eqn{\lambda_1 + \mu_1 = \mu_2}{l1 + mu1 = mu2}, and \deqn{f(t | \lambda_1, \mu_1, \mu_2) = \frac{(\lambda_1+\mu_1)e^{-(\lambda_1+\mu_1)t}(\mu_2-\mu_1) + \mu_2\lambda_1e^{-\mu_2t}}{\lambda_1+\mu_1-\mu_2}}{f(t | l1, mu1, mu2) = ((l1+mu1)*exp(-(l1+mu1)*t)*(mu2-mu1) + mu2*l1*exp(-mu2*t))/(l1+mu1-mu2)} otherwise. The distribution function is \deqn{F(t | \lambda_1, \mu_1) = 1 - e^{-(\lambda_1+\mu_1) t} (1 + \lambda_1 t)}{F(t | l1, mu1) = 1 - exp(-(l1+mu1)*t)*(1 + l1*t)} if \eqn{\lambda_1 + \mu_1 = \mu_2}{l1 + mu1 = mu2}, and \deqn{F(t | \lambda_1, \mu_1, \mu_2) = 1 - \frac{e^{-(\lambda_1+\mu_1) t} (\mu_2 - \mu_1) + \lambda_1 e^{-\mu_2 t}}{\lambda_1+\mu_1-\mu_2}}{F(t | l1, mu1, mu2) = 1 - (exp(-(l1+mu1)*t)*(-mu1+mu2) + l1*exp(-mu2*t))/(l1+mu1-mu2)} otherwise. Quantiles are calculated by numerically inverting the distribution function. The mean is \eqn{(1 + \lambda_1/\mu_2) / (\lambda_1 + \mu_1)}{(1 + l1/mu2) / (l1 + mu1)}. The variance is \eqn{(2 + 2\lambda_1(\lambda_1+\mu_1+ \mu_2)/\mu_2^2 - (1 + \lambda_1/\mu_2)^2)/(\lambda_1+\mu_1)^2}{(2 + 2*l1*(l1+mu1+ mu2)/mu2^2 - (1 + l1/mu2)^2)/(l1+mu1)^2}. If \eqn{\mu_1=\mu_2}{mu1=mu2} it reduces to an exponential distribution with rate \eqn{\mu_1}{mu1}, and the parameter \eqn{\lambda_1}{l1} is redundant. Or also if \eqn{\lambda_1=0}{l1=0}. The hazard at \eqn{x=0} is \eqn{\mu_1}, and smoothly increasing if \eqn{\mu_1<\mu_2}{mu1= mu2} it increases to an asymptote of \eqn{\mu_2}{mu2}, and if \eqn{\lambda_1 + \mu_1 \leq \mu_2}{l1 + mu1 <= mu2} it increases to an asymptote of \eqn{\lambda_1 + \mu_1}{l1 + mu1}. The hazard is decreasing if \eqn{\mu_1>\mu_2}{mu1>mu2}, to an asymptote of \eqn{\mu_2}{mu2}. } \section{Alternative parameterisation}{ An individual following this distribution can be seen as coming from a mixture of two populations: 1) "short stayers" whose mean sojourn time is \eqn{M_1 = 1/(\lambda_1+\mu_1)}{M1 = 1/(l1+mu1)} and sojourn distribution is exponential with rate \eqn{\lambda_1 + \mu_1}{l1+mu1}. 2) "long stayers" whose mean sojourn time \eqn{M_2 = 1/(\lambda_1+\mu_1) + 1/\mu_2}{1/(l1+mu1) + 1/mu2} and sojourn distribution is the sum of two exponentials with rate \eqn{\lambda_1 + \mu_1}{l1+mu1} and \eqn{\mu_2}{mu2} respectively. The individual is a "long stayer" with probability \eqn{p=\lambda_1/(\lambda_1 + \mu_1)}. Thus a two-phase distribution can be more intuitively parameterised by the short and long stay means \eqn{M_1 < M_2} and the long stay probability \eqn{p}. Given these parameters, the transition intensities are \eqn{\lambda_1=p/M_1}{l1=p/M1}, \eqn{\mu_1=(1-p)/M_1}{mu1=(1-p)/M1}, and \eqn{\mu_2=1/(M_2-M_1)}{mu2 = 1/(M2 - M1)}. This can be useful for choosing intuitively reasonable initial values for procedures to fit these models to data. The hazard is increasing at least if \eqn{M_2 < 2M_1}{M2 < 2M1}, and also only if \eqn{(M_2 - 2M_1)/(M_2 - M_1) < p}{(M2 - 2M1)/(M2 - M1) < p}. For increasing hazards with \eqn{\lambda_1 + \mu_1 \leq \mu_2}{l1 + mu1 <= mu2}, the maximum hazard ratio between any time \eqn{t} and time 0 is \eqn{1/(1-p)}. For increasing hazards with \eqn{\lambda_1 + \mu_1 \geq \mu_2}{l1 + mu1 >= mu2}, the maximum hazard ratio is \eqn{M_1/((1-p)(M_2 - M_1))}{M1/((1-p)(M2 - M1))}. This is the minimum hazard ratio for decreasing hazards. % Illustration of hazard ratio at short mean and long mean. } \section{General phase-type distributions}{ This is a special case of the n-phase Coxian phase-type distribution, which in turn is a special case of the (general) phase-type distribution. The \pkg{actuar} R package implements a general n-phase distribution defined by the time to absorption of a general continuous-time Markov chain with a single absorbing state, where the process starts in one of the transient states with a given probability. } \references{ C. Dutang, V. Goulet and M. Pigeon (2008). actuar: An R Package for Actuarial Science. Journal of Statistical Software, vol. 25, no. 7, 1-37. URL http://www.jstatsoft.org/v25/i07 } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk} } \keyword{distribution} msm/man/print.msm.Rd0000644000176200001440000000435613051600620014040 0ustar liggesusers\name{print.msm} \title{Print a fitted msm model object} \alias{print.msm} \alias{printnew.msm} \description{ Print a fitted msm model object } \usage{ \method{print}{msm}(x,covariates=NULL, digits=4, \dots) printnew.msm(x, covariates=NULL, digits=4, \dots) } \arguments{ \item{x}{Output from \code{\link{msm}}, representing a fitted multi-state model object.} \item{covariates}{Covariates for which to print ``baseline'' transition intensities or misclassification probabilities. See \code{\link{qmatrix.msm}} for more details. } \item{digits}{Minimum number of significant digits, passed to \code{\link{format}}. Defaults to 4.} \item{...}{Other arguments to be passed to \code{\link{format}}.} } \details{ This is the new method of formatting msm objects for printing. The old method was based on printing lists of matrices. That produced a lot of wasted space for parameters which were zero, and it was difficult to match corresponding numbers between matrices. The new method presents all the transition intensities and covariate effects as a single compact table, and likewise for misclassification matrices. Also in the old method, covariate effects were presented as log hazard ratios or log odds ratios. The log scale is more convenient mathematically, but unnatural to interpret. The new method presents hazard ratios for covariates on transition intensities and odds ratios for misclassification probabilities. \code{printnew.msm} is an alias for \code{print.msm}. } \value{ The object returned by \code{print.msm} is a numeric matrix with one column for each estimate or confidence limit for intensities and their covariates, in the same arrangement as printed, but with the underlying numbers in full precision. The results formatted for printing are stored in the \code{"formatted"} attribute of the object, as a character matrix. These can alternatively be produced by \code{\link{msm.form.qoutput}}, which has no printing side-effect. \code{\link{msm.form.eoutput}} produces the same arrangement for misclassification probabilities instead of intensities. } \seealso{ \code{\link{msm}}, \code{\link{printold.msm}}, \code{\link{msm.form.qoutput}}. } \author{C. H. Jackson \email{chris.jackson@mrc-bsu.cam.ac.uk}} \keyword{models} msm/DESCRIPTION0000644000176200001440000000177714124311712012564 0ustar liggesusersPackage: msm Version: 1.6.9 Date: 2021-09-26 Title: Multi-State Markov and Hidden Markov Models in Continuous Time Author: Christopher Jackson Maintainer: Christopher Jackson Description: Functions for fitting continuous-time Markov and hidden Markov multi-state models to longitudinal data. Designed for processes observed at arbitrary times in continuous time (panel data) but some other observation schemes are supported. Both Markov transition rates and the hidden Markov output process can be modelled in terms of covariates, which may be constant or piecewise-constant in time. License: GPL (>= 2) Imports: survival,mvtnorm,expm Suggests: mstate,minqa,doParallel,foreach,numDeriv,testthat,flexsurv URL: https://github.com/chjackson/msm BugReports: https://github.com/chjackson/msm/issues LazyData: yes NeedsCompilation: yes Packaged: 2021-09-27 08:24:28 UTC; Chris Repository: CRAN Date/Publication: 2021-09-27 09:50:02 UTC msm/build/0000755000176200001440000000000014124277672012161 5ustar liggesusersmsm/build/vignette.rds0000644000176200001440000000034014124277672014515 0ustar liggesusers}Q0  Qc Mpb&^WȀ擋E46i׭~6!D%:1a9L% Q`Ib7HjSqeJK<:/)\b(x(UgÉ(y4]`2HxW2 50Em=K@wqРɋcVȋڜ s䷺~Ymsm/tests/0000755000176200001440000000000014124277674012226 5ustar liggesusersmsm/tests/testthat/0000755000176200001440000000000014124277674014066 5ustar liggesusersmsm/tests/testthat/test_analyticp.r0000644000176200001440000006715114116442530017270 0ustar liggesuserscontext("analytic transition probability matrices") fixq <- function(Q){ diag(Q) <- 0; diag(Q) <- - rowSums(Q); Q } # avoid namespace faff nsubj <- 50; nobspt <- 6 sim.df <- data.frame(subject = rep(1:nsubj, each=nobspt), time = seq(0, 20, length.out=nobspt), x = rnorm(nsubj*nobspt), y = rnorm(nsubj*nobspt)* 5 + 2 ) set.seed(22061976) test_that("2 state analytic P matrices",{ (two.q <- fixq(rbind(c(0, exp(-2)), c(0, 0)))) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=two.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-3)), c(0, 0)), analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-3)), c(0, 0)), analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) ## 1,2 (two.q <- fixq(rbind(c(0, exp(-2)), c(exp(-2), 0)))) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=two.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-3)), c(exp(-1), 0)), analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-3)), c(exp(-1), 0)), analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) }) test_that("3 state analytic P matrices",{ ## 1,2 (three.q <- fixq(rbind(c(0, exp(-3), exp(-3)), c(0, 0, 0), c(0, 0, 0)))) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-1)), c(0, 0, 0), c(0, 0, 0)), analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-1)), c(0, 0, 0), c(0, 0, 0)), analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) ## 1,4 (three.q <- fixq(rbind(c(0, exp(-3), 0), c(0, 0, exp(-3)), c(0, 0, 0)))) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0), c(0, 0, exp(-1)), c(0, 0, 0)), analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0), c(0, 0, exp(-1)), c(0, 0, 0)), analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) # 4,5 (== 1,4) nsubj <- 500; nobspt <- 6 sim.df <- data.frame(subject = rep(1:nsubj, each=nobspt), time = seq(0, 20, length.out=nobspt), x = rnorm(nsubj*nobspt), y = rnorm(nsubj*nobspt)* 5 + 2 ) (three.q <- fixq(rbind(c(0, 0, 0), c(0, 0, exp(-2)), c(exp(-3), 0, 0)))) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, start=rep(2,500)) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, 0, 0), c(0, 0, exp(-3)), c(exp(-2), 0, 0)), analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, 0, 0), c(0, 0, exp(-3)), c(exp(-2), 0, 0)), analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) ## 1,6 (three.q <- fixq(rbind(c(0, exp(-3), 0), c(0, 0, 0), c(0, exp(-3), 0)))) nsubj <- 50; nobspt <- 6 sim.df <- data.frame(subject = rep(1:nsubj, each=nobspt), time = seq(0, 20, length.out=nobspt), x = rnorm(nsubj*nobspt), y = rnorm(nsubj*nobspt)* 5 + 2 ) set.seed(22061976) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, start=c(rep(3,25),rep(1,25))) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0), c(0, 0, 0), c(0, exp(-1), 0)), analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0), c(0, 0, 0), c(0, exp(-1), 0)), analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) #1,2,4 (= 3,4,5) (three.q <- fixq(rbind(c(0, 0, 0), c(exp(-3), 0, exp(-3)), c(exp(-3), 0, 0)))) set.seed(22061976) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, start=rep(2, 50)) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, 0, 0), c(exp(-2), 0, exp(-2)), c(2*exp(-2), 0, 0)), analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, 0, 0), c(exp(-2), 0, exp(-2)), c(2*exp(-2), 0, 0)), analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) # 1,2,4 (three.q <- fixq(rbind(c(0, exp(-3), exp(-6)), c(0, 0, exp(-3)), c(0, 0, 0)))) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-2)), c(0, 0, exp(-1)), c(0, 0, 0)), analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-2)), c(0, 0, exp(-1)), c(0, 0, 0)), analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) # 1,2,4 (=1,2,6) (three.q <- fixq(rbind(c(0, exp(-3), exp(-6)), c(0, 0, 0), c(0, exp(-3), 0)))) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-2)), c(0, 0, 0), c(0, exp(-2), 0)), analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-2)), c(0, 0, 0), c(0, exp(-2), 0)), analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) #1,3,5 (= 2,4,5) (three.q <- fixq(rbind(c(0, 0, exp(-3)), c(0, 0, exp(-3)), c(exp(-3), 0, 0)))) set.seed(22061976) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, start=c(rep(1, 25), rep(2,25))) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, 0, exp(-1)), c(0, 0, exp(-1)), c(exp(-2), 0, 0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, 0, exp(-1)), c(0, 0, exp(-1)), c(exp(-2), 0, 0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) #1,2,4,6 (three.q <- fixq(rbind(c(0, exp(-3), exp(-3)), c(0, 0, exp(-3)), c(0, exp(-3), 0)))) set.seed(22061976) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, start=c(rep(1, 25), rep(2,25))) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-1)), c(0, 0, exp(-1)), c(0, exp(-2), 0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-1)), c(0, 0, exp(-1)), c(0, exp(-2), 0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-1)), c(0, 0, exp(-1)), c(0, exp(-1), 0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), exp(-1)), c(0, 0, exp(-1)), c(0, exp(-1), 0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) }) ## FOUR STATES #1,5,9 test_that("4 state analytic P matrices",{ (four.q <- fixq(rbind(c(0, exp(-3), 0, 0), c(0, 0, exp(-3), 0), c(0, 0, 0, exp(-3)), c(0,0,0,0)))) set.seed(22061976) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=four.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0, 0), c(0, 0, exp(-1), 0), c(0, 0, 0, exp(-1)), c(0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0, 0), c(0, 0, exp(-1), 0), c(0, 0, 0, exp(-1)), c(0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0, 0), c(0, 0, exp(-1), 0), c(0, 0, 0, exp(-2)), c(0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0, 0), c(0, 0, exp(-1), 0), c(0, 0, 0, exp(-2)), c(0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0, 0), c(0, 0, exp(-2), 0), c(0, 0, 0, exp(-1)), c(0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-1), 0, 0), c(0, 0, exp(-2), 0), c(0, 0, 0, exp(-1)), c(0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, 0), c(0, 0, exp(-1), 0), c(0, 0, 0, exp(-1)), c(0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, 0), c(0, 0, exp(-1), 0), c(0, 0, 0, exp(-1)), c(0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, 0), c(0, 0, exp(-1), 0), c(0, 0, 0, exp(-3)), c(0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, 0), c(0, 0, exp(-1), 0), c(0, 0, 0, exp(-3)), c(0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) #13569 (four.q <- fixq(rbind(c(0, exp(-3), 0, exp(-3)), c(0, 0, exp(-3), exp(-3)), c(0, 0, 0, exp(-3)), c(0,0,0,0)))) set.seed(22061976) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=four.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, exp(-2)), c(0, 0, exp(-2), exp(-2)), c(0, 0, 0, 2*exp(-2)), c(0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, exp(-2)), c(0, 0, exp(-2), exp(-2)), c(0, 0, 0, 2*exp(-2)), c(0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik, tol=1e-06) ## no convergence with analytic, in 1.2 or 1.3, but matches with fixed (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, exp(-2)), c(0, 0, exp(-2), exp(-2)), c(0, 0, 0, exp(-2)), c(0,0,0,0)), fixedpars=FALSE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, exp(-2)), c(0, 0, exp(-2), exp(-2)), c(0, 0, 0, exp(-2)), c(0,0,0,0)), fixedpars=FALSE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, exp(-2)), c(0, 0, exp(-3), exp(-3)), c(0, 0, 0, 2*exp(-2)), c(0,0,0,0)), fixedpars=FALSE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, exp(-2)), c(0, 0, exp(-3), exp(-3)), c(0, 0, 0, 2*exp(-2)), c(0,0,0,0)), fixedpars=FALSE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-3), 0, exp(-3)), c(0, 0, exp(-2), exp(-2)), c(0, 0, 0, 2*exp(-2)), c(0,0,0,0)), fixedpars=FALSE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-3), 0, exp(-3)), c(0, 0, exp(-2), exp(-2)), c(0, 0, 0, 2*exp(-2)), c(0,0,0,0)), fixedpars=FALSE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, exp(-2)), c(0, 0, exp(-3), exp(-3)), c(0, 0, 0, exp(-2)), c(0,0,0,0)), fixedpars=FALSE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0, exp(-2), 0, exp(-2)), c(0, 0, exp(-3), exp(-3)), c(0, 0, 0, exp(-2)), c(0,0,0,0)), fixedpars=FALSE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) }) ## FIVE STATES #1_6_11_16 test_that("5 state analytic P matrices",{ (five.q <- fixq(rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)))) set.seed(22061976) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=five.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),0,0), c(0,0,0,exp(-4),0), c(0,0,0,0,exp(-5)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),0,0), c(0,0,0,exp(-4),0), c(0,0,0,0,exp(-5)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-3),0), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-3),0), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),0,0), c(0,0,0,exp(-4),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),0,0), c(0,0,0,exp(-4),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-4),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-4),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-4),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-4),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-3)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-3)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-3),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-3),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),0,0), c(0,0,0,exp(-2),0), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) #1_4_6_8_11_12_16 (five.q <- fixq(rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,exp(-2)), c(0,0,0,0,0)))) set.seed(22061976) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=five.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-3),0,exp(-3)), c(0,0,0,exp(-4),exp(-4)), c(0,0,0,0,exp(-5)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-3),0,exp(-3)), c(0,0,0,exp(-4),exp(-4)), c(0,0,0,0,exp(-5)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-3),exp(-3)), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-3),exp(-3)), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-3),0,exp(-3)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-3),0,exp(-3)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-3),0,exp(-3)), c(0,0,0,exp(-4),exp(-4)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-3),0,exp(-3)), c(0,0,0,exp(-4),exp(-4)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,exp(-3)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,exp(-3)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,exp(-4)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,exp(-3)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-4),exp(-4)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,exp(-3)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-4),exp(-4)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,exp(-3)), c(0,0,exp(-4),0,exp(-4)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,exp(-3)), c(0,0,exp(-4),0,exp(-4)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,exp(-3)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,exp(-3)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-3),exp(-3)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-3),exp(-3)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-3),0,exp(-3)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-3),0,exp(-3)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,exp(-3)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,exp(-3)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,exp(-2)), c(0,0,exp(-2),0,exp(-2)), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,2*exp(-2)), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) #1_6_7_11_12 (five.q <- fixq(rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),exp(-2),0), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,0), c(0,0,0,0,0)))) set.seed(22061976) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=five.q) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),exp(-3),0), c(0,0,0,exp(-4),exp(-4)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-3),exp(-3),0), c(0,0,0,exp(-4),exp(-4)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,2*exp(-2),0,0,0), c(0,0,exp(-2),exp(-2),0), c(0,0,0,exp(-3),exp(-3)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,2*exp(-2),0,0,0), c(0,0,exp(-2),exp(-2),0), c(0,0,0,exp(-3),exp(-3)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,2*exp(-2),0,0,0), c(0,0,exp(-3),exp(-3),0), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,2*exp(-2),0,0,0), c(0,0,exp(-3),exp(-3),0), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-2),exp(-2),0), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-3),0,0,0), c(0,0,exp(-2),exp(-2),0), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) (sim.mod1 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),exp(-2),0), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=TRUE)) (sim.mod2 <- msm(state ~ time, subject=subject, data=sim2.df, qmatrix = rbind(c(0,exp(-2),0,0,0), c(0,0,exp(-2),exp(-2),0), c(0,0,0,exp(-2),exp(-2)), c(0,0,0,0,0), c(0,0,0,0,0)), fixedpars=TRUE, analyticp=FALSE)) expect_equal(sim.mod1$minus2loglik, sim.mod2$minus2loglik) }) msm/tests/testthat/test_models_hmm.r0000644000176200001440000002420013051600620017405 0ustar liggesuserscontext("Hidden Markov model likelihoods") three.q <- rbind(c(0, exp(-6), exp(-9)), c(0, 0, exp(-6)), c(0, 0, 0)) four.q <- rbind(c(0, exp(-6), 0, exp(-9)), c(0, 0, exp(-6.01), exp(-9)), c(0, 0, 0, exp(-6.02)), c(0, 0, 0, 0)) five.q <- rbind(c(0, exp(-6), 0, 0, exp(-9)), c(0, 0, exp(-6.01), 0, exp(-9)), c(0, 0, 0, exp(-6.02), exp(-6.03)), c(0, 0, 0, 0, exp(-6.04)), c(0, 0, 0, 0, 0)) hmodel3 <- list(hmmNorm(mean=100, sd=16), hmmNorm(mean=54, sd=18), hmmIdent(999)) hmodel4 <- list(hmmNorm(mean=100, sd=16), hmmNorm(mean=72.5, sd=10), hmmNorm(mean=42.5, sd=18), hmmIdent(999)) hmodel5 <- list(hmmNorm(mean=100, sd=16), hmmNorm(mean=72.5, sd=10), hmmNorm(mean=62.5, sd=10), hmmNorm(mean=42.5, sd=18), hmmIdent(999)) test_that("HMM normal likelihoods: FEV data",{ (fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, fixedpars=TRUE)) expect_equal(52388.7381942858, fev3.hid$minus2loglik, tol=1e-06) (fev4.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=four.q, deathexact=4, hmodel=hmodel4, fixedpars=TRUE)) expect_equal(50223.9497625937, fev4.hid$minus2loglik, tol=1e-06) (fev5.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=five.q, deathexact=5, hmodel=hmodel5, fixedpars=TRUE)) expect_equal(49937.9840668066, fev5.hid$minus2loglik, tol=1e-06) }) test_that("HMM with obstrue",{ fev$obstrue <- as.numeric(fev$fev==999) fev$fev2 <- fev$fev; fev$fev2[fev$obstrue==1] <- 3 hmodel32 <- list(hmmNorm(mean=100, sd=16), hmmNorm(mean=54, sd=18), hmmIdent(3)) (fev3.hid <- msm(fev2 ~ days, subject=ptnum, obstrue=obstrue, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel32, fixedpars=TRUE)) expect_equal(52388.7381942858, fev3.hid$minus2loglik, tol=1e-06) fev$obstrue <- "foo" expect_error(fev3.hid <- msm(fev2 ~ days, subject=ptnum, obstrue=obstrue, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel32, fixedpars=TRUE), "obstrue should be logical or numeric") fev$obstrue <- as.numeric(fev$fev==999); fev$obstrue[1] <- 10 expect_error(fev3.hid <- msm(fev2 ~ days, subject=ptnum, obstrue=obstrue, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel32, fixedpars=TRUE), "Interpreting \"obstrue\" as containing true states, but it contains values not in 0,1,...,3") ## can supply true state in obstrue fev$obstrue <- as.numeric(fev$fev==999); fev$obstrue[fev$obstrue==1] <- 3 fev3.hid <- msm(fev2 ~ days, subject=ptnum, obstrue=obstrue, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel32, fixedpars=TRUE) expect_equal(52388.7381942858, fev3.hid$minus2loglik, tol=1e-06) }) test_that("HMM normal likelihoods: FEV data: covariate on outcome",{ (fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, hcovariates=list(~acute, ~acute, NULL), hcovinits = list(-8, -8, NULL), hconstraint = list(acute = c(1,1)), fixedpars=TRUE, center=FALSE)) expect_equal(52134.2372359988, fev3.hid$minus2loglik, tol=1e-06) (fev4.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=four.q, deathexact=4, hmodel=hmodel4, hcovariates=list(~acute, ~acute, ~acute, NULL), hcovinits = list(-8, -8, -8, NULL), hconstraint = list(acute = c(1,1,1)), fixedpars=TRUE, center=FALSE)) expect_equal(50095.8606697016, fev4.hid$minus2loglik, tol=1e-06) (fev5.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=five.q, deathexact=5, hmodel=hmodel5, hcovariates=list(~acute, ~acute, ~acute, ~acute, NULL), hcovinits = list(-8, -8, -8, -8, NULL), hconstraint = list(acute = c(1,1,1,1)), fixedpars=TRUE, center=FALSE)) expect_equal(49839.1627881087, fev5.hid$minus2loglik, tol=1e-06) }) context("Hidden Markov model error handling") test_that("errors in hmodel",{ ## hmodel with wrong named parameters expect_error( hmodel3 <- list(hmmMETNorm(mean=100, sd=16, splat=8, lower=80, upper=Inf, meanerr=0), hmmMETNorm(mean=54, sd=18, sderr=8, lower=0, upper=80, meanerr=0), hmmIdent(999)), "unused argument \\(splat" ) ## hmodel with extra unnamed parameter expect_error( hmodel3 <- list(hmmMETNorm(mean=100, sd=16, sderr=8, lower=80, upper=Inf, meanerr=0), hmmMETNorm(mean=54, sd=18, sderr=8, lower=0, upper=80, meanerr=0), hmmIdent(999, 3)), "unused argument \\(3" ) ## hmodel with parameters unnamed, but correct number - OK. hmodel.OK <- list(hmmMETNorm(100, 16, 8, 80, Inf, 0), hmmMETNorm(mean=54, sd=18, sderr=8, lower=0, upper=80, meanerr=0), hmmIdent(999)) ## hmodel with too few parameters (named or unnamed) expect_error( hmodel3 <- list(hmmMETNorm(100, 16, 80, Inf), hmmMETNorm(mean=54, sd=18, sderr=8, lower=0, upper=80, meanerr=0), hmmIdent(999)), "Parameter sderr for hmmMETNorm not supplied" ) ### Initial values for certain parameters in wrong ranges. hmodel3 <- list(hmmMETNorm(mean=100, sd=-16, sderr=8, lower=80, upper=Inf, meanerr=0), hmmMETNorm(mean=54, sd=18, sderr=8, lower=0, upper=80, meanerr=0), hmmIdent(999)) expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, fixedpars=1:9), "Initial value -16 of parameter \"sd\" outside allowed range") expect_error( hmodel3 <- list(hmmMETNorm(mean=100, sd=16, sderr="splat", lower=80, upper=Inf, meanerr=0), hmmMETNorm(mean=54, sd=18, sderr=8, lower=0, upper=80, meanerr=0), hmmIdent(999)), "Expected numeric values" ) expect_error( hmodel3 <- list( hmmBinom(size=0.1, prob=0.5), hmmCat(prob=c(0.1, 0.8, 0.1, 0)), hmmCat(prob=c(0, 0.1, 0.9, 0)), hmmIdent()), "Value of size should be integer") }) test_that("error handling in HMM fits",{ hmodel3 <- list(hmmMETNorm(mean=100, sd=16, sderr=8, lower=80, upper=Inf, meanerr=0), hmmMETNorm(mean=54, sd=18, sderr=8, lower=0, upper=80, meanerr=0), hmmIdent(999)) hmodel4 <- list(hmmMETNorm(mean=100, sd=16, sderr=8, lower=80, upper=Inf, meanerr=0), hmmMEUnif(sderr=8, lower=65, upper=80, meanerr=0), hmmMETNorm(mean=54, sd=18, sderr=8, lower=0, upper=65, meanerr=0), hmmIdent(999)) hmodel5 <- list(hmmMETNorm(mean=100, sd=16, sderr=8, lower=80, upper=Inf, meanerr=0), hmmMEUnif(sderr=8, lower=65, upper=80, meanerr=0), hmmMEUnif(sderr=8, lower=50, upper=65, meanerr=0), hmmMETNorm(mean=42, sd=18, sderr=8, lower=0, upper=50, meanerr=0), hmmIdent(999)) ### Wrong number of states in the hmodel, versus the qmatrix. expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel4, fixedpars=1:9), "hmodel of length 4") ### Rubbish in hmodel list hmodel.rubbish <- list("should be a ", " list of ", "hmodel objects") expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel.rubbish, fixedpars=1:9), "hmodel should be a list of HMM distribution objects") ## Death state wrong (not HMM-specific error, but no harm putting it in this file anyway) expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=10, hmodel=hmodel3, fixedpars=1:9), "Exact death states indicator contains states not in 1, 2, 3") ## Covariate list of wrong length expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, hcovariates=list(~acute, ~acute), hcovinits = list(-8, -8, NULL),), "hcovariates of length 2, expected 3") ## Covariate list has rubbish in it expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, hcovariates=list("should be formulae", "rubbish", NULL), hcovinits = list(-8, -8, NULL)), "hcovariates should be a list of formulae or NULLs") ## Covariates not in the data expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, hcovariates=list(~acute, ~nonexistent, NULL), hcovinits = list(-8, -8, NULL)), "object .+ not found") ## Covariate inits of wrong length (just warning, ignores) expect_warning(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, hcovariates=list(~acute, ~acute, NULL), hcovinits = list(-8, -8, -8), fixedpars=TRUE), "Initial values for hidden covariate effects do not match numbers of covariates") ## Rubbish in hcovinits (just warning, ignores) expect_warning(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3,hcovariates=list(~acute, ~acute, NULL), hcovinits = list("fooo", -8, NULL), fixedpars=TRUE), "hcovinits should be numeric") ## hconstraint has unknown parameters expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, hcovariates=list(~acute, ~acute, NULL), hcovinits = list(-8, -8, NULL), hconstraint = list(nonexistent = c(1,1), acute = c(1,1))), "parameter .+ in hconstraint unknown") ## hconstraint has rubbish in (note character vectors are allowed) expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, hcovariates=list(~acute, ~acute, NULL), hcovinits = list(-8, -8, NULL), hconstraint = list("rubbish", acute = c(1,1))), "parameter .+ in hconstraint unknown") expect_error(fev3.hid <- msm(fev ~ days, subject=ptnum, data=fev, qmatrix=three.q, deathexact=3, hmodel=hmodel3, hcovariates=list(~acute, ~acute, NULL), hcovinits = list(-8, -8, NULL), hconstraint = list(sderr=c("wrong length"), acute = c(1,1))), "constraint for \"sderr\" of length 1, should be 2") }) msm/tests/testthat/test_models_misc.r0000644000176200001440000002044514060677057017611 0ustar liggesuserscontext("msm misclassification model likelihoods") test_that("cav misclassification model with no covariates",{ misc.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, fixedpars=TRUE) expect_equal(4296.9155995778, misc.msm$minus2loglik, tol=1e-06) miscnew.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, deathexact = 4, fixedpars=TRUE, hmodel=list( hmmCat(prob=c(0.9, 0.1, 0, 0)), hmmCat(prob=c(0.1, 0.8, 0.1, 0)), hmmCat(prob=c(0, 0.1, 0.9, 0)), hmmIdent()) ) expect_equal(miscnew.msm$minus2loglik, misc.msm$minus2loglik) }) test_that("cav misclassification model with covariates on transition rates",{ misccov.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, fixedpars = TRUE, covariates = ~ sex, covinits=list(sex=rep(0.1, 5))) expect_equal(4299.38058878142, misccov.msm$minus2loglik, tol=1e-06) }) test_that("cav misclassification model with covariates on misclassification probabilities",{ misccov.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, fixedpars=TRUE, misccovariates = ~dage + sex, misccovinits = list(dage=c(0.01,0.02,0.03,0.04), sex=c(-0.013,-0.014,-0.015,-0.016))) expect_equal(4306.3077053482, misccov.msm$minus2loglik, tol=1e-06) misccovnew.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, deathexact = 4, fixedpars=TRUE, center=TRUE, hmodel=list( hmmCat(prob=c(0.9, 0.1, 0, 0)), hmmCat(prob=c(0.1, 0.8, 0.1, 0)), hmmCat(prob=c(0, 0.1, 0.9, 0)), hmmIdent()), hcovariates=list(~dage + sex, ~dage + sex, ~dage + sex, ~1), hcovinits = list(c(0.01,-0.013), c(0.02,-0.014,0.03,-0.015), c(0.04,-0.016), NULL) ) expect_equal(misccov.msm$minus2loglik, misccovnew.msm$minus2loglik, tol=1e-06) }) test_that("misclassification model with no misclassification reduces to simple",{ nomisc.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = twoway4.q, ematrix=matrix(0, nrow=4, ncol=4), deathexact = 4, fixedpars=TRUE) simple.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = twoway4.q, deathexact = 4, fixedpars=TRUE) expect_equal(nomisc.msm$minus2loglik, simple.msm$minus2loglik) }) test_that("misclassification model with obstrue",{ misc.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, fixedpars=TRUE, obstrue=firstobs) expect_equal(4165.84711809003, misc.msm$minus2loglik, tol=1e-06) }) test_that("misclassification model with exact times",{ miscexact.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, exacttimes=TRUE, fixedpars=TRUE) expect_equal(4864.14764195147, miscexact.msm$minus2loglik, tol=1e-06) }) test_that("misclassification model with initprobs",{ miscinits.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, initprobs=c(0.7, 0.1, 0.1, 0.1), fixedpars=TRUE) expect_equal(4725.9078185031, miscinits.msm$minus2loglik, tol=1e-06) }) test_that("misclassification model with est.initprobs",{ expect_error({ miscinits.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, initprobs=c(0.8, 0.1, 0.1, 0), est.initprobs=TRUE, method="BFGS", control=list(fnscale=4000, maxit=10000), fixedpars=1:9) miscinits.msm }, NA) }) test_that("misclassification model with censoring",{ misccens.msm <- msm(state ~ years, subject = PTNUM, data = cav.cens, qmatrix = oneway4.q, ematrix=ematrix, deathexact=TRUE, censor=99, fixedpars=TRUE) expect_equal(4025.42265024404, misccens.msm$minus2loglik, tol=1e-06) }) test_that("misclassification model with two types of censoring",{ misccens.msm <- msm(state ~ years, subject=PTNUM, data=cav.cens2, qmatrix=oneway4.q, ematrix=ematrix, censor=c(99, 999), deathexact=4, censor.states=list(c(1,2,3), c(2,3)), fixedpars=TRUE) expect_equal(3811.69640533587, misccens.msm$minus2loglik, tol=1e-06) cav.cens2$obstrue <- as.numeric(cav.cens2$state %in% c(999)) misccens.msm <- msm(state ~ years, subject=PTNUM, data=cav.cens2, qmatrix=oneway4.q, ematrix=ematrix, censor=c(99, 999), deathexact=4, obstrue=obstrue, censor.states=list(c(1,2,3), c(2,3)), fixedpars=TRUE) expect_equal(3822.04540210944, misccens.msm$minus2loglik, tol=1e-06) }) test_that("misclassification model with no misclassification reduces to simple, with censoring",{ misc.msm <- msm(state ~ years, subject = PTNUM, data = cav.cens, qmatrix = twoway4.q, ematrix=matrix(0, nrow=4, ncol=4), censor=99, deathexact=TRUE, fixedpars=TRUE) simple.msm <- msm(state ~ years, subject = PTNUM, data = cav.cens, qmatrix = twoway4.q, deathexact=TRUE, censor=99, fixedpars=TRUE) expect_equal(misc.msm$minus2loglik, simple.msm$minus2loglik, tol=1e-06) misc.msm <- msm(state ~ years, subject = PTNUM, data = cav.cens, qmatrix = twoway4.q, ematrix=matrix(0, nrow=4, ncol=4), censor=99, fixedpars=TRUE) simple.msm <- msm(state ~ years, subject = PTNUM, data = cav.cens, qmatrix = twoway4.q, censor=99, fixedpars=TRUE) expect_equal(misc.msm$minus2loglik, simple.msm$minus2loglik, tol=1e-06) }) test_that("misclassification model with no misclassification reduces to simple, using hmmCat",{ miscnew.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = twoway4.q, hmodel=list(hmmCat(prob=c(1, 0, 0, 0)), hmmCat(prob=c(0, 1, 0, 0)), hmmCat(prob=c(0, 0, 1, 0)), hmmIdent()), fixedpars=TRUE) simple.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = twoway4.q, fixedpars=TRUE) expect_equal(miscnew.msm$minus2loglik, simple.msm$minus2loglik, tol=1e-06) }) test_that("can't mix ematrix and hcovariates",{ expect_error( misccov.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, fixedpars=1:17, hcovariates=list(~dage + sex, ~dage + sex, ~dage + sex, ~1), hcovinits = list(c(0.01,0.013), c(0.01,0.013,0.01,0.013), c(0.01,0.013), NULL) ), "hcovariates have been specified, but no hmodel") }) test_that("data inconsistent with initprobs/ematrix",{ cav2 <- cav cav2$state[c(1,8)] <- 3 expect_warning(msm(state ~ years, subject = PTNUM, data = cav2, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, fixedpars=TRUE), "First observation .+ is impossible") }) test_that("various errors",{ wrong.e <- "foo" expect_error(misc.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=wrong.e, deathexact = 4, fixedpars=TRUE),"ematrix should be a numeric matrix") wrong.e <- 1 expect_error(misc.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=wrong.e, deathexact = 4, fixedpars=TRUE),"ematrix should be a numeric matrix") wrong.e <- cbind(c(0,1,2), c(0,1,2)) expect_error(misc.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=wrong.e, deathexact = 4, fixedpars=TRUE),"Number of rows and columns of ematrix should be equal") wrong.e <- cbind(c(0,1), c(0,2)) expect_error(misc.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=wrong.e, deathexact = 4, fixedpars=TRUE),"Dimensions of qmatrix and ematrix should be the same") expect_warning(msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, fixedpars=TRUE, gen.inits=TRUE), "gen.inits not supported for hidden Markov models, ignoring") }) msm/tests/testthat/test_utils.r0000644000176200001440000001504113443747375016454 0ustar liggesuserscontext("Distribution functions and utilities") test_that("MatrixExp",{ A <- matrix(c(-0.11, 0.01, 0.001, 0.2, -0.2, 0, 0, 0, 0), nrow=3, byrow=TRUE) me <- MatrixExp(A, method="pade") res <- c(0.896703832431769, 0.171397960992687, 0, 0.00856989804963433, 0.81957474998506, 0, 0.00094726269518597, 9.0272890222537e-05, 1) expect_equal(res, as.numeric(me), tol=1e-06) me <- MatrixExp(A, method="series") expect_equal(res, as.numeric(me), tol=1e-06) ev <- eigen(A) me2 <- ev$vectors %*% diag(exp(ev$values)) %*% solve(ev$vectors) expect_equal(me2, me, tol=1e-06) }) test_that("truncated normal",{ suppressWarnings(RNGversion("3.5.0")) set.seed(220676) rl <- rnorm(10) expect_equal(dtnorm(rl), dnorm(rl), tol=1e-06) expect_equal(dtnorm(rl, mean=2, sd=1.2), dnorm(rl, mean=2, sd=1.2), tol=1e-06) d <- dtnorm(rl, mean=2, sd=1.2, lower=seq(-4,5)) expect_equal(c(0.260110259383406, 0.108097895222820, 0.0558659556833655, 0.160829438765247, 0.343919966894772, 0, 0, 0, 0, 0), d, tol=1e-06) expect_equal(c(0, 0.5, 1), ptnorm(c(-1000, 0, 1000)), tol=1e-06) expect_equal(c(0.139068959153926, 0, 0.156451685781240), ptnorm(c(-1, 0, 1), mean=c(0,1,2), sd=c(1,2,3), lower=c(-2,1,0)), tol=1e-06) expect_equal(rl, qtnorm(ptnorm(rl)), tol=1e-03) expect_warning(qtnorm(c(-1, 0, 1, 2)), "NaN") expect_warning(qtnorm(c(-1, 0, 1, 2),lower=-1,upper=1), "NaN") expect_equal(rl, qtnorm(ptnorm(rl, mean=1:10), mean=1:10)) ## NA handling in rtnorm expect_warning(rtnorm(3, mean=c(1, NA, 0)), "NAs produced") expect_warning(res <- rtnorm(3, sd=c(1, NA, 1), lower=c(NA, 0, 2)), "NAs produced") expect_equal(res[1:2], c(NaN, NaN)) }) test_that("Measurement error distributions: normal",{ expect_equal(dnorm(2), dmenorm(2), tol=1e-06) expect_equal(dnorm(2, log=TRUE), dmenorm(2, log=TRUE), tol=1e-06) expect_equal(c(0.0539909665131881, 0.241970724519143, 0.398942280401433), dmenorm(c(-2, 0, 2), mean=c(0,1,2)), tol=1e-06) expect_equal(c(0.119536494085260, 0.120031723608082, 0.0967922982964366), dmenorm(c(-2, 0, 2), mean=c(0,1,2), lower=c(-3,-2,-1), sderr=c(2,3,4)), tol=1e-06) expect_equal(pmenorm(c(-2, 0, 2)), pnorm(c(-2, 0, 2)), tol=1e-06) expect_equal(pmenorm(c(-2, 0, 2), log.p=TRUE), pnorm(c(-2, 0, 2), log.p=TRUE), tol=1e-06) expect_equal(pmenorm(c(-2, 0, 2), lower.tail=FALSE), pnorm(c(-2, 0, 2), lower.tail=FALSE), tol=1e-06) expect_equal(c(0.347443301205908, 0.500000000140865, 0.652556698813763), pmenorm(c(-2, 0, 2), sderr=5), tol=1e-06) expect_equal(c(0.00930146266876999, 0.0249300921973760, 0.0583322325986182), pmenorm(c(-2, 0, 2), sderr=5, meanerr=10), tol=1e-06) expect_equal(qmenorm(pmenorm(c(-2, 0, 2), sderr=5, lower=0), sderr=5, lower=0), qmenorm(pmenorm(c(-2, 0, 2))), tol=1e-03) }) test_that("Measurement error distributions: uniform",{ expect_equal(c(0,1,1,0,0), dmeunif(c(-2, 0, 0.7, 1, 2))) expect_equal(dunif(c(-2, 0, 0.7, 1, 2), min=-3:1, max=4:8), dmeunif(c(-2, 0, 0.7, 1, 2), lower=-3:1, upper=4:8), tol=1e-06) expect_equal(c(0.120192106440279, 0.139607083057178, 0.136490639905731, 0.120192106440279, 0.120192106440279), dmeunif(c(-2, 0, 0.7, 1, 2), lower=-3:1, upper=4:8, sderr=1), tol=1e-06) expect_equal(pmeunif(c(0.1, 0.5, 0.9)), punif(c(0.1, 0.5, 0.9)), tol=1e-04) expect_equal(c(0.468171571157871, 0.500000000120507, 0.531828429094026), pmeunif(c(0.1, 0.5, 0.9), sderr=5), tol=1e-06) expect_equal(c(0.0189218497312070, 0.0229301821964305, 0.0276311076816442), pmeunif(c(0.1, 0.5, 0.9), sderr=5, meanerr=10), tol=1e-06) expect_equal(c(0.1, 0.5, 0.9), qmeunif(pmeunif(c(0.1, 0.5, 0.9), sderr=5, lower=-1), sderr=5, lower=-1), tol=1e-03) expect_equal(c(0.1, 0.5, 0.9), qmeunif(pmeunif(c(0.1, 0.5, 0.9))), tol=1e-03) }) test_that("Exponential distribution with piecewise constant hazard",{ expect_equal(1, integrate(dpexp, 0, Inf)$value) rate <- c(0.1, 0.2, 0.05, 0.3) t <- c(0, 10, 20, 30) expect_equal(1, integrate(dpexp, 0, Inf, rate=rate, t=t)$value, tol=1e-04) x <- rexp(10) expect_equal(dpexp(x), dexp(x)) expect_equal(dpexp(x, log=TRUE), log(dpexp(x))) expect_equal(dpexp(x, log=TRUE), dexp(x, log=TRUE)) stopifnot(ppexp(-5) == 0) stopifnot(ppexp(0) == 0) stopifnot(ppexp(Inf) == 1) set.seed(22061976) q <- rexp(10) expect_equal(pexp(q), ppexp(q)) expect_equal(pexp(q, log.p=TRUE), ppexp(q, log.p=TRUE)) rate <- c(0.1, 0.2, 0.05, 0.3) t <- c(0, 10, 20, 30) stopifnot(ppexp(-5, rate, t) == 0) stopifnot(ppexp(0, rate, t) == 0) expect_equal(1, ppexp(Inf, rate, t)) expect_equal(1, ppexp(9999999, rate, t)) expect_equal(pexp(c(5, 6, 7), rate[1]), ppexp(c(5, 6, 7), rate, t)) expect_error(ppexp(q, rate=c(1,2,3), t=c(1,2)),"length of t must be equal to length of rate") expect_warning(ppexp(q, rate=-4),"NaN") expect_error(ppexp(q, rate=c(1,2,3), t=c(-1, 4, 6)), "first element of t should be 0") set.seed(22061976) p <- runif(10) expect_equal(qpexp(p), qexp(p), tol=1e-03) expect_equal(qpexp(p, lower.tail=FALSE), qexp(p, lower.tail=FALSE), tol=1e-03) expect_equal(qpexp(log(p), log.p=TRUE), qexp(log(p), log.p=TRUE), tol=1e-03) expect_equal(p, ppexp(qpexp(p)), tol=1e-03) set.seed(22061976) q <- rexp(10) expect_equal(q, qpexp(ppexp(q)), tol=1e-03) ## "special" argument to qgeneric r <- c(0.3,0.6,0.8,1.3) t <- c(0,2,3,5) expect_equal(qpexp(p = c(0.1,0.5,0.9,1) , rate=r, t=t), c(qpexp(p=0.1, rate=r, t=t), qpexp(p=0.5, rate=r, t=t), qpexp(p=0.9, rate=r, t=t), qpexp(p=1, rate=r, t=t))) expect_error(qpexp(p=0.1, rate=r, t=t[-1]), "length of t must be equal to length of rate") expect_error(qpexp(p=0.1, rate=r, t=c(0.1, t[-1])), "first element of t should be 0") set.seed(220676) rt <- rpexp(10) set.seed(220676) r <- rexp(10) expect_equal(rt, r, tol=1e-06) }) test_that("deltamethod",{ ## Example in help(deltamethod) ## Simple linear regression, E(y) = alpha + beta x x <- 1:100 suppressWarnings(RNGversion("3.5.0")) set.seed(220676) y <- rnorm(100, 4*x, 5) toy.lm <- lm(y ~ x) (estmean <- coef(toy.lm)) (estvar <- summary(toy.lm)$cov.unscaled * summary(toy.lm)$sigma^2) ## Estimate of (1 / (alphahat + betahat)) expect_equal(0.206982798128202, as.numeric(1 / (estmean[1] + estmean[2]))) ## Approximate standard error expect_equal(0.0396485739892983, deltamethod(~ 1 / (x1 + x2), estmean, estvar)) estvar2 <- estvar; estvar2[1,2] <- Inf expect_equal(deltamethod(~ 1 / (x1 + x2), estmean, estvar2), Inf) }) msm/tests/testthat/test_models.r0000644000176200001440000013616414060676731016602 0ustar liggesuserscontext("msm simple model likelihoods") test_that("simple model, death",{ cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE, method="BFGS", control=list(trace=5, REPORT=1)) expect_equal(4908.81676837903, cav.msm$minus2loglik) }) test_that("simple model, no death",{ cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = FALSE, fixedpars=TRUE) expect_equal(4833.00640639644, cav.msm$minus2loglik) }) test_that("simple model, covariates",{ cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE, covariates = ~ sex, covinits = list(sex=rep(0.01, 7))) expect_equal(4909.17147259115, cav.msm$minus2loglik) }) test_that("autogenerated inits reproduce crudeinits",{ cinits <- crudeinits.msm(state ~ years, PTNUM, data=cav, qmatrix=twoway4.q) expect_equal(msm( state ~ years, subject=PTNUM, data = cav, qmatrix = cinits, deathexact = TRUE, fixedpars=TRUE)$minus2loglik, msm( state ~ years, subject=PTNUM, data = cav, qmatrix=twoway4.i, gen.inits=TRUE, deathexact = TRUE, fixedpars=TRUE)$minus2loglik) }) test_that("data as global variables",{ state.g <- cav$state; time.g <- cav$years; subj.g <- cav$PTNUM cav.msm <- msm(state.g ~ time.g, subject=subj.g, qmatrix = twoway4.i, gen.inits=TRUE, fixedpars=TRUE) expect_equal(4119.9736299032, cav.msm$minus2loglik) }) psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), control=list(fnscale=1)) test_that("psor model: covariates, constraints",{ expect_equal(1114.89946121717, psor.msm$minus2loglik, tol=1e-06) expect_equal(0.0959350004999946, psor.msm$Qmatrices$baseline[1,2], tol=1e-06) expect_equal(exp(psor.msm$Qmatrices$logbaseline[c(5,10,15)]), psor.msm$Qmatrices$baseline[c(5,10,15)], tol=1e-06) }) test_that("psor model: transition-specific covariates",{ psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.q, covariates = list("2-3"=~ollwsdrt, "3-4"=~hieffusn), control=list(fnscale=1)) expect_equal(hazard.msm(psor.msm)$ollwsdrt["State 1 - State 2","HR"], 1) expect_equal(hazard.msm(psor.msm)$hieffusn["State 2 - State 3","HR"], 1) }) test_that("psor model: transition-specific covariates with pci",{ psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.q, covariates = list("2-3"=~ollwsdrt, "3-4"=~hieffusn), pci = 10, fixedpars=7:8, control=list(fnscale=1)) h <- hazard.msm(psor.msm) expect_equal(h$ollwsdrt["State 1 - State 2","HR"], 1) expect_equal(h$hieffusn["State 1 - State 2","HR"], 1) expect_true(!isTRUE(all.equal(h$"timeperiod[10,Inf)"["State 1 - State 2","HR"], 1))) expect_equal(h$"timeperiod[10,Inf)"["State 2 - State 3","HR"], 1) expect_equal(h$"timeperiod[10,Inf)"["State 3 - State 4","HR"], 1) }) psor.nocen.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), center=FALSE) test_that("no covariate centering",{ expect_equal(exp(psor.nocen.msm$Qmatrices$logbaseline[c(5,10,15)]), psor.nocen.msm$Qmatrices$baseline[c(5,10,15)], tol=1e-06) }) test_that("gen.inits with missing values for state / time",{ psor2 <- psor; psor2$ptnum[13:14] <- psor2$months[7:8] <- psor2$state[7:8] <- NA psor2.msm <- msm(state ~ months, subject=ptnum, data=psor2, gen.inits=TRUE, qmatrix = psor.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), fixedpars=TRUE) expect_equal(1179.95441284169, psor2.msm$minus2loglik, tol=1e-06) }) test_that("exact transition times using exacttimes",{ msmtest5 <- msm(state ~ time, qmatrix = fiveq, subject = ptnum, data = bos, exacttimes=TRUE, fixedpars=TRUE) expect_equal(3057.85781916437, msmtest5$minus2loglik, tol=1e-06) }) test_that("exact transition times using obstype vector of all 2",{ msmtest5 <- msm(state ~ time, qmatrix = fiveq, subject = ptnum, data = bos, obstype=rep(2, nrow(bos)), fixedpars=TRUE) expect_equal(3057.85781916437, msmtest5$minus2loglik, tol=1e-06) }) test_that("exact transition times with death, should be same",{ expect_warning(msmtested <- msm(state ~ time, qmatrix = fiveq, subject = ptnum, data = bos, deathexact=5, obstype=rep(2, nrow(bos)), exacttimes=TRUE, fixedpars=TRUE), "Ignoring death") expect_equal(3057.85781916437, msmtested$minus2loglik, tol=1e-06) (msmtest5 <- msm(state ~ time, qmatrix = fiveq, subject = ptnum, data = bos, deathexact=5, obstype=rep(2, nrow(bos)), fixedpars=TRUE)) # no warning, inconsistently expect_equal(3057.85781916437, msmtest5$minus2loglik, tol=1e-06) }) cav$statefac <- factor(cav$state) cav$statefac2 <- factor(cav$state, labels=c("none","mild","severe","death")) test_that("factors as states, death",{ cav.msm <- msm( statefac ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE, method="BFGS", control=list(trace=5, REPORT=1)) expect_equal(4908.81676837903, cav.msm$minus2loglik) expect_error(msm( statefac2 ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE), "state variable should be numeric or a factor with ordinal numbers as levels") }) test_that("factor covariates with factor() in formula",{ ## Should be no need for users to do this. factors should already be identified as such in the data frame expect_warning(cavfaccov.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ factor(pdiag), covinits=list(sex=rep(0.1,7)), fixedpars=TRUE), "covariate .+ unknown") expect_equal(4793.30238295565, cavfaccov.msm$minus2loglik, tol=1e-06) cavfaccov.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ factor(pdiag), covinits=list("factor(pdiag)Hyper"=rep(0.1,7)), fixedpars=TRUE) expect_equal(4793.20440566637, cavfaccov.msm$minus2loglik, tol=1e-06) }) test_that("factors as global variables",{ state.g <- cav$state; time.g <- cav$years; subj.g <- cav$PTNUM; pdiag.g <- factor(cav$pdiag) cavfaccov.msm <- msm(state.g ~ time.g, subject=subj.g, qmatrix = twoway4.q, covariates = ~ pdiag.g, fixedpars=TRUE) expect_equal(4793.30238295565, cavfaccov.msm$minus2loglik, tol=1e-06) }) test_that("factor covariates using existing factors: inits are given to contrasts ",{ ## Warnings could be more informative here expect_warning(cavfaccov.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ pdiag, covinits=list(pdiag=rep(0.1,7)), fixedpars=TRUE), "covariate .+ unknown") expect_equal(4793.30238295565, cavfaccov.msm$minus2loglik, tol=1e-06) expect_warning(cavfaccov.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ pdiag, covinits=list(pdiagNonexistentlevel=rep(0.1,7)), fixedpars=TRUE), "covariate .+ unknown") expect_equal(4793.30238295565, cavfaccov.msm$minus2loglik, tol=1e-06) cavfaccov.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ pdiag, covinits=list(pdiagHyper=rep(0.1,7)), fixedpars=TRUE) expect_equal(4793.20440566637, cavfaccov.msm$minus2loglik, tol=1e-06) cavfaccov.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ pdiag, covinits=list(pdiagHyper=rep(0.1,7),pdiagIDC=rep(0.1,7),pdiagIHD=rep(0.1,7),pdiagOther=rep(0.1,7),pdiagRestr=rep(0.1,7)), fixedpars=TRUE) # OK expect_equal(4793.13035886505, cavfaccov.msm$minus2loglik, tol=1e-06) }) context("censored states") test_that("censored states: final state censored",{ cavcens.msm <- msm(state ~ years, subject=PTNUM, data=cav.cens, qmatrix=twoway4.q, censor=99, fixedpars=TRUE) expect_equal(4724.26606344485, cavcens.msm$minus2loglik, tol=1e-06) v <- viterbi.msm(cavcens.msm) expect_equal(v$observed[v$observed<10], v$fitted[v$observed<10]) expect_equal(v$fitted[v$observed==99][1], 3) }) test_that("two kinds of censoring",{ cavcens2.msm <- msm(state ~ years, subject=PTNUM, data=cav.cens2, qmatrix=twoway4.q, censor=c(99, 999), censor.states=list(c(1,2,3), c(2,3)), fixedpars=TRUE) expect_equal(4678.23348518727, cavcens2.msm$minus2loglik, tol=1e-06) v <- viterbi.msm(cavcens2.msm) expect_equal(v$observed[v$observed<10], v$fitted[v$observed<10]) expect_equal(v$fitted[v$observed==99][1], 3) }) test_that("intermediate state censored",{ cavcens3.msm <- msm(state ~ years, subject=PTNUM, data=cav.cens3, qmatrix=twoway4.q, censor=c(99, 999), censor.states=list(c(2,3), c(1,2,3)), fixedpars=TRUE) expect_equal(4680.66073438518, cavcens3.msm$minus2loglik, tol=1e-06) v <- viterbi.msm(cavcens3.msm) expect_equal(v$observed[v$observed<10], v$fitted[v$observed<10]) expect_true(all(v$fitted[v$observed==99] %in% 2:3)) expect_true(all(v$fitted[v$observed==999] %in% 1:3)) }) test_that("first state censored",{ cav.cens4 <- cav cav.cens4$state[c(1,8,12,22)] <- 99 cavcens4.msm <- msm(state ~ years, subject=PTNUM, data=cav.cens4, qmatrix=twoway4.q, censor=c(99), censor.states=list(c(2,3)), fixedpars=TRUE) expect_equal(4846.06045097812, cavcens4.msm$minus2loglik) v <- viterbi.msm(cavcens4.msm) expect_true(all(v$fitted[v$observed==99] %in% 2:3)) }) test_that("piecewise constant intensities with pci",{ cav5.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE, pci = c(5), covinits = list("timeperiod[5,Inf)"=rep(0.01,7)), ) expect_equal(4906.01423796805, cav5.msm$minus2loglik, tol=1e-06) cav10.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, pci = c(5,10), fixedpars=TRUE, covinits = list("timeperiod[5,10)"=rep(0.01,7), "timeperiod[10,Inf)"=rep(0.01,7)), ) expect_equal(4905.61646158639, cav10.msm$minus2loglik, tol=1e-06) }) test_that("piecewise constant intensities with pci, cut points outside data",{ ## Make sure works for pci outside time range, with warning expect_warning(cav5.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE, pci = c(-1,5,50,60), covinits = list("timeperiod[5,Inf)"=rep(0.01,7))), "cut point .+ less than") expect_warning(cav.pci.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE, pci = c(-1,50,60))) cav.msm <- msm( state ~ years, subject=PTNUM, data = cav,qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE) expect_equal(cav.pci.msm$minus2loglik, cav.msm$minus2loglik) # degrades to time-homogeneous if all cuts outside data }) suppressWarnings(RNGversion("3.5.0")) set.seed(22061976) cav$pdiag3 <- cav$pdiag cav$pdiag3[!cav$pdiag %in% c("IDC","IHD")] <- "Other" cav$pdiag3 <- factor(cav$pdiag3) subs <- cav$PTNUM %in% sample(unique(cav$PTNUM), 50) cavsub <- subset(cav, subs) cavsub$maxtime <- tapply(cavsub$years, cavsub$PTNUM, max)[as.character(cavsub$PTNUM)] cavsub.extra <- cavsub[cavsub$years==0 & cavsub$maxtime >= 5,] cavsub.extra$years <- 5 cavsub.extra$state <- 99 cavsub.extra10 <- cavsub[cavsub$years==0 & cavsub$maxtime >= 10,] cavsub.extra10$years <- 10 cavsub.extra10$state <- 999 cavsub2 <- rbind(cavsub, cavsub.extra, cavsub.extra10) cavsub2 <- cavsub2[order(cavsub2$PTNUM, cavsub2$years),] cavsub2$after5 <- ifelse(cavsub2$years>=5 & cavsub2$years<10, 1, 0) cavsub2$after10 <- ifelse(cavsub2$years>=10, 1, 0) cavsub2$after510 <- as.numeric(cavsub2$after5 | cavsub2$after10) test_that("piecewise constant intensities with pci, with other covariates",{ cav5cov.msm <- msm( state ~ years, subject=PTNUM, data = cavsub, qmatrix = twoway4.q, covariates = ~ pdiag3 + sex, deathexact = TRUE, pci = c(5,10), fixedpars=TRUE, covinits = list("timeperiod[5,10)"=rep(0.01,7), "timeperiod[10,Inf)"=rep(0.01,7), pdiag3IHD=rep(0.01,7), pdiag3Other=rep(0.01,7)), ) expect_equal(448.122802051545, cav5cov.msm$minus2loglik, tol=1e-06) cav5cov.msm <- msm( state ~ years, subject=PTNUM, data = cavsub2, qmatrix = twoway4.q, deathexact = TRUE, covariates = ~ pdiag3 + sex + after5 + after10, censor=c(99,999), censor.states=list(1:4,1:4), covinits = list(after5=rep(0.01,7), after10=rep(0.01,7), pdiag3IHD=rep(0.01,7), pdiag3Other=rep(0.01,7)), fixedpars=TRUE ) expect_equal(448.122802051545, cav5cov.msm$minus2loglik, tol=1e-06) }) test_that("piecewise constant intensities with pci, with uncentered covariates",{ cav5cov.msm <- msm( state ~ years, subject=PTNUM, data = cavsub, qmatrix = twoway4.q, covariates = ~ pdiag3 + sex, deathexact = TRUE, pci = c(5,10), fixedpars=TRUE, center=FALSE, covinits = list("timeperiod[5,10)"=rep(0.01,7), "timeperiod[10,Inf)"=rep(0.01,7), pdiag3IHD=rep(0.01,7), pdiag3Other=rep(0.01,7)), ) expect_equal(449.691983558378, cav5cov.msm$minus2loglik, tol=1e-06) cav5cov.msm <- msm( state ~ years, subject=PTNUM, data = cavsub2, qmatrix = twoway4.q, deathexact = TRUE, covariates = ~ pdiag3 + sex + after5 + after10, censor=c(99,999), censor.states=list(1:4,1:4), center=FALSE, covinits = list(after5=rep(0.01,7), after10=rep(0.01,7), pdiag3IHD=rep(0.01,7), pdiag3Other=rep(0.01,7)), fixedpars=TRUE ) expect_equal(449.691983558378, cav5cov.msm$minus2loglik, tol=1e-06) }) test_that("piecewise constant intensities with pci, with other censored states",{ cav.cens <- cav cav.cens$state[cav.cens$state==4][1:50] <- 99 cav5cens.msm <- msm(state ~ years, subject=PTNUM, data = cav.cens, qmatrix = twoway4.q, deathexact = TRUE, censor=99, pci = 5, covinits=list("timeperiod[5,Inf)"=rep(0.02,7)), fixedpars=TRUE, method="BFGS", control=list(trace=5, REPORT=1)) expect_equal(4754.41981265159, cav5cens.msm$minus2loglik, tol=1e-06) }) test_that("piecewise constant intensities with covariates in HMMs",{ misccov.msm <- msm(state ~ years, subject = PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, deathexact = 4, fixedpars=TRUE, pci = 5, covinits=list("timeperiod[5,Inf)"=rep(0.0001,5)), misccovariates = ~dage + sex, misccovinits = list(dage=c(0.01,0.02,0.03,0.04), sex=c(-0.013,-0.014,-0.015,-0.016))) expect_equal(4306.29865288466, misccov.msm$minus2loglik, tol=1e-06) }) context("output functions") test_that("qmatrix.msm for psor model, defaults",{ expect_equal(c(-0.0959350004999946, 0, 0, 0, 0.0959350004999946, -0.164306508892574, 0, 0, 0, 0.164306508892574, -0.254382807485639, 0, 0, 0, 0.254382807485639, 0), as.numeric(qmatrix.msm(psor.msm)$estimates), tol=1e-03) expect_equal(c(0.0115942726096754, 0, 0, 0, 0.0115942726096754, 0.0196169975000406, 0, 0, 0, 0.0196169975000406, 0.0375066077515386, 0, 0, 0, 0.0375066077515386, 0), as.numeric(qmatrix.msm(psor.msm)$SE), tol=1e-03) qmatrix.msm(psor.msm, ci="normal", B=2) expect_error(qmatrix.msm("foo"), "expected .+ msm model") expect_error(qmatrix.msm(psor.msm, covariates="foo"), "covariates argument must be") expect_warning(qmatrix.msm(psor.msm, covariates=list(foo=1)), "ignoring") }) test_that("qmatrix.msm defaults to Qmatrices in object",{ expect_equal(psor.msm$Qmatrices$baseline, qmatrix.msm(psor.msm, covariates="mean", ci="none")) expect_equal(psor.nocen.msm$Qmatrices$baseline, qmatrix.msm(psor.nocen.msm, covariates=0, ci="none")) }) test_that("qmatrix.msm with supplied covariates",{ qmat <- qmatrix.msm(psor.msm, covariates=list(ollwsdrt=0.1, hieffusn=0.4)) expect_equal(c(-0.121430585652200, 0, 0, 0, 0.121430585652200, -0.207972362475868, 0, 0, 0, 0.207972362475868, -0.257535341208494, 0, 0, 0, 0.257535341208494, 0), as.numeric(qmat$estimates), tol=1e-03) expect_equal(c(0.0162156605802465, 0, 0, 0, 0.0162156605802465, 0.0266727053124233, 0, 0, 0, 0.0266727053124233, 0.0364321127089265, 0, 0, 0, 0.0364321127089265, 0), as.numeric(qmat$SE), tol=1e-04) expect_warning(qmatrix.msm(psor.msm, covariates=list(hieffusn=0.1, foo=0.4)), "Covariate .+ unknown") }) test_that("qmatrix.msm with non-default confidence limits",{ qmat <- qmatrix.msm(psor.msm, covariates=list(ollwsdrt=0.1, hieffusn=0.4), cl=0.99) expect_equal(c(-0.171282667596986, 0, 0, 0, 0.0860880282792585, -0.289385121267802, 0, 0, 0, 0.149463467106753, -0.370756460718086, 0, 0, 0, 0.178889538008097, 0), as.numeric(qmat$L), tol=1e-04) }) test_that("qmatrix.msm sojourn component",{ soj <- qmatrix.msm(psor.msm, covariates=list(ollwsdrt=0.1, hieffusn=0.4), sojourn=TRUE)$sojourn expect_equal(c(8.23515751512713, 4.80833120370037, 3.88296221911705, Inf), as.numeric(soj), tol=1e-03) expect_equal(as.numeric(soj[1:3]), sojourn.msm(psor.msm, covariates=list(ollwsdrt=0.1, hieffusn=0.4))[,"estimates"]) }) test_that("qmatrix.msm bug for user-supplied covariates fixed in 1.1.3",{ expect_equal(qmatrix.msm(psor.nocen.msm, covariates=0)$SE[1,2], qmatrix.msm(psor.nocen.msm, covariates=list(hieffusn=0, ollwsdrt=0))$SE[1,2]) expect_equal(qmatrix.msm(psor.nocen.msm, covariates=0)$SE[1,1], qmatrix.msm(psor.nocen.msm, covariates=list(hieffusn=0, ollwsdrt=0))$SE[1,1]) expect_equal(qmatrix.msm(psor.nocen.msm, covariates=0)$L[1,2], qmatrix.msm(psor.nocen.msm, covariates=list(hieffusn=0, ollwsdrt=0))$L[1,2]) expect_equal(qmatrix.msm(psor.nocen.msm, covariates=0)$L[1,2], qmatrix.msm(psor.nocen.msm, covariates=list(hieffusn=0))$L[1,2]) cm <- psor.nocen.msm$qcmodel$covmeans expect_equal(qmatrix.msm(psor.nocen.msm, covariates="mean")$SE[1,2], qmatrix.msm(psor.nocen.msm, covariates=list(hieffusn=cm["hieffusn"], ollwsdrt=cm["ollwsdrt"]))$SE[1,2]) }) test_that("qmatrix.msm: unspecified covariate values default to zero",{ expect_equal(psor.nocen.msm$Qmatrices$baseline, qmatrix.msm(psor.nocen.msm, covariates=list(ollwsdrt=0), ci="none")) # missing covs default to zero expect_equal(qmatrix.msm(psor.msm, covariates=list(hieffusn=0)), qmatrix.msm(psor.msm, covariates=list(ollwsdrt=0, hieffusn=0))) expect_equal(qmatrix.msm(psor.nocen.msm, covariates=list(hieffusn=0)), qmatrix.msm(psor.nocen.msm, covariates=list(ollwsdrt=0, hieffusn=0))) }) test_that("sojourn.msm",{ expect_equal(psor.msm$sojourn, sojourn.msm(psor.msm, covariates="mean")) expect_equal(psor.nocen.msm$sojourn, sojourn.msm(psor.nocen.msm, covariates=0)) soj <- sojourn.msm(psor.msm, covariates=list(ollwsdrt=0.1, hieffusn=0.4)) expect_equal(c(8.23515751512713, 4.80833120370037, 3.88296221911705, 1.09971073904434, 0.616674252838334, 0.549301375677405, 6.33875136203292, 3.73961380505919, 2.94271599303942, 10.6989240349703, 6.18246967994404, 5.12363260020806), as.numeric(unlist(soj)), tol=1e-04) soj <- sojourn.msm(psor.msm, covariates=list(ollwsdrt=0.1, hieffusn=0.4), cl=0.99) expect_equal(5.83830234564607, soj[1,"L"], tol=1e-04) expect_error(sojourn.msm("foo"), "expected .+ msm model") expect_error(sojourn.msm(psor.msm, covariates="foo"),"covariates argument must be") expect_warning(sojourn.msm(psor.msm, covariates=list(foo=1)), "ignoring") }) test_that("pmatrix.msm",{ expect_equal(0.149287738928777, pmatrix.msm(psor.msm, ci="none", t=10)[1,3], tol=1e-04) p <- pmatrix.msm(psor.msm, t=10, covariates=list(ollwsdrt=0.1, hieffusn=0.2)) expect_equal(0.18196160265907, p[1,3], tol=1e-04) set.seed(22061976); expect_equal(0.12, pmatrix.msm(psor.msm, ci="normal", B=3)$L[2,3], tol=1e-01, scale=1) expect_error(pmatrix.msm("foo"), "expected .+ msm model") expect_error(pmatrix.msm(psor.msm, t="foo"), "must be a positive number") expect_error(pmatrix.msm(psor.msm, -9), "must be a positive number") expect_equivalent(unclass(pmatrix.msm(psor.msm, 0)), diag(4)) expect_warning(pmatrix.msm(psor.msm, 1, covariates=list(foo=1)), "ignoring") }) test_that("qratio.msm",{ q <- qratio.msm(psor.msm, c(1,2), c(2,3)) expect_equal(c(0.583878474075081, 0.0996029045389022, 0.417943274168735, 0.815694601537263), as.numeric(q), tol=1e-04) q <- qratio.msm(psor.msm, c(1,2), c(2,3), cl=0.99) expect_equal(0.376262194364283, as.numeric(q["L"]), tol=1e-04) q <- qratio.msm(psor.msm, c(1,1), c(2,3)) expect_equal(c(-0.583878474075081, 0.0996029045389022, -0.815694601537263, -0.417943274168735), as.numeric(q), tol=1e-04) q <- qratio.msm(psor.msm, c(2,2), c(2,3)) expect_equivalent(c(-1,0,-1,-1), q) qratio.msm(psor.msm, c(1,2), c(2,3), ci="norm", B=2) expect_error(qratio.msm("foo")) expect_error(qratio.msm(psor.msm, "foo")) expect_error(qratio.msm(psor.msm, c(1,8), c(1,0))) expect_error(qratio.msm(psor.msm, c(1,2), c(1,0))) expect_error(qratio.msm(psor.msm, c(1,2), c(2,3), cl="foo")) expect_error(qratio.msm(psor.msm, c(1,2), c(2,3), cl=2), "expected cl in") }) test_that("coef.msm",{ co <- coef.msm(psor.msm) expect_equal(0.498319866154661, co$hieffusn[1,2], tol=1e-04) expect_error(coef.msm("foo")) }) test_that("hazard.msm",{ haz <- hazard.msm(psor.msm) expect_equal(0.385347226135311, haz$ollwsdrt[1,2], tol=1e-04) expect_equal(0.385347226135311, haz$ollwsdrt[2,2], tol=1e-04) expect_equal(2.35928404626333, haz$hieffusn[1,3], tol=1e-04) expect_equal(2.35928404626333, haz$hieffusn[3,3], tol=1e-04) haz <- hazard.msm(psor.msm, hazard.scale=2) expect_equal(0.148492484690178, haz$ollwsdrt[1,2], tol=1e-04) expect_equal(haz$ollwsdrt[1,2], haz$ollwsdrt[2,2]) expect_equal(haz$hieffusn[1,3], haz$hieffusn[3,3]) haz <- hazard.msm(psor.msm, hazard.scale=c(1,2)) expect_equal(0.385347226135311, haz$ollwsdrt[1,2], tol=1e-04) expect_equal(haz$ollwsdrt[1,2], haz$ollwsdrt[2,2], tol=1e-04) expect_equal(haz$hieffusn[1,3], haz$hieffusn[3,3]) expect_error(hazard.msm("foo")) expect_error(hazard.msm(psor.msm, hazard.scale="foo")) expect_error(hazard.msm(psor.msm, hazard.scale=c(1,2,3)), "hazard.scale of length") }) test_that("transient.msm and absorbing.msm",{ expect_equivalent(c(1,2,3), transient.msm(psor.msm)) expect_equivalent(4, absorbing.msm(psor.msm)) expect_error(transient.msm("foo")) expect_error(absorbing.msm("foo")) expect_error(transient.msm(qmatrix="foo")) expect_error(absorbing.msm(qmatrix="foo")) expect_error(transient.msm(qmatrix=c(1,4,5,6))) expect_error(absorbing.msm(qmatrix=c(1,4,5,6))) expect_error(transient.msm(qmatrix=cbind(c(1,2,3),c(1,3,2)))) expect_error(absorbing.msm(qmatrix=cbind(c(1,2,3),c(1,3,2)))) expect_error(transient.msm()) expect_error(absorbing.msm()) }) test_that("prevalence.msm",{ p <- prevalence.msm(psor.msm) expect_equal(59, p$Observed[5,5], tol=1e-06) expect_equal(59, p$Expected[5,5], tol=1e-06) expect_equal(57.35294, p$"Observed percentages"[4,4], tol=1e-03) expect_equal(49.96882, p$"Expected percentages"[4,4], tol=1e-03) summ <- summary.msm(psor.msm) expect_equal(summ$prevalences, p) p <- prevalence.msm(psor.msm, times=seq(0,60,5)) expect_equal(63, p$Observed[5,5], tol=1e-06) expect_equal(63, p$Expected[5,5], tol=1e-06) expect_equal(50.70423, p$"Observed percentages"[4,4], tol=1e-03) expect_equal(41.46338, p$"Expected percentages"[4,4], tol=1e-03) expect_error(prevalence.msm("foo")) expect_error(summary.msm("foo")) ## lisa edwards bug - can't reproduce # library(msm, lib.loc="~/work/msm/src/1.2") # library(msm, lib.loc="~/work/msm/src/1.3") # p <- prevalence.msm(psor.msm, covariates=list(hieffusn=0, ollwsdrt=1)) # b.age <- sample(18:75, size=nrow(psor), replace=TRUE) # psor.contcov.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.q, covariates = ~b.age) # p <- prevalence.msm(psor.contcov.msm) # p <- prevalence.msm(psor.contcov.msm, covariates=list(b.age=10)) # p <- prevalence.msm(psor.contcov.msm, covariates="population") }) test_that("pmatrix.piecewise.msm",{ times <- c(5, 10, 15) covariates <- list(list(ollwsdrt=0, hieffusn=0), list(ollwsdrt=0, hieffusn=1), list(ollwsdrt=1, hieffusn=0), list(ollwsdrt=1, hieffusn=1) ) p <- pmatrix.msm(psor.msm, 3, covariates=covariates[[1]]) pp <- pmatrix.piecewise.msm(psor.msm, 0, 3, times, covariates) expect_equal(pp[1,3], p[1,3], tol=1e-04) p <- pmatrix.piecewise.msm(psor.msm, 0, 7, times, covariates) expect_equal(0.172773087945103, p[1,3], tol=1e-04) pp <- pmatrix.piecewise.msm(psor.msm, 0, 19, times, covariates) expect_equal(0.0510873669808412, pp[1,3], tol=1e-04) p <- pmatrix.msm(psor.msm, 5, covariates=covariates[[1]]) %*% pmatrix.msm(psor.msm, 5, covariates=covariates[[2]]) %*% pmatrix.msm(psor.msm, 5, covariates=covariates[[3]]) %*% pmatrix.msm(psor.msm, 4, covariates=covariates[[4]]) expect_equal(pp[1,3], p[1,3], tol=1e-04) covariates <- list(list(ollwsdrt=0, hieffusn=0),list(ollwsdrt=0, hieffusn=1)) p <- pmatrix.piecewise.msm(psor.msm, 0, 7, times=5, covariates) expect_equal(0.172773087945103, p[1,3], tol=1e-04) expect_error(pmatrix.piecewise.msm("foo", 1,2, c(1, 2), c(1,2)), "expected .+ msm model") expect_error(pmatrix.piecewise.msm("foo", 1, 2, c(1, 0.5, 2), list(0, 1, 0, 1)), "expected .+ msm model") expect_error(pmatrix.piecewise.msm(psor.msm, 1, 2, c(1, 0.5, 2), list(0, 1, 0, 1)), "times should be a vector of numbers in increasing order") expect_error(pmatrix.piecewise.msm(psor.msm, 1, 2, "rubbish", list(0, 1, 0, 1)),"times should be a vector of numbers in increasing order") expect_error(pmatrix.piecewise.msm(psor.msm, 1, 2, c(1, 1.5, 2), "rubbish")) expect_error(pmatrix.piecewise.msm(psor.msm, 1, 2, c(1, 1.5, 2), list("rubbish", "foo","bar","boing")), "covariates argument") expect_error(pmatrix.piecewise.msm(psor.msm, 1, 2, c(1, 1.5, 2), list(0, 1, 0, 1)), "covariates argument") }) test_that("logLik.msm",{ expect_equivalent(unclass(logLik.msm(psor.msm)), psor.msm$minus2loglik / -2) expect_error(logLik.msm("foo")) }) test_that("qmatrix subset function",{ Q <- qmatrix.msm(psor.msm) expect_equivalent(Q[1,2]["SE"], Q$SE[1,2]) expect_error(Q[1,2,3,4,5], "unused arguments") expect_error(Q[1], "Two dimensions must be supplied") expect_equivalent(Q[], Q) Q[1,] Q[,2] Q[c(1,2),] Q[c(2,1),] Q[c(1,2),c(1,2)] }) test_that("efpt.msm",{ Q <- twoway4.q expect_equal(efpt.msm(qmatrix=Q, tostate=3), c(Inf,Inf,0,Inf)) Q <- rbind(c(-0.25,0.25,0), c(0.166, -0.332, 0.166), c(0, 0.25, -0.25)) expect_equal(efpt.msm(qmatrix=Q, tostate=3)[c(1,2)], solve(-Q[1:2,1:2], c(1,1)),tol=1e-06) Q <- twoway4.q; Q[2,4] <- Q[2,1] <- 0; diag(Q) <- 0; diag(Q) <- -rowSums(Q) expect_equal(efpt.msm(qmatrix=Q, tostate=3), c(Inf, 6.02409638554217, 0, Inf), tol=1e-05) expect_equal(efpt.msm(psor.msm, tostate=c(2)), c(10.4237243422138, 0, Inf, Inf), tol=1e-05) expect_equal(efpt.msm(psor.msm, tostate=c(3)), c(16.5099104995137, 6.08618615729989, 0, Inf), tol=1e-05) expect_equal(efpt.msm(psor.msm, tostate=c(2,3)), c(10.4237243422138, 0, 0, Inf), tol=1e-05) }) test_that("ppass.msm",{ pp <- ppass.msm(psor.msm, tot=10) pm <- pmatrix.msm(psor.msm, t=10) expect_equal(pp[,4], pm[,4]) # state 4 is absorbing pp <- ppass.msm(qmatrix=twoway4.q, tot=1000) expect_equal(pp[1,2], 0.5) expect_warning(ppass.msm(qmatrix=twoway4.q, tot=100, ci="normal"), "No fitted model supplied: not calculating confidence intervals") }) test_that("score residuals",{ sres <- scoreresid.msm(psor.msm) expect_equal(c(0.0608163009112361, 0.187998750251689, 0.0143302186951471), as.numeric(sres[1:3]), tol=1e-05) psor2 <- na.omit(psor); psor2$months[psor2$ptnum==5] <- psor2$months[psor2$ptnum==5]*10 psor.0.q <- rbind(c(0,0.1,0,0),c(0,0,0.2,0),c(0,0,0,0.3),c(0,0,0,0)) psor.infl.msm <- msm(state ~ months, subject=ptnum, data=psor2, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), qmatrix = psor.0.q) sres <- scoreresid.msm(psor.infl.msm) if (interactive()) sres <- scoreresid.msm(psor.infl.msm, plot=TRUE) expect_equal(names(which.max(sres)), "5") }) test_that("observed, expected etc",{ ## two covariates expect_equal(get.covhist(psor.msm)$example$time, c(6.4606, 17.078, 26.3217, 30.5763, 6.4052, 7.6893, 3.3593, 12.7775)) expect_equivalent(observed.msm(psor.msm)$obstab[,"State 4"], c(0, 6, 25, 39, 48, 50, 52, 53, 55, 56, 57)) expect_equal(as.numeric(expected.msm(psor.msm, covariates="population")$Expected[1:5,"State 3"]), c(0, 11.7058415609289, 14.8078062584701, 9.50355791490463, 5.83372436779321), tol=1e-05) expect_equal(as.numeric(expected.msm(psor.msm, covariates="mean")$Expected[1:5,"State 3"]), c(0, 11.165395364321, 14.8732589026358, 9.67192721319246, 6.26754773418822), tol=1e-05) }) test_that("observed, expected etc with one covariate, should run",{ expect_error({ psor1.msm <- msm(state ~ months, covariates=~ollwsdrt, subject=ptnum, data=psor, qmatrix = psor.q) get.covhist(psor1.msm) observed.msm(psor1.msm) expected.msm(psor1.msm) expected.msm(psor1.msm, covariates="mean") }, NA) }) test_that("observed, expected etc with PCI, should run",{ expect_error({ psor1.msm <- msm(state ~ months, covariates=~ollwsdrt+hieffusn, subject=ptnum, data=psor, qmatrix = psor.q, pci=c(5,10)) covhist <- get.covhist(psor1.msm) observed.msm(psor1.msm) expected.msm(psor1.msm) expected.msm(psor1.msm, covariates="mean") }, NA) }) test_that("subset argument to observed",{ subs <- psor.msm$data$mf$"(subject)"[!duplicated(psor.msm$data$mf$"(subject)") & psor.msm$data$mf$ollwsdrt==0] expect_equivalent(observed.msm(psor.msm, subset=subs)$obstab[,"State 4"], c(0, 5, 20, 30, 37, 38, 40, 41, 43, 44, 45)) }) test_that("error handling: formula",{ ## formula expect_error(msm(), "state ~ time formula not given") expect_error(cav.msm <- msm(state, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE), "not found") expect_error(cav.msm <- msm(~1, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE), "invalid data") expect_error(cav.msm <- msm("foo", subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE), "not a formula") }) test_that("error handling: qmatrix",{ wrong.q <- cbind(c(0,1,2), c(0,1,2)) expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = wrong.q, deathexact = TRUE, fixedpars=TRUE),"Number of rows and columns of qmatrix should be equal") wrong.q <- cbind(c(0,1), c(0,1)) expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = wrong.q, fixedpars=TRUE),"State vector contains elements not in 1, 2") expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = wrong.q, deathexact = TRUE, fixedpars=TRUE),"Not all the states specified in \"deathexact\" are absorbing") wrong.q <- "foo" expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = wrong.q, deathexact = TRUE, fixedpars=TRUE),"qmatrix should be a numeric matrix") wrong.q <- 1 expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = wrong.q, deathexact = TRUE, fixedpars=TRUE),"qmatrix should be a numeric matrix") }) test_that("error handling: subject",{ expect_error(cav.msm <- msm(state~years, subject="foo", data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE),"variable lengths differ") expect_error(cav.msm <- msm(state~years, subject=foo, data = cav, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE),"not found") }) test_that("error handling: obstype",{ expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = twoway4.q, obstype="foo", deathexact = TRUE, fixedpars=TRUE),"should be numeric") expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = twoway4.q, obstype=rep(1,10), deathexact = TRUE, fixedpars=TRUE),"obstype of length") ##FIXME expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = twoway4.q, obstype=rep(4, nrow(cav)), deathexact = TRUE, fixedpars=TRUE),"elements of obstype should be 1, 2, or 3") obstype <- rep(1, nrow(cav)) obstype[c(1,8)] <- 5 expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = twoway4.q, obstype=obstype, deathexact = TRUE, fixedpars=TRUE), NA) # no error: obstype for first subject doesn't matter obstype[2] <- 5 expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = twoway4.q, obstype=obstype, deathexact = TRUE, fixedpars=TRUE),"elements of obstype should be 1, 2, or 3") # error }) test_that("error handling: covariates",{ expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = "wibble"),"should be a formula or list of formulae") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sux),"not found") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, fixedpars=TRUE, misccovariates = "wobble"),"should be a formula") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sox),"not found") }) test_that("error handling: covinits",{ expect_warning(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sex, covinits="foo", fixedpars=TRUE),"covinits should be a list") expect_warning(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sex, covinits=list(sex="foo", age="bar"), fixedpars=TRUE),"should be numeric") expect_warning(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sex, covinits=list(sex=c(1,2,3), age="bar"), fixedpars=TRUE),"should be a list of numeric vectors") expect_warning(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sex, covinits=list(age=rep(0.1, 7)), fixedpars=TRUE),"covariate age in covinits unknown") expect_warning(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sex, covinits=list(age=rep(0.1, 7), foo=1, bar=2), fixedpars=TRUE),"covariates age, foo, bar in covinits unknown") expect_warning(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sex, covinits=list(sex=1), fixedpars=TRUE),"initial values of length 1, should be 7") expect_warning(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, misccovariates = ~ sex, misccovinits="foo", fixedpars=TRUE), "hcovinits should be numeric") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, misccovariates = ~ sex, misccovinits=list(sex=1, age="bar"), fixedpars=TRUE), "misccovariates supplied but no ematrix") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, misccovariates = ~ sex, misccovinits=list(sex=1, age="bar"), fixedpars=TRUE),"misccovariates supplied but no ematrix") expect_warning(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, ematrix=ematrix, misccovariates = ~ sex, misccovinits=list(sex=1, age="bar"), fixedpars=TRUE),"covinits should be a list of numeric") }) test_that("error handling: constraints",{ expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sex, constraint="foo"),"constraint should be a list") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sex, constraint=list(foo="bar")),"constraint should be a list of numeric vectors") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, covariates = ~ sex, constraint=list(foo=1)),"Covariate .+ in constraint statement not in model.") expect_warning(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, misccovariates = ~ sex, constraint="foo", fixedpars=TRUE),"constraint specified but no covariates") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, misccovariates = ~ sex, miscconstraint=list(foo="bar")),"constraint should be a list of numeric vectors") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, misccovariates = ~ sex, miscconstraint=list(foo=1)),"Covariate .+ in constraint statement not in model.") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, misccovariates = ~ sex, miscconstraint=list(sex=1)),"constraint of length 1, should be 4") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, qconstraint="foo", fixedpars=TRUE),"qconstraint should be numeric") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, qconstraint=list(c(1,1,2)), fixedpars=TRUE),"qconstraint should be numeric") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, qconstraint=c(1,1,2), fixedpars=TRUE),"baseline intensity constraint of length 3, should be 7") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, econstraint="foo", fixedpars=TRUE) ,"econstraint should be numeric") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, econstraint=list(c(1,1,2)), fixedpars=TRUE) ,"econstraint should be numeric") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, econstraint=c(1,1,2), fixedpars=TRUE),"baseline misclassification constraint of length 3, should be 4") }) test_that("error handling: initprobs",{ expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, initprobs="poo", fixedpars=TRUE),"initprobs should be numeric") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, initprobs=c(1,2), fixedpars=TRUE),"initprobs vector of length 2, should be vector of length 4 or a matrix") expect_error(cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.q, ematrix=ematrix, initprobs=c(2,1,1,1), fixedpars=TRUE), NA) # scaled to sum to 1. }) test_that("error handling: check states",{ wrong.q <- cbind(c(0,1), c(0,1)) # extra states in data expect_error(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = wrong.q, fixedpars=TRUE),"State vector contains elements not in 1, 2") wrong.q <- rbind(c(0,1,2,3,1), c(0,1,3,4,1), c(0,1,2,3,2), c(0,1,2,3,4), c(0,0,0,0,0)) expect_warning(cav.msm <- msm(state~years, subject=PTNUM, data = cav, qmatrix = wrong.q, fixedpars=TRUE),"State vector doesn't contain observations of 5") }) test_that("error handling: check times",{ cav.wrong <- cav cav.wrong$years[3:5] <- 4:2 expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE),"not ordered by time") cav.wrong <- cav cav.wrong$PTNUM[4:5] <- 100003 expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = twoway4.q, deathexact = TRUE, fixedpars=TRUE),"Observations within subjects .+ are not adjacent in the data") cav2 <- cav cav2$years[10] <- cav2$years[9] expect_warning(msm(state ~ years, subject=PTNUM, data = cav2, qmatrix = twoway4.q, fixedpars=TRUE), "Different states observed at the same time on the same subject at observations 9 and 10") ## with missing data cav2$years[6] <- NA ## report original rows before excluding missing data expect_warning(msm(state ~ years, subject=PTNUM, data = cav2, qmatrix = twoway4.q, fixedpars=TRUE), "Different states observed at the same time on the same subject at observations 9 and 10") cav2 <- cav2[6:nrow(cav),] expect_warning(msm(state ~ years, subject=PTNUM, data = cav2, qmatrix = twoway4.q, fixedpars=TRUE), "Different states observed at the same time on the same subject at observations 4 and 5", "Subject 100002 only has one complete observation") }) test_that("error handling: check model",{ cav.wrong <- cav cav.wrong$state[4] <- 1 expect_warning(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = oneway4.q, deathexact = TRUE, fixedpars=TRUE),"Data may be inconsistent with transition matrix for model without misclassification:\nindividual 100002 moves from state 2 to state 1 at observation 4") expect_warning(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = oneway4.i, gen.inits=TRUE, fixedpars=TRUE),"individual 100046 moves from state 2 to state 1 at observation 225") ## row number reporting with missing data - should be the same cav.wrong$PTNUM[2] <- NA expect_warning(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = oneway4.q, deathexact = TRUE, fixedpars=TRUE),"100002 moves from state 2 to state 1 at observation 4") cav.wrong <- cav cav.wrong$state[4] <- 1 expect_warning(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = twoway4.q, exacttimes=TRUE, fixedpars=TRUE),"individual 100003 moves from state 1 to state 3 at observation 10") ## row number reporting with missing data cav.wrong$state[3] <- NA expect_warning(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = twoway4.q, exacttimes=TRUE, fixedpars=TRUE),"individual 100003 moves from state 1 to state 3 at observation 10") # should complain about obs 10 obstype <- rep(2, nrow(cav)) obstype[10] <- 1 expect_warning(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = twoway4.q, obstype=obstype, fixedpars=TRUE),"individual 100006 moves from state 1 to state 3 at observation 29") ## absorbing-absorbing transitions cav.wrong$state[6] <- 4 expect_warning(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = twoway4.q, obstype=obstype, fixedpars=TRUE),"Absorbing - absorbing transition at observation 7") }) test_that("error handling: death",{ expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = "foo", fixedpars=TRUE) ,"Exact death states indicator must be numeric") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = 5, fixedpars=TRUE) ,"Exact death states indicator contains states not in 1, 2, ... , 4") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = 1:5, fixedpars=TRUE) ,"Exact death states indicator contains states not in 1, 2, ... , 4") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, deathexact = 3, fixedpars=TRUE),"Not all the states specified in \"deathexact\" are absorbing" ) }) test_that("error handling: censor",{ expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, censor="rubbish", fixedpars=TRUE),"censor must be numeric") expect_warning(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, censor=1, fixedpars=TRUE),"some censoring indicators are the same as actual states") expect_warning(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, censor.states="rubbish", fixedpars=TRUE) ,"censor.states supplied but censor not supplied") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.cens, qmatrix = twoway4.q, censor=99, censor.states="rubbish", fixedpars=TRUE) ,"censor.states should be all numeric") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav.cens, qmatrix = twoway4.q, censor=99, censor.states=list(c(1,2,3), "rubbish"), fixedpars=TRUE) ,"censor.states should be a vector") }) test_that("error handling: obstype",{ expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, obstype="rubbish", fixedpars=TRUE) ,"obstype should be numeric") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, obstype=c(1,2,3), fixedpars=TRUE) ,"obstype of length 3, should be length 1 or 2846") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, obstype=4, fixedpars=TRUE),"elements of obstype should be 1, 2, or 3" ) expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, obstype=rep(4,nrow(cav)), fixedpars=TRUE) ,"elements of obstype should be 1, 2, or 3") }) test_that("error handling: fixedpars",{ expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, fixedpars="foo"),"Elements of fixedpars should be in 1, ..., 7") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, fixedpars=list(c(1,3,4))),"Elements of fixedpars should be in 1, ..., 7") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, fixedpars=1:8),"Elements of fixedpars should be in 1, ..., 7") expect_error(cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, fixedpars=0.5),"Elements of fixedpars should be in 1, ..., 7") }) test_that("error handling: plot",{ expect_error(plot.msm("foo"),"expected .+ msm model") expect_error(plot.msm(psor.msm, from="foo"), "from must be numeric") expect_error(plot.msm(psor.msm, to="foo"), "to must be numeric") expect_error(plot.msm(psor.msm, from = 1:8, to=3),"from must be a vector of states in 1, ..., 4") expect_error(plot.msm(psor.msm, to = 3),"to must be an absorbing state") expect_error(plot.msm(psor.msm, range="foo")) expect_error(plot.msm(psor.msm, range=1:6),"range must be a numeric vector of two elements") }) msm/tests/testthat/test_deriv.r0000644000176200001440000002767314116442530016422 0ustar liggesusers## depends on psor.msm context("analytic derivatives of likelihood") test_that("derivatives by subject: sum to overall derivative",{ psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), fixedpars=FALSE) q.mle <- psor.msm$paramdata$opt$par deriv.overall <- deriv.msm(q.mle, expand.data(psor.msm), psor.msm$qmodel, psor.msm$qcmodel, psor.msm$cmodel, psor.msm$hmodel, psor.msm$paramdata) deriv.subj <- Ccall.msm(q.mle, do.what="deriv.subj", expand.data(psor.msm), psor.msm$qmodel, psor.msm$qcmodel, psor.msm$cmodel, psor.msm$hmodel, psor.msm$paramdata) expect_equal(deriv.overall, colSums(deriv.subj)) }) options(msm.test.analytic.derivatives=TRUE) err <- 1e-04 test_that("analytic derivatives match numeric",{ cav.msm <- msm(state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, death = TRUE, fixedpars=TRUE) expect_lt(deriv_error(cav.msm), err) cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qmatrix = twoway4.q, death = FALSE, fixedpars=TRUE) expect_lt(deriv_error(cav.msm), err) cav.msm <- msm( state ~ years, subject=PTNUM, data = cav, qconstraint = c(1,1,2,2,2,3,3), qmatrix = twoway4.q, death = FALSE, fixedpars=TRUE) expect_lt(deriv_error(cav.msm), err) psor.0.q <- rbind(c(0,0.1,0,0),c(0,0,0.2,0),c(0,0,0,0.3),c(0,0,0,0)) psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.0.q, fixedpars=TRUE) expect_lt(deriv_error(psor.msm), err) psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.0.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), fixedpars=TRUE) expect_lt(deriv_error(psor.msm), err) psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.0.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), death=TRUE, fixedpars=TRUE) expect_lt(deriv_error(psor.msm), err) psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.0.q, covariates = ~ollwsdrt+hieffusn, death=TRUE, fixedpars=TRUE) expect_lt(deriv_error(psor.msm), err) msmtest5 <- msm(state ~ time, qmatrix = fiveq, subject = ptnum, data = bos, exacttimes=TRUE, fixedpars=TRUE) expect_lt(deriv_error(msmtest5), err) msmtest5 <- msm(state ~ time, qmatrix = fiveq, subject = ptnum, data = bos, exacttimes=TRUE, qconstraint=c(1,2,1,2,1,2,1), fixedpars=TRUE) expect_lt(deriv_error(msmtest5), err) msmtest5 <- msm(state ~ time, qmatrix = fiveq, covariates = ~time, subject = ptnum, data = bos, exacttimes=TRUE, fixedpars=TRUE) expect_lt(deriv_error(msmtest5), err) msmtest5 <- msm(state ~ time, qmatrix = fiveq, covariates = ~time, constraint=list(time=c(1,2,1,2,1,2,2)), subject = ptnum, data = bos, exacttimes=TRUE, fixedpars=TRUE) expect_lt(deriv_error(msmtest5), err) }) test_that("analytic derivatives for models with censoring",{ cavcens.msm <- msm(state ~ years, subject=PTNUM, data=cav.cens, qmatrix=twoway4.q, censor=99, fixedpars=TRUE) expect_lt(deriv_error(cavcens.msm), err) }) if (0) { ### NOTE: NUMERIC DERIVS BREAK WITH THESE MATRICES when analyticp=TRUE: CLOSE TO REPEATED EIGENVALUES. psor.1.q <- rbind(c(0,0.1,0,0),c(0,0,0.1,0),c(0,0,0,0.1),c(0,0,0,0)) psor.1.q <- rbind(c(0,0.1,0,0),c(0,0,0.10001,0),c(0,0,0,0.1001),c(0,0,0,0)) diag(psor.1.q) <- -rowSums(psor.1.q) psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.1.q, fixedpars=TRUE) psor.msm$paramdata$deriv.test psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.1.q, fixedpars=TRUE, analyticp=FALSE) psor.msm$paramdata$deriv.test psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.1.q, qconstraint=c(1,1,2), fixedpars=TRUE) psor.msm$paramdata$deriv.test psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.1.q, qconstraint=c(1,1,2), fixedpars=TRUE, analyticp=FALSE) psor.msm$paramdata$deriv.test psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.1.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), fixedpars=FALSE, analyticp=TRUE) psor.msm$paramdata$deriv.test psor.msm <- msm(state ~ months, subject=ptnum, data=psor, qmatrix = psor.1.q, covariates = ~ollwsdrt+hieffusn, constraint = list(hieffusn=c(1,1,1),ollwsdrt=c(1,1,2)), fixedpars=FALSE, analyticp=FALSE) psor.msm$paramdata$deriv.test } context("analytic derivatives of likelihood in HMMs") test.df <- data.frame(time=1:2, obs=c(1,1), x=c(1,2), y=c(3,4)) test_that("Categorical, 2 obs",{ tm <- msm(obs ~ time, qmatrix=rbind(c(0,1,0),c(0,0,0),c(0,0,0)), ematrix=rbind(c(0.8,0.1,0.1),c(0.1,0.9,0),c(0,0,0)), data=test.df, fixedpars=TRUE) expect_lt(deriv_error(tm), err) }) test_that("Categorical, lots of obs ",{ nobs <- 100 test.df <- data.frame(time=1:nobs, obs=sample(c(1,2),size=nobs,replace=TRUE), x=c(1,2), y=c(3,4)) tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), ematrix=rbind(c(0.8,0.2),c(0.9,0.1)), data=test.df, fixedpars=TRUE) expect_lt(deriv_error(tm), err) }) test_that("Categorical, a covariate",{ tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), hmodel=list(hmmCat(c(0.8,0.2)),hmmCat(c(0.9,0.1))), hcovariates=list(~x,~1), data=test.df, fixedpars=TRUE) expect_lt(deriv_error(tm), err) }) test_that("Categorical, a covariate on more than one state",{ tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), hmodel=list(hmmCat(c(0.8,0.2)),hmmCat(c(0.9,0.1))), hcovariates=list(~x,~x), data=test.df, fixedpars=TRUE) expect_lt(deriv_error(tm), err) }) test_that("Categorical, 4 potential obs",{ tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), hmodel=list(hmmCat(c(0.8,0.1,0.05,0.05)),hmmCat(c(0.05,0.9,0.02,0.03))), data=test.df, fixedpars=TRUE) expect_lt(deriv_error(tm), err) }) test_that("Derivatives not supported with misclassification constraints",{ expect_warning(tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), ematrix=rbind(c(0.8,0.2),c(0.9,0.1)), econstraint=c(1,1), data=test.df, fixedpars=TRUE), "Analytic derivatives not available") expect_warning(tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), hmodel=list(hmmCat(c(0.8,0.1,0.05,0.05)),hmmCat(c(0.05,0.9,0.02,0.03))), data=test.df, hconstraint=list(p=c(1,1,2,3,4,5)), fixedpars=TRUE), "Analytic derivatives not available") expect_warning(tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), hmodel=list(hmmCat(c(0.8,0.1,0.05,0.05)),hmmCat(c(0.05,0.9,0.02,0.03))), data=test.df, hcovariates=list(~x+y,~x+y), hconstraint=list(p=c(1,1,2,3,4,5),x=c(1,2,2,3,4,5),y=c(1,2,3,3,3,3)), fixedpars=TRUE), "Analytic derivatives not available") expect_warning(tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), hmodel=list(hmmCat(c(0.8,0.2)),hmmCat(c(0.9,0.1))), hcovariates=list(~x,~x), hconstraint=list(x=c(1,1)), data=test.df, fixedpars=TRUE), "Analytic derivatives not available") }) test_that("Derivatives with CAV misclassification model",{ misc.msm <- msm(state ~ years, subject = PTNUM, data = cav[1:200,], qmatrix = oneway4.q, ematrix=ematrix, misccovariates = ~dage + sex, covariates = ~ dage, covinits = list(dage=c(0.1,0.2,0.3,0.4,0.5)), misccovinits = list(dage=c(0.01,0.02,0.03,0.04), sex=c(-0.013,-0.014,-0.015,-0.016)), fixedpars=TRUE) expect_lt(deriv_error(misc.msm), err) misc.msm <- msm(state ~ years, subject = PTNUM, data = cav[1:20,], qmatrix = oneway4.q, ematrix=ematrix, initprobs=c(0.5, 0.2, 0.1, 0.2), fixedpars=TRUE) expect_lt(deriv_error(misc.msm), err) misc.msm <- msm(state ~ years, subject = PTNUM, data = cav[1:2,], qmatrix = rbind(c(0,0.5,0),c(0,0,0.5),c(0,0,0)), hmodel=list(hmmCat(c(0.9,0.1,0)), hmmCat(c(0.1,0.8,0.1)), hmmCat(c(0,0.1,0.9))), initprobs=c(0.5, 0.2, 0.3), fixedpars=TRUE) expect_lt(deriv_error(misc.msm), err) }) ## others in slow/test_fits_hmm.r test_that("simple exponential",{ nobs <- 3 test.df <- data.frame(time=1:nobs, obs=c(rexp(nobs,c(sample(c(1,2),size=nobs,replace=TRUE))))) tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), hmodel=list(hmmExp(1.5),hmmExp(2)), data=test.df, fixedpars=TRUE) expect_lt(deriv_error(tm), err) }) test_that("Information matrix",{ nobs <- 1000 suppressWarnings(RNGversion("3.5.0")) set.seed(1) test.df <- data.frame(time=1:nobs, obs=sample(c(1,2),size=nobs,replace=TRUE)) p1 <- 0.2; p2 <- 0.2; pr1 <- c(1-p1, p1) # P obs(1,2) | true 1 pr2 <- c(p2, 1-p2) # P obs(1,2) | true 2 (tm <- msm(obs ~ time, qmatrix=rbind(c(0,1),c(0,0)), hmodel=list(hmmCat(pr1),hmmCat(pr2)), data=test.df, fixedpars=TRUE, hessian=TRUE)) expect_equal(c(0.88475550512612, 0.202501688704573, -0.474183198550202), tm$paramdata$info[1:3], tol=1e-05) tm$paramdata$opt$hessian }) set.seed(22061976) nsubj <- 100; nobspt <- 6 sim.df <- data.frame(subject = rep(1:nsubj, each=nobspt), time = seq(0, 20, length.out=nobspt), x = rnorm(nsubj*nobspt), y = rnorm(nsubj*nobspt)* 5 + 20) three.q <- rbind(c(0, exp(-6), exp(-9)), c(0, 0, exp(-6)), c(0, 0, 0)) set.seed(22061976) nsubj <- 100; nobspt <- 6 sim.df <- data.frame(subject = rep(1:nsubj, each=nobspt), time = seq(0, 20, length.out=nobspt), x = rnorm(nsubj*nobspt), y = rnorm(nsubj*nobspt)* 5 + 20) test_that("poisson",{ hmodel3 <- list(hmmPois(6), hmmPois(12), hmmIdent(999)) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, hmodel = hmodel3) sim.hid <- msm(obs ~ time, subject=subject, data=sim2.df, qmatrix=three.q, hmodel=hmodel3, fixedpars=TRUE) expect_lt(deriv_error(sim.hid), err) }) test_that("binomial",{ hmodel3 <- list(hmmBinom(10, 0.1), hmmBinom(20, 0.3), hmmIdent(999)) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, hmodel = hmodel3) sim.hid <- msm(obs ~ time, subject=subject, data=sim2.df, qmatrix=three.q, hmodel=hmodel3, fixedpars=TRUE) expect_lt(deriv_error(sim.hid), err) }) ## Derivatives not working yet for beta-binomial if (0){ test_that("betabinomial",{ hmodel3 <- list(hmmBetaBinom(20, 0.7, 0.1), hmmBetaBinom(20, 0.3, 0.1), hmmIdent(999)) three.q <- rbind(c(0, exp(-2), exp(-4)), c(0, 0, exp(-2)), c(0, 0, 0)) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, hmodel = hmodel3) sim.hid <- msm(obs ~ time, subject=subject, data=sim2.df[1:2,], qmatrix=three.q, hmodel=hmodel3, fixedpars=TRUE) sim.hid sim.hid$paramdata$deriv.test deriv_error(sim.hid) expect_lt(deriv_error(sim.hid), err) sim.hid <- msm(obs ~ time, subject=subject, data=sim2.df, qmatrix=three.q, hmodel=hmodel3) }) } test_that("negative binomial",{ hmodel3 <- list(hmmNBinom(10, 0.1), hmmNBinom(20, 0.3), hmmIdent(999)) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, hmodel = hmodel3) sim.hid <- msm(obs ~ time, subject=subject, data=sim2.df, qmatrix=three.q, hmodel=hmodel3, fixedpars=TRUE) expect_lt(deriv_error(sim.hid), err) }) test_that("beta",{ ### some kind of underflow with about 200 obs or more. big derivs, prob poorly identified model hmodel3 <- list(hmmBeta(0.5,0.5), hmmBeta(2, 2), hmmIdent(999)) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, hmodel = hmodel3) sim.hid <- msm(obs ~ time, subject=subject, data=sim2.df[1:100,], qmatrix=three.q, hmodel=hmodel3, fixedpars=TRUE) expect_lt(deriv_error(sim.hid), err) }) test_that("t",{ hmodel3 <- list(hmmT(1, 2, 2), hmmT(4, 2, 3), hmmIdent(999)) sim2.df <- simmulti.msm(sim.df[,1:2], qmatrix=three.q, hmodel = hmodel3) sim.hid <- msm(obs ~ time, subject=subject, data=sim2.df[1:100,], qmatrix=three.q, hmodel=hmodel3, fixedpars=TRUE) expect_lt(deriv_error(sim.hid), err) }) options(msm.test.analytic.derivatives=NULL) msm/tests/testthat/test_models_hmmmulti.r0000644000176200001440000001401214116442530020467 0ustar liggesuserscontext("HMMs with multivariate responses") ## Simulate data from a Markov model nsubj <- 30; nobspt <- 5 sim.df <- data.frame(subject = rep(1:nsubj, each=nobspt), time = seq(0, 20, length.out=nobspt)) suppressWarnings(RNGversion("3.5.0")) set.seed(1) two.q <- rbind(c(-0.1, 0.1), c(0, 0)) dat <- simmulti.msm(sim.df[,1:2], qmatrix=two.q, drop.absorb=FALSE) ## Bin(40, 0.1) for state 1, Bin(40, 0.5) for state 2 dat$obs1 <- dat$obs2 <- NA suppressWarnings(RNGversion("3.5.0")) set.seed(1) dat$obs1[dat$state==1] <- rbinom(sum(dat$state==1), 40, 0.1) dat$obs2[dat$state==1] <- rbinom(sum(dat$state==1), 40, 0.1) dat$obs1[dat$state==2] <- rbinom(sum(dat$state==2), 40, 0.5) dat$obs2[dat$state==2] <- rbinom(sum(dat$state==2), 40, 0.5) dat$obs <- cbind(obs1 = dat$obs1, obs2 = dat$obs2) dat$dobs1 <- dat$dobs2 <- NA suppressWarnings(RNGversion("3.5.0")) set.seed(1) ## Bin(40, 0.1) and Bin(40, 0.2) for state 1, dat$dobs1[dat$state==1] <- rbinom(sum(dat$state==1), 40, 0.1) dat$dobs2[dat$state==1] <- rbinom(sum(dat$state==1), 40, 0.2) ## Bin(40, 0.5) and Bin(40, 0.6) for state 2 dat$dobs1[dat$state==2] <- rbinom(sum(dat$state==2), 40, 0.6) dat$dobs2[dat$state==2] <- rbinom(sum(dat$state==2), 40, 0.5) dat$dobs <- cbind(dobs1 = dat$dobs1, dobs2 = dat$dobs2) options(msm.test.analytic.derivatives=TRUE) err <- 1e-04 test_that("HMMs with multiple responses from the same distribution",{ hmm <- msm(obs ~ time, subject=subject, data=dat, qmatrix=two.q, hmodel = list(hmmBinom(size=40, prob=0.2), hmmBinom(size=40, prob=0.2)), fixedpars=TRUE) expect_equal(hmm$minus2loglik, 4387.58552977954, tol=1e-06) expect_lt(deriv_error(hmm), err) }) test_that("HMMs with multiple responses: cbind() in formula",{ hmm <- msm(cbind(obs1, obs2) ~ time, subject=subject, data=dat, qmatrix=two.q, hmodel = list(hmmBinom(size=40, prob=0.2), hmmBinom(size=40, prob=0.2)), fixedpars=TRUE) expect_equal(hmm$minus2loglik, 4387.58552977954, tol=1e-06) }) test_that("HMMs with multiple responses from different distributions",{ hmm <- msm(dobs ~ time, subject=subject, data=dat, qmatrix=two.q, hmodel = list(hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3))), fixedpars=TRUE) expect_equal(hmm$minus2loglik, 3767.11569380418, tol=1e-06) expect_lt(deriv_error(hmm), err) expect_error(msm(obs1 ~ time, subject=subject, data=dat, qmatrix=two.q, hmodel = list(hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3))), fixedpars=TRUE), "Only one column in state outcome data") }) test_that("HMMs with multiple responses from different distributions: non-default initprobs, different probs",{ hmm <- msm(dobs ~ time, subject=subject, data=dat, qmatrix=two.q, initprobs=c(0.6, 0.4), hmodel = list(hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmMV(hmmBinom(size=40, prob=0.4), hmmBinom(size=40, prob=0.4))), fixedpars=TRUE) expect_lt(deriv_error(hmm), err) }) dat$dobsmiss <- dat$dobs dat$dobsmiss[1:10,2] <- NA test_that("HMMs with multiple responses from different distributions: missing data",{ hmm <- msm(dobsmiss ~ time, subject=subject, data=dat, qmatrix=two.q, hmodel = list(hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3))), fixedpars=TRUE) expect_lt(deriv_error(hmm), err) }) dat$obstrue <- NA obstimes <- seq(2, 147, by=5) # times when true state is known dat$obstrue[obstimes] <- dat$state[obstimes] test_that("HMMs with multiple responses: true state known sometimes",{ hmm <- msm(dobs ~ time, subject=subject, data=dat, qmatrix=two.q, obstrue=obstrue, hmodel = list(hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3))), fixedpars=TRUE) expect_equal(hmm$minus2loglik, 3804.03972787726, tol=1e-06) expect_lt(deriv_error(hmm), err) }) datd <- dat datd$dobs[c(5,10),1] <- 999 three.q <- rbind(cbind(two.q, c(0.1,0.1)), c(0,0,0)) options(msm.test.analytic.derivatives=NULL) test_that("HMMs with multiple responses: exact death and hmmIdent",{ hmm <- msm(dobs ~ time, subject=subject, data=datd, qmatrix=three.q, death = 3, hmodel = list(hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmIdent(999)), fixedpars=TRUE) expect_error(msm(dobs ~ time, subject=subject, data=datd, qmatrix=three.q, death = 3, hmodel = list(hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmMV(hmmBinom(size=40, prob=0.3), hmmBinom(size=40, prob=0.3)), hmmPois(1)), fixedpars=TRUE), "States specified in \"deathexact\" should have the identity hidden distribution hmmIdent") }) ## censoring? msm/tests/testthat/test_datasumm.r0000644000176200001440000000627413051600620017107 0ustar liggesuserscontext("msm data summaries") test_that("statetable.msm", { stab <- statetable.msm(state, PTNUM, data=cav) expect_that(stab, equals(structure(c(1367L, 46L, 4L, 204L, 134L, 13L, 44L, 54L, 107L, 148L, 48L, 55L), .Dim = 3:4, .Dimnames = structure(list(from = c("1","2", "3"), to = c("1", "2", "3", "4")), .Names = c("from", "to")), class = "table"))) expect_equal(as.numeric(stab), c(1367, 46, 4, 204, 134, 13, 44, 54, 107, 148, 48, 55)) expect_error(statetable.msm(state,PTNUM), "not found") stabc <- statetable.msm(state, PTNUM, cav.cens) expect_equal(as.numeric(stabc), c(1367, 46, 4, 204, 134, 13, 44, 54, 107, 127, 40, 34, 21, 8, 21)) }) test_that("crudeinits.msm", { cinits <- crudeinits.msm(state ~ years, PTNUM, data=cav, qmatrix=twoway4.q) expect_equal(as.numeric(cinits), c(-0.117314905786477, 0.116817878212849, 0, 0, 0.067989320398981, -0.375848825554382, 0.049084006577444, 0, 0, 0.137134030945518, -0.256747111328168, 0, 0.049325585387496, 0.121896916396016, 0.207663104750724, 0)) expect_error(crudeinits.msm(state ~ years, PTNUM, qmatrix=twoway4.q), "not found") }) test_that("crudeinits.msm ignores inconsistent transitions unless exact times", { cav.wrong <- cav; cav.wrong$state[4] <- 1 expect_error(crudeinits.msm(state ~ years, PTNUM, oneway4.q, cav), NA) expect_warning(msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = twoway4.q, exacttimes=TRUE, fixedpars=TRUE), "inconsistent with intensity") obstype <- rep(2, nrow(cav)); obstype[10] <- 1 expect_warning(msm(state ~ years, subject=PTNUM, data = cav.wrong, qmatrix = twoway4.q, obstype=obstype, fixedpars=TRUE), "inconsistent with intensity") }) test_that("crudeinits.msm handles NAs", { psor2 <- psor; psor2$ptnum[13:14] <- psor2$months[7:8] <- psor2$state[7:8] <- NA expect_equal(crudeinits.msm(state ~ months, ptnum, data=psor2, qmatrix=psor.q), crudeinits.msm(state ~ months, ptnum, data=psor2[-c(7,8,13,14),], qmatrix=psor.q)) }) test_that("crudeinits.msm handles censoring",{ expect_error(crudeinits.msm(state ~ years, PTNUM, twoway4.q, cav.cens), "elements not in 1, 2") cru <- crudeinits.msm(state~ years, PTNUM, twoway4.q, cav.cens, censor=99) expect_equal(as.numeric(cru), c(-0.111798558088660, 0.122878533946307, 0, 0, 0.0689030388220138, -0.373978146793108, 0.0618112185064827, 0, 0, 0.144248713763056, -0.223471328446514, 0, 0.0428955192666458, 0.106850899083745, 0.161660109940032, 0)) cru <- crudeinits.msm(state~ years, PTNUM, twoway4.q, cav.cens2, censor=c(99,999), censor.states=list(c(1,2,3),c(2,3))) expect_equal(as.numeric(cru), c(-0.107299472349819, 0.134927714425074, 0, 0, 0.0697104852209013, -0.369584609077378, 0.0789635719132074, 0, 0, 0.158393403890305, -0.170075385659216, 0, 0.0375889871289174, 0.0762634907619986, 0.0911118137460085, 0), tol=1e-06) cru <- crudeinits.msm(state~ years, PTNUM, twoway4.q, cav.cens3, censor=c(99,999), censor.states=list(c(2,3),c(1,2,3))) expect_equal(as.numeric(cru), c(-0.112107245394208, 0.124370575094641, 0, 0, 0.0686998668421821, -0.370347934726264, 0.0659650781282531, 0, 0, 0.135425737325276, -0.238489128617530, 0, 0.0434073785520255, 0.110551622306348, 0.172524050489277, 0), tol=1e-06) }) msm/tests/testthat/helper.r0000644000176200001440000000275613051600620015515 0ustar liggesuserstwoway4.q <- rbind(c(-0.5, 0.25, 0, 0.25), c(0.166, -0.498, 0.166, 0.166), c(0, 0.25, -0.5, 0.25), c(0, 0, 0, 0)) twoway4.q2 <- rbind(c(-0.51, 0.24, 0, 0.25), c(0.162, -0.498, 0.168, 0.166), c(0, 0.26, -0.5, 0.25), c(0, 0, 0, 0)) twoway3.q <- rbind(c(-0.5, 0.25, 0), c(0.166, -0.498, 0.166), c(0, 0.25, -0.5)) oneway4.q <- rbind(c(0, 0.148, 0, 0.0171), c(0, 0, 0.202, 0.081), c(0, 0, 0, 0.126), c(0, 0, 0, 0)) rownames(twoway4.q) <- colnames(twoway4.q) <- rownames(oneway4.q) <- colnames(oneway4.q) <- c("Well","Mild","Severe","Death") twoway4.i <- twoway4.q; twoway4.i[twoway4.i!=0] <- 1 oneway4.i <- oneway4.q; oneway4.i[oneway4.i!=0] <- 1 psor.q <- rbind(c(0,0.1,0,0),c(0,0,0.1,0),c(0,0,0,0.1),c(0,0,0,0)) fiveq <- rbind(c(0,0.01,0,0,0.002), c(0,0,0.07,0,0.01), c(0,0,0,0.07,0.02), c(0,0,0,0,0.03), c(0,0,0,0,0)) ematrix <- rbind(c(0, 0.1, 0, 0),c(0.1, 0, 0.1, 0),c(0, 0.1, 0, 0),c(0, 0, 0, 0)) rownames(oneway4.q) <- colnames(oneway4.q) <- rownames(ematrix) <- colnames(ematrix) <- c("Well","Mild","Severe","Death") cav.cens <- cav cav.cens$state[cav$state==4][1:50] <- 99 cav.cens2 <- cav cav.cens2$state[cav$state==4][1:50] <- 99 cav.cens2$state[cav$state==4][51:100] <- 999 cav.cens3 <- cav ns <- c(cav$state[2:nrow(cav)], 0) cav.cens3$state[cav$state==4][1:50] <- 99 cav.cens3$state[ns==4][1:50] <- 999 deriv_error <- function(object){ if (!isTRUE(getOption("msm.test.analytic.derivatives"))) stop("msm.test.analytic.derivatives option not set") object$paramdata$deriv.test$error["nd"] } msm/tests/test_base.R0000644000176200001440000000004413051600620014273 0ustar liggesuserslibrary(testthat) test_check("msm") msm/src/0000755000176200001440000000000014124277672011651 5ustar liggesusersmsm/src/expm.h0000644000176200001440000000024613571236554012774 0ustar liggesusers/* Interface to expm package. */ typedef enum {Ward_2, Ward_1, Ward_buggy_octave} precond_type; void (*expm)(double *x, int n, double *z, precond_type precond_kind); msm/src/hmm.c0000644000176200001440000001010013326041537012556 0ustar liggesusers#include "hmm.h" #include #include "msm.h" /* Response (emission) functions for hidden Markov models (probability of outcome conditionally on the hidden state). All of the form double f(double x, double *pars) */ /* Categorical distribution on the set (1, 2, 3, ..., pars[0]), Baseline category is given by pars[1] (not used any more, to delete?) Probabilities are defined by pars[2], ... pars[ncats+1] NEW IMPLEMENTATION in v1.3 pars[2],pars[3]... are absolute probs. covariates applied in R. used to be relative with covariates applied in C. */ double hmmCat(double x, double *pars) { int cat = fprec(x, 0); int ncats = fprec(pars[0], 0); if ((cat > ncats) || (cat < 1)) return 0; return pars[1 + cat]; } double hmmIdent(double x, double *pars) { return all_equal(x, pars[0]); } double hmmUnif(double x, double *pars) { double lower = pars[0], upper = pars[1]; return dunif(x, lower, upper, 0); } double hmmNorm(double x, double *pars) { double mean = pars[0], sd = pars[1]; return dnorm(x, mean, sd, 0); } double hmmLNorm(double x, double *pars) { double meanlog = pars[0], sdlog = pars[1]; return dlnorm(x, meanlog, sdlog, 0); } double hmmExp(double x, double *pars) { double mean = 1 / pars[0]; return dexp(x, mean, 0); } double hmmGamma(double x, double *pars) { double shape = pars[0], scale = 1 / pars[1]; return dgamma(x, shape, scale, 0); } double hmmWeibull(double x, double *pars) { double shape = pars[0], scale = pars[1]; return dweibull(x, shape, scale, 0); } double hmmPois(double x, double *pars) { double lambda = pars[0]; return dpois(x, lambda, 0); } double hmmBinom(double x, double *pars) { double size = pars[0], prob = pars[1]; return dbinom(x, size, prob, 0); } double hmmBetaBinom(double x, double *pars) { double size = pars[0], meanp = pars[1], sdp = pars[2], shape1, shape2, dens; shape1 = meanp/sdp; shape2 = (1 - meanp)/sdp; if ((x<0) || (x>size)) dens = 0.0; else { dens = exp(lchoose(size, x) + lbeta(x + shape1, size - x + shape2) - lbeta(shape1, shape2)); } return dens; } /* Truncated normal distribution. Infinite bounds are allowed through a parameter with a value of "Inf" or "-Inf" passed from R */ double hmmTNorm(double x, double *pars) { double mean = pars[0], sd = pars[1], lower = pars[2], upper = pars[3]; double denom = pnorm(upper, mean, sd, 1, 0) - pnorm(lower, mean, sd, 1, 0); if (x < lower) return 0; if (x > upper) return 0; return dnorm(x, mean, sd, 0) / denom; } /* Satten and Longini's truncated normal distribution with normal measurement error */ /* To parameterise so covariates go on observation: Put in a dummy parameter meanerr = 0 for the measurement error model xobs ~ N(xhid + meanerr, sderr), then covs go on meanerr. */ double hmmMETNorm(double x, double *pars) { double mean = pars[0], sd = pars[1], lower = pars[2], upper = pars[3], sderr = pars[4], meanerr = pars[5]; double sumsq = sd*sd + sderr*sderr; double sigtmp = sd*sderr / sqrt(sumsq); double mutmp = ((x - meanerr)*sd*sd + mean*sderr*sderr) / sumsq; double nc = 1/(pnorm(upper, mean, sd, 1, 0) - pnorm(lower, mean, sd, 1, 0)); double nctmp = pnorm(upper, mutmp, sigtmp, 1, 0) - pnorm(lower, mutmp, sigtmp, 1, 0); return nc * nctmp * dnorm(x, meanerr + mean, sqrt(sumsq), 0); } /* Satten and Longini's uniform distribution with normal measurement error */ double hmmMEUnif(double x, double *pars) { double lower = pars[0], upper = pars[1], sderr = pars[2], meanerr = pars[3]; return ( pnorm(x, meanerr + lower, sderr, 1, 0) - pnorm(x, meanerr + upper, sderr, 1, 0) ) / (upper - lower) ; } double hmmNBinom(double x, double *pars) { double size = pars[0], prob = pars[1]; return dnbinom(x, size, prob, 0); } double hmmBeta(double x, double *pars) { double shape1 = pars[0], shape2 = pars[1]; return dbeta(x, shape1, shape2, 0); } double hmmT(double x, double *pars) { double tmean = pars[0], tscale = pars[1], tdf=pars[2]; return (1/tscale)*dt((x-tmean)/tscale, tdf, 0); } msm/src/msm-init.c0000644000176200001440000000140513075701351013540 0ustar liggesusers#include #include #include // for NULL #include #include "expm.h" /* .C calls */ extern void MatrixExpR(void *, void *, void *, void *, void *, void *, void *, void *, void *); /* .Call calls */ extern SEXP msmCEntry(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); static const R_CMethodDef CEntries[] = { {"MatrixExpR", (DL_FUNC) &MatrixExpR, 9}, {NULL, NULL, 0} }; static const R_CallMethodDef CallEntries[] = { {"msmCEntry", (DL_FUNC) &msmCEntry, 8}, {NULL, NULL, 0} }; void R_init_msm(DllInfo *dll) { R_registerRoutines(dll, CEntries, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); expm = (void (*) (double*, int, double*, precond_type)) R_GetCCallable("expm", "expm"); } msm/src/hmm.h0000644000176200001440000000320713326031254012570 0ustar liggesusers typedef double (*hmmfn)(double x, double *pars); typedef void (*dhmmfn)(double x, double *pars, double *d); double hmmCat(double x, double *pars); double hmmIdent(double x, double *pars); double hmmUnif(double x, double *pars); double hmmNorm(double x, double *pars); double hmmLNorm(double x, double *pars); double hmmExp(double x, double *pars); double hmmGamma(double x, double *pars); double hmmWeibull(double x, double *pars); double hmmPois(double x, double *pars); double hmmBinom(double x, double *pars); double hmmBetaBinom(double x, double *pars); double hmmTNorm(double x, double *pars); double hmmMETNorm(double x, double *pars); double hmmMEUnif(double x, double *pars); double hmmNBinom(double x, double *pars); double hmmBeta(double x, double *pars); double hmmT(double x, double *pars); void DhmmCat(double x, double *pars, double *d); void DhmmIdent(double x, double *pars, double *d); void DhmmUnif(double x, double *pars, double *d); void DhmmNorm(double x, double *pars, double *d); void DhmmLNorm(double x, double *pars, double *d); void DhmmExp(double x, double *pars, double *d); void DhmmGamma(double x, double *pars, double *d); void DhmmWeibull(double x, double *pars, double *d); void DhmmPois(double x, double *pars, double *d); void DhmmBinom(double x, double *pars, double *d); void DhmmBetaBinom(double x, double *pars, double *d); void DhmmTNorm(double x, double *pars, double *d); void DhmmMETNorm(double x, double *pars, double *d); void DhmmMEUnif(double x, double *pars, double *d); void DhmmNBinom(double x, double *pars, double *d); void DhmmBeta(double x, double *pars, double *d); void DhmmT(double x, double *pars, double *d); msm/src/analyticp.c0000644000176200001440000015710113051600620013763 0ustar liggesusers/* Analytic formulae for P(t) in terms of transition intensities, for selected 2, 3, 4 and 5-state models. These were derived using symbolic algebra software (Mathematica). Increases speed and stability by avoiding the numeric calculation of the matrix exponential. ### The numbered label gives the indices into the matrix of rates (vectorised by reading across rows) ### e.g. the 3-state model with qmatrix of the form ### well-disease, well-death, disease-death transitions allowed. ### *,1,1 ### 0,*,1 ### 0,0,* uses the function p3q124() ### Some models are isomorphic and use the same p?q? function. ### See .msm.graphs in R/constants.R for permutations. */ #include "msm.h" #include void p2q1(Matrix pmat, double t, Matrix qmat, int *degen); void p2q12(Matrix pmat, double t, Matrix qmat, int *degen); void p3q12(Matrix pmat, double t, Matrix qmat, int *degen); void p3q14(Matrix pmat, double t, Matrix qmat, int *degen); void p3q16(Matrix pmat, double t, Matrix qmat, int *degen); void p3q124(Matrix pmat, double t, Matrix qmat, int *degen); void p3q135(Matrix pmat, double t, Matrix qmat, int *degen); void p3q1246(Matrix pmat, double t, Matrix qmat, int *degen); void p4q159(Matrix pmat, double t, Matrix qmat, int *degen); void p4q13569(Matrix pmat, double t, Matrix qmat, int *degen); void p5q1_6_11_16(Matrix pmat, double t, Matrix qmat, int *degen); void p5q1_4_6_8_11_12_16(Matrix pmat, double t, Matrix qmat, int *degen); void p5q1_6_7_11_12(Matrix pmat, double t, Matrix qmat, int *degen); typedef void (*pfn)(Matrix pmat, double t, Matrix qmat, int *degen); pfn P2FNS[] = { p2q1, p2q12 }; pfn P3FNS[] = { p3q12,p3q14,p3q16,p3q124,p3q135,p3q1246 }; pfn P4FNS[] = { p4q159,p4q13569 }; pfn P5FNS[] = { p5q1_6_11_16,p5q1_4_6_8_11_12_16,p5q1_6_7_11_12 }; void AnalyticP(Matrix pmat, double t, int nstates, int iso, int *perm, int *qperm, Matrix qmat, int *degen) { int i, j; Matrix qmat_base = (Matrix) Calloc( (nstates)*(nstates), double); Matrix pmat_base = (Matrix) Calloc( (nstates)*(nstates), double); for (i=0; i #include /* Derivatives of PDF w.r.t parameters, for each HMM outcome * distribution */ void DhmmCat(double x, double *pars, double *d) { /* f(x) = p_y if x=y, and 0 otherwise df / dp_y |x = 1 if x=y, and 0 otherwise */ int i; int cat = fprec(x, 0); int ncats = fprec(pars[0], 0); for (i=0; i ncats) || (cat < 1)) return; d[1+cat] = 1; } void DhmmIdent(double x, double *pars, double *d){ d[0] = 0; } void DhmmUnif(double x, double *pars, double *d) { d[0]=0; d[1]=0; /* uniform parameters are not estimated */ } void DhmmNorm(double x, double *pars, double *d) { double mean = pars[0], sd = pars[1], f; f = dnorm(x, mean, sd, 0); d[0] = f*(x - mean)/R_pow_di(sd,2); d[1] = f*(R_pow_di((x-mean)/sd, 2) - 1)/sd; } void DhmmLNorm(double x, double *pars, double *d) { double meanlog = pars[0], sdlog = pars[1], f; f = dlnorm(x, meanlog, sdlog, 0); d[0] = f*(log(x) - meanlog)/R_pow_di(sdlog,2); d[1] = f*(R_pow_di((log(x)-meanlog)/sdlog, 2) - 1)/sdlog; } void DhmmExp(double x, double *pars, double *d) { double rate = pars[0]; d[0] = (1 - rate*x)*exp(-rate*x); } void DhmmGamma(double x, double *pars, double *d) { double shape = pars[0], rate=pars[1], scale = 1 / rate, f; f = dgamma(x, shape, scale, 0); d[0] = f*(log(rate) + log(x) - digamma(shape)); d[1] = f*(shape/rate - x); } void DhmmWeibull(double x, double *pars, double *d) { double shape = pars[0], scale = pars[1], f, rp; f = dweibull(x, shape, scale, 0); rp = R_pow(x/scale, shape); d[0] = f*(1/shape + log(x/scale)*(1 - rp)); d[1] = f*(shape/scale*(rp - 1)); } void DhmmPois(double x, double *pars, double *d) { double lambda = pars[0], f; f = dpois(x, lambda, 0); d[0] = (x/lambda - 1)*f; } void DhmmBinom(double x, double *pars, double *d) { double size = pars[0], prob = pars[1], f; f = dbinom(x, size, prob, 0); d[0] = 0; // fixed d[1] = f*(x/prob - (size-x)/(1-prob)); // printf("f=%.3f, dlf=%.3f, d[1]=%.5f\n", f, (x/prob - (size-x)/(1-prob)), d[1]); } /* beta binomial TODO d/da B(a,b) = B(a,b) (digamma(a) - digamma(a+b)) d/db B(a,b) = B(a,b) (digamma(b) - digamma(a+b)) d/da B(x+a, n-x+b) * B(a,b)^-1 = d/da B(x+a, n-x+b) * B(a,b)^-1 + B(x+a, n-x+b) * -B(a,b)^-2 * d/da B(a,b) = ( d/da B(x+a, n-x+b) B(a,b) - B(x+a, n-x+b) d/da B(a,b) ) / B(a,b)^2 = ( B(x+a,n-x+b) (digamma(x+a) - digamma(n+a+b)) B(a,b) - B(x+a, n-x+b) B(a,b) (digamma(a) - digamma(a+b)) ) / B(a,b)^2 = B(x+a,n-x+b) (digamma(x+a) - digamma(n+a+b) - digamma(a) + digamma(a+b)) / B(a,b) and d/db B(x+a, n-x+b) * B(a,b)^-1 = B(x+a,n-x+b) (digamma(n-x+b) - digamma(n+a+b) - digamma(b) + digamma(a+b)) / B(a,b) */ // FIXME this doesn't match num derivs for meanp, but does for sdp void DhmmBetaBinom(double x, double *pars, double *d) { double size = pars[0], meanp = pars[1], sdp = pars[2], shape1, shape2, dens; double pd[3], J[2][2]; dens = hmmBetaBinom(x, pars); shape1 = meanp/sdp; shape2 = (1 - meanp)/sdp; if ((x<0) || (x>size)) { d[0]=0.0; d[1]=0.0; d[2]=0.0; } else { J[0][0] = 1.0/sdp; J[0][1] = -meanp/(sdp*sdp); J[1][0] = -1.0/sdp; J[1][1] = -(1-meanp)/(sdp*sdp); pd[0] = 0; // fixed pd[1] = dens * (digamma(x+shape1) - digamma(size+shape1+shape2) - digamma(shape1) + digamma(shape1+shape2)); pd[2] = dens * (digamma(size-x+shape2) - digamma(size+shape1+shape2) - digamma(shape2) + digamma(shape1+shape2)); d[0] = 0; d[1] = pd[1]*J[0][0] + pd[2]*J[1][0]; d[2] = pd[1]*J[0][1] + pd[2]*J[1][1]; } } /* not sure these three are tractable. don't support */ void DhmmTNorm(double x, double *pars, double *d){} void DhmmMETNorm(double x, double *pars, double *d){} void DhmmMEUnif(double x, double *pars, double *d){} void DhmmNBinom(double x, double *pars, double *d) { double size = pars[0], prob = pars[1], f; f = dnbinom(x, size, prob, 0); d[0] = f*(digamma(x+size) - digamma(size) + log(prob)); d[1] = f*(size/prob - x/(1-prob)); } void DhmmBeta(double x, double *pars, double *d) { double shape1 = pars[0], shape2 = pars[1], f; f = dbeta(x, shape1, shape2, 0); d[0] = f*(digamma(shape1+shape2) - digamma(shape1) + log(x)); d[1] = f*(digamma(shape1+shape2) - digamma(shape2) + log(1-x)); } void DhmmT(double x, double *pars, double *d) { double tmean = pars[0], tscale = pars[1], tdf=pars[2], f, xmsq; f = (1/tscale)*dt((x-tmean)/tscale, tdf, 0); xmsq = (x - tmean)*(x-tmean); d[0] = f * (x - tmean)*(tdf + 1) / (tdf*tscale*tscale + xmsq); d[1] = f * (-1/tscale + (tdf+1)*xmsq / (tdf*R_pow(tscale,3) + tscale*xmsq)); d[2] = 0.5 * f * (digamma((tdf + 1)/2) - digamma(tdf/2) - 1/tdf - log(1 + xmsq / (tdf*tscale*tscale)) + (tdf+1)*xmsq / (R_pow(tdf*tscale,2) + tdf*xmsq)); } msm/src/Makevars0000644000176200001440000000006113051600620013317 0ustar liggesusersPKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) msm/src/pijt.c0000644000176200001440000004362214124024571012756 0ustar liggesusers/* ***************************************************************** pijt.c: Linear algebra routines for msm. To obtain Markov transition probabilities (the P-matrix) from transition intensities (the Q-matrix). Copyright (c) Chris Jackson 2001-2005 Pade approximants method of calculating matrix exponentials is based on matexp.cc from JAGS, Copyright (c) 2004, Martyn Plummer. http://www-fis.iarc.fr/~martyn/software/jags ****************************************************************** */ #include "msm.h" /* Crude benchmarks have shown that using the eigensystem routines from LINPACK, and the matrix inversion routines from LAPACK, is the faster combination. However... Occasional crashes on extremely flat optimisations. Valgrind reveals memory errors within LINPACK Fortran eigen code. Crashes don't occur if use LAPACK code. */ #define _USE_LAPACK_EIGEN_ #define _USE_LAPACK_INVERSE_ #define MEXP_PADE 1 #define MEXP_SERIES 2 #include "R_ext/Lapack.h" #ifndef FCONE #define FCONE #endif #include "R_ext/Rdynload.h" typedef enum {Ward_2, Ward_1, Ward_buggy_octave} precond_type; extern void (*expm)(double *x, int n, double *z, precond_type precond_kind); #define NODERIVDEBUG /* Set A to be an n x n identity matrix */ void FormIdentity(Matrix A, int n) { int i; for (i = 0; i < (n*n); ++i) A[i] = 0; for (i = 0; i < n; ++i) A[MI(i, i, n)] = 1; } /* Invert a matrix by calling LINPACK QR decomposition routines */ /* DGETRF/DGETRI method (current) is from LAPACK. This is the fastest. */ /* DQR method (used in <=0.4.1) is from LINPACK */ void MatInvDGE(Matrix A, Matrix Ainv, int n) { int i, j; Matrix temp = (Matrix) Calloc(n*n, double); Matrix work = (Matrix) Calloc(n*n, double); int nsq=n*n, info, *pivot = Calloc(n, int); for (i=0; i 0) REprintf("Lapack routine dgesv: system is exactly singular\n"); Free(Acopy); Free(ipiv); Free(work); } static void padeseries (double *Sum, double *A, int m, int order, double scale, double *Temp) { int i, j, r; int N = m*m; FormIdentity(Sum, m); for (j = order; j >= 1; --j) { double s = (order-j+1) / (j*(2*order-j+1) * scale); MultMat(Sum, A, m, m, m, Temp); for (i = 0; i < N; ++i) { Sum[i] = Temp[i] * s; } for (r = 0; r < m; ++r) { Sum[r*m+r] += 1; } } } void MatrixExpPade(double *ExpAt, double *A, int n, double t) { /* Calculate exp(A*t) by diagonal Pade approximation with scaling and squaring */ int i, j; int order = 8; int N = n*n; double *workspace = Calloc( 4*N, double); double * Temp = workspace; double * At = workspace + N; double * Num = workspace + 2*N; double * Denom = workspace + 3*N; double l1 = F77_CALL(dlange)("1", &n, &n, At, &n, 0 FCONE); /* L-1 norm */ double linf = F77_CALL(dlange)("i", &n, &n, At, &n, Temp FCONE); /* L-Infinity norm */ double K = (log(l1) + log(linf))/log(4); int npower = (R_FINITE(K) ? (int)(K)+4 : NA_INTEGER); double scale = 1; /* Multiply by t */ for (i = 0; i < N; ++i) { At[i] = A[i] * t; } /* Scale the matrix by a power of 2 */ /* The expression below is not clear because it is optimized. The idea is that sqrt(l1 * linf) is an upper bound on the L2 norm of the matrix At (i.e the largest eigenvalue). We want to take the log, to base 2 of this to get the smallest K, st ||At/2^K|| <= 1. */ if (npower < 0) { npower = 0; } for (i = 0; i < npower; ++i) { scale *= 2; } /* Calculate exp(A/scale) by Pade series */ padeseries (Num, At, n, order, scale, Temp); for (i = 0; i < N; ++i) { At[i] = -At[i]; } padeseries (Denom, At, n, order, scale, Temp); solve(ExpAt, Denom, Num, n); /* Now repeatedly square the result */ for (i = 0; i < npower; ++i) { for (j = 0; j < N; ++j) { Temp[j] = ExpAt[j]; } MultMat(Temp, Temp, n, n, n, ExpAt); } Free(workspace); } /* Tests if a vector has any non-unique entries */ int repeated_entries(vector vec, int n) { int i, j; for (i=1; i 0) AnalyticP(expmat, *t, *n, *iso, perm, qperm, mat, degen); else MatrixExpMSM(mat, *n, expmat, *t, *degen, *method); } void MatrixExpEXPM(double *mat, int *n, double *expmat, double *t, int *method, int *iso, int *perm, int *qperm, int *degen, int *err){ int i; int nsq = (*n)*(*n); double *matt = Calloc(nsq, double); if (*iso > 0) AnalyticP(expmat, *t, *n, *iso, perm, qperm, mat, degen); else { for (i=0; i<((*n)*(*n)); ++i) { matt[i] = (*t) * mat[i]; /* Check whether any of the elements of Q have overflowed. If so, Fortran eigen function will hang in a infinite loop, so bail out before this happens. */ /* Could we return loglik = -Inf instead of halting by setting error code? return all zeros for pmat in that case? Doesn't help convergence with test case in test/rory.r: lik stays at zero. */ if (!R_FINITE(matt[i])){ /* *err = -1; return; */ error("numerical overflow in calculating likelihood\n"); } } expm(matt, *n, expmat, Ward_2); } Free(matt); } /* Returns i-j transition intensity time t given vectors of intensities and transition indicators */ /* Calculates the whole transition matrix in time t given an intensity matrix */ void Pmat(Matrix pmat, double t, Matrix qmat, int nstates, int exacttimes, int iso, ivector perm, ivector qperm, int use_expm) { int i,j,method=MEXP_PADE,degen=0,err=0; double pii; if (exacttimes) { for (i=0; i 1 - DBL_EPSILON) pmat[MI(i, j, nstates)] = 1; } } } double pijdeath(int r, int s, Matrix pmat, Matrix qmat, int n) { int j; double contrib; if (r == s) return 1; /* absorbing-same absorbing transition has probability 1 */ else { /* sum over unobserved state at the previous instant */ contrib = 0; for (j = 0; j < n; ++j) if (j != s) { contrib += pmat[MI(r, j, n)] * qmat[MI(j,s,n)]; } } return contrib; } /*************************************************** CODE FOR DERIVATIVES OF P MATRIX. ***************************************************/ /* qij exp (qii t) dqij exp(qii t) + dqii qij t exp(qii t) exp(qii t) ( dqij + dqii qij t ) or exp(qii t) if diag */ void DPmatEXACT(Array3 dqmat, Matrix qmat, int n, int npars, Array3 dpmat, double t) { int i,j,p; for (i=0; i 0) REprintf("error code %d from EISPACK eigensystem routine rg\n", err); if (repeated_entries (revals, n)) { DMatrixExpSeries(dqmat, qmat, n, npars, dpmat, t); } else { MatInv(evecs, evecsinv, n); for (p=0; p