From 4dea065e151f3a07cb3c121bfb551da7614c164b Mon Sep 17 00:00:00 2001 From: gowerc Date: Wed, 19 Feb 2025 12:59:17 +0000 Subject: [PATCH 1/9] Add saveObject function --- NAMESPACE | 2 ++ R/JointModelSamples.R | 23 +++++++++++++++++++++ R/generics.R | 14 +++++++++++++ _pkgdown.yml | 2 ++ design/examples/quantity_plots.R | 5 +++++ man/as.CmdStanMCMC.Rd | 2 +- man/saveObject.JointModelSamples.Rd | 21 +++++++++++++++++++ man/saveObject.Rd | 19 +++++++++++++++++ tests/testthat/test-JointModelSamples.R | 27 +++++++++++++++++++++++++ 9 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 man/saveObject.JointModelSamples.Rd create mode 100644 man/saveObject.Rd diff --git a/NAMESPACE b/NAMESPACE index 4313391b..288fb843 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -162,6 +162,7 @@ S3method(sampleSubjects,SimLongitudinalGSF) S3method(sampleSubjects,SimLongitudinalRandomSlope) S3method(sampleSubjects,SimLongitudinalSteinFojo) S3method(sampleSubjects,SimSurvival) +S3method(saveObject,JointModelSamples) S3method(set_limits,Prior) S3method(size,Parameter) S3method(size,ParameterList) @@ -255,6 +256,7 @@ export(resolvePromise) export(sampleObservations) export(sampleStanModel) export(sampleSubjects) +export(saveObject) export(set_limits) export(show) export(write_stan) diff --git a/R/JointModelSamples.R b/R/JointModelSamples.R index f9537330..b9af1d93 100644 --- a/R/JointModelSamples.R +++ b/R/JointModelSamples.R @@ -144,3 +144,26 @@ setMethod( as.CmdStanMCMC.JointModelSamples <- function(object, ...) { return(object@results) } + + +#' Save a `JointModelSamples` object to a file. +#' +#' This function is just a wrapper around `saveRDS` that saves the object to a file +#' ensuring that all of the Stan samples are correctly stored. Note that as +#' CmdStanR objects store their samples as a csv file the samples may be lost +#' if you call `saveRDS` directly on the object. +#' +#' @param object ([`JointModelSamples`])\cr the object to save. +#' @param file (`character`)\cr the file to save the object to. +#' @param ... (`ANY`)\cr additional arguments to [`saveRDS`]. +#' +#' @family saveObject +#' +#' @export +saveObject.JointModelSamples <- function(object, file, ...) { + object@results$draws() + try(object@results$sampler_diagnostics(), silent = TRUE) + try(object@results$init(), silent = TRUE) + try(object@results$profiles(), silent = TRUE) + saveRDS(object, file, ...) +} diff --git a/R/generics.R b/R/generics.R index 4b09a0fb..78e50296 100755 --- a/R/generics.R +++ b/R/generics.R @@ -471,3 +471,17 @@ as_formula.default <- function(x, ...) { set_limits <- function(object, lower = -Inf, upper = Inf) { UseMethod("set_limits") } + + + +#' Save Object to File +#' +#' @param object (`ANY`) \cr object to save. +#' @param file (`character`) \cr file to save object to. +#' @param ... (`ANY`) \cr additional arguments. +#' +#' @family saveObject +#' @export +saveObject <- function(object, file, ...) { + UseMethod("saveObject") +} diff --git a/_pkgdown.yml b/_pkgdown.yml index 41a4490b..57c42d7f 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -168,6 +168,8 @@ reference: - as.list.StanModule - as.list.Link - as.list.LinkComponent + - saveObject + - saveObject.JointModelSamples - length.Link - subset.DataJoint - extractVariableNames.DataLongitudinal diff --git a/design/examples/quantity_plots.R b/design/examples/quantity_plots.R index 9471f43a..7345dd6b 100644 --- a/design/examples/quantity_plots.R +++ b/design/examples/quantity_plots.R @@ -3,6 +3,7 @@ library(jmpost) library(dplyr) library(ggplot2) library(tidyr) +library(cmdstanr) ############################ @@ -132,6 +133,10 @@ mp <- sampleStanModel( # get the raw stan object for subsequent processing stanobj <- as.CmdStanMCMC(mp) +stanobj$save_object("local/mod.Rds") +x <- readRDS("local/mod.Rds") +x +str(x) ############################ diff --git a/man/as.CmdStanMCMC.Rd b/man/as.CmdStanMCMC.Rd index 775fae8e..ef4f50c3 100644 --- a/man/as.CmdStanMCMC.Rd +++ b/man/as.CmdStanMCMC.Rd @@ -5,7 +5,7 @@ \alias{as.CmdStanMCMC} \title{Coerce to \code{CmdStanMCMC}} \usage{ -as.CmdStanMCMC.JointModelSamples(object, ...) +\method{as.CmdStanMCMC}{JointModelSamples}(object, ...) } \arguments{ \item{object}{to be converted} diff --git a/man/saveObject.JointModelSamples.Rd b/man/saveObject.JointModelSamples.Rd new file mode 100644 index 00000000..26623f8d --- /dev/null +++ b/man/saveObject.JointModelSamples.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/JointModelSamples.R +\name{saveObject.JointModelSamples} +\alias{saveObject.JointModelSamples} +\title{Save a \code{JointModelSamples} object to a file.} +\usage{ +\method{saveObject}{JointModelSamples}(object, file, ...) +} +\arguments{ +\item{object}{(\code{\link{JointModelSamples}})\cr the object to save.} + +\item{file}{(\code{character})\cr the file to save the object to.} + +\item{...}{(\code{ANY})\cr additional arguments to \code{saveRDS}.} +} +\description{ +This function is just a wrapper around \code{saveRDS} that saves the object to a file +ensuring that all of the Stan samples are correctly stored. Note that as +CmdStanR objects store their samples as a csv file the samples may be lost +if you call \code{saveRDS} directly on the object. +} diff --git a/man/saveObject.Rd b/man/saveObject.Rd new file mode 100644 index 00000000..8db18e2f --- /dev/null +++ b/man/saveObject.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/generics.R +\name{saveObject} +\alias{saveObject} +\title{Save Object to File} +\usage{ +saveObject(object, file, ...) +} +\arguments{ +\item{object}{(\code{ANY}) \cr object to save.} + +\item{file}{(\code{character}) \cr file to save object to.} + +\item{...}{(\code{ANY}) \cr additional arguments.} +} +\description{ +Save Object to File +} +\concept{saveObject} diff --git a/tests/testthat/test-JointModelSamples.R b/tests/testthat/test-JointModelSamples.R index 886d2100..dbd816df 100644 --- a/tests/testthat/test-JointModelSamples.R +++ b/tests/testthat/test-JointModelSamples.R @@ -6,3 +6,30 @@ test_that("print works as expected for JointModelSamples", { print(test_data_1$jsamples) }) }) + + + +test_that("saving and restoring samples from disk works as expected", { + samps <- test_data_1$jsamples + + tfile <- tempfile(fileext = ".Rds") + saveObject(samps, file = tfile) + + samps2 <- readRDS(tfile) + + # Can't compare entire object as some components contain formulas + # whose environment component will be different no matter what + expect_equal( + samps@data@survival@data, + samps2@data@survival@data + ) + expect_equal( + samps@data@longitudinal@data, + samps2@data@longitudinal@data + ) + # Key bit is that the retieved samples are identical + expect_equal( + posterior::as_draws_df(samps@results), + posterior::as_draws_df(samps2@results) + ) +}) From f70ced11b0221a3a5bb6188985ec85c68063ba75 Mon Sep 17 00:00:00 2001 From: gowerc Date: Wed, 19 Feb 2025 13:01:27 +0000 Subject: [PATCH 2/9] Clean up lingering test code --- design/examples/quantity_plots.R | 4 ---- 1 file changed, 4 deletions(-) diff --git a/design/examples/quantity_plots.R b/design/examples/quantity_plots.R index 7345dd6b..ccac9a3c 100644 --- a/design/examples/quantity_plots.R +++ b/design/examples/quantity_plots.R @@ -133,10 +133,6 @@ mp <- sampleStanModel( # get the raw stan object for subsequent processing stanobj <- as.CmdStanMCMC(mp) -stanobj$save_object("local/mod.Rds") -x <- readRDS("local/mod.Rds") -x -str(x) ############################ From 2b19c2ca6251eda4c958d7e5c2d05f88e9a0ff57 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 13:04:32 +0000 Subject: [PATCH 3/9] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/as.CmdStanMCMC.Rd | 2 +- man/saveObject.JointModelSamples.Rd | 7 ++++++- man/saveObject.Rd | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/man/as.CmdStanMCMC.Rd b/man/as.CmdStanMCMC.Rd index ef4f50c3..775fae8e 100644 --- a/man/as.CmdStanMCMC.Rd +++ b/man/as.CmdStanMCMC.Rd @@ -5,7 +5,7 @@ \alias{as.CmdStanMCMC} \title{Coerce to \code{CmdStanMCMC}} \usage{ -\method{as.CmdStanMCMC}{JointModelSamples}(object, ...) +as.CmdStanMCMC.JointModelSamples(object, ...) } \arguments{ \item{object}{to be converted} diff --git a/man/saveObject.JointModelSamples.Rd b/man/saveObject.JointModelSamples.Rd index 26623f8d..24db8021 100644 --- a/man/saveObject.JointModelSamples.Rd +++ b/man/saveObject.JointModelSamples.Rd @@ -11,7 +11,7 @@ \item{file}{(\code{character})\cr the file to save the object to.} -\item{...}{(\code{ANY})\cr additional arguments to \code{saveRDS}.} +\item{...}{(\code{ANY})\cr additional arguments to \code{\link{saveRDS}}.} } \description{ This function is just a wrapper around \code{saveRDS} that saves the object to a file @@ -19,3 +19,8 @@ ensuring that all of the Stan samples are correctly stored. Note that as CmdStanR objects store their samples as a csv file the samples may be lost if you call \code{saveRDS} directly on the object. } +\seealso{ +Other saveObject: +\code{\link{saveObject}()} +} +\concept{saveObject} diff --git a/man/saveObject.Rd b/man/saveObject.Rd index 8db18e2f..525163f1 100644 --- a/man/saveObject.Rd +++ b/man/saveObject.Rd @@ -16,4 +16,8 @@ saveObject(object, file, ...) \description{ Save Object to File } +\seealso{ +Other saveObject: +\code{\link{saveObject.JointModelSamples}()} +} \concept{saveObject} From 90e8ab095f5c82f4e4155801d2b6debaca21a83f Mon Sep 17 00:00:00 2001 From: gowerc Date: Wed, 19 Feb 2025 13:15:22 +0000 Subject: [PATCH 4/9] fix spelligns --- R/JointModelSamples.R | 2 +- inst/WORDLIST | 2 ++ man/as.CmdStanMCMC.Rd | 2 +- man/saveObject.JointModelSamples.Rd | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/R/JointModelSamples.R b/R/JointModelSamples.R index b9af1d93..18463b4e 100644 --- a/R/JointModelSamples.R +++ b/R/JointModelSamples.R @@ -150,7 +150,7 @@ as.CmdStanMCMC.JointModelSamples <- function(object, ...) { #' #' This function is just a wrapper around `saveRDS` that saves the object to a file #' ensuring that all of the Stan samples are correctly stored. Note that as -#' CmdStanR objects store their samples as a csv file the samples may be lost +#' `cmdstanr` objects store their samples as a csv file the samples may be lost #' if you call `saveRDS` directly on the object. #' #' @param object ([`JointModelSamples`])\cr the object to save. diff --git a/inst/WORDLIST b/inst/WORDLIST index ab3f1f57..5fb882e7 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -142,3 +142,5 @@ du int pk LogitNormal +csv +saveObject diff --git a/man/as.CmdStanMCMC.Rd b/man/as.CmdStanMCMC.Rd index 775fae8e..ef4f50c3 100644 --- a/man/as.CmdStanMCMC.Rd +++ b/man/as.CmdStanMCMC.Rd @@ -5,7 +5,7 @@ \alias{as.CmdStanMCMC} \title{Coerce to \code{CmdStanMCMC}} \usage{ -as.CmdStanMCMC.JointModelSamples(object, ...) +\method{as.CmdStanMCMC}{JointModelSamples}(object, ...) } \arguments{ \item{object}{to be converted} diff --git a/man/saveObject.JointModelSamples.Rd b/man/saveObject.JointModelSamples.Rd index 24db8021..5836dd44 100644 --- a/man/saveObject.JointModelSamples.Rd +++ b/man/saveObject.JointModelSamples.Rd @@ -16,7 +16,7 @@ \description{ This function is just a wrapper around \code{saveRDS} that saves the object to a file ensuring that all of the Stan samples are correctly stored. Note that as -CmdStanR objects store their samples as a csv file the samples may be lost +\code{cmdstanr} objects store their samples as a csv file the samples may be lost if you call \code{saveRDS} directly on the object. } \seealso{ From 8a18eddd9571f5d639831bf081014ccadf751863 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 13:18:19 +0000 Subject: [PATCH 5/9] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/as.CmdStanMCMC.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/as.CmdStanMCMC.Rd b/man/as.CmdStanMCMC.Rd index ef4f50c3..775fae8e 100644 --- a/man/as.CmdStanMCMC.Rd +++ b/man/as.CmdStanMCMC.Rd @@ -5,7 +5,7 @@ \alias{as.CmdStanMCMC} \title{Coerce to \code{CmdStanMCMC}} \usage{ -\method{as.CmdStanMCMC}{JointModelSamples}(object, ...) +as.CmdStanMCMC.JointModelSamples(object, ...) } \arguments{ \item{object}{to be converted} From fd59c50ca2e2739c3fec12889a512270834ea461 Mon Sep 17 00:00:00 2001 From: gowerc Date: Thu, 20 Feb 2025 09:17:20 +0000 Subject: [PATCH 6/9] updated news --- NEWS.md | 11 +++++++++++ inst/WORDLIST | 2 ++ 2 files changed, 13 insertions(+) diff --git a/NEWS.md b/NEWS.md index c19b1d8b..dc837359 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,14 @@ + +# jmpost Development Version + +- Introduced the `saveObject()` method for `JointModelSample` objects in order to serialise them to disk (#431). +- Added support for truncated prior distributions e.g. you can now apply a normal prior to a strictly positive parameter and jmpost will take care of adjusting the density accordingly (#429). +- Included new Gamma distribution survival model (#411). +- Reworked LOO calculations to apply to each individual submodel and disabled LOO calculations for the overall joint model (#402). +- Added support for additive variance (#403). +- Added support for independent variances per study/arm (#389). +- Miscellaneous bug fixes. + # jmpost 0.0.1 - Initial Release diff --git a/inst/WORDLIST b/inst/WORDLIST index 5fb882e7..c3d07be5 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -144,3 +144,5 @@ pk LogitNormal csv saveObject +submodel +serialise From a9c37b5b801343b49f43c685c243c54ff003e482 Mon Sep 17 00:00:00 2001 From: gowerc Date: Thu, 20 Feb 2025 09:18:35 +0000 Subject: [PATCH 7/9] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 40fc3f6a..53153cb5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: jmpost Title: Joint Models for Predicting Overall Survival Trajectories -Version: 0.0.1 +Version: 0.0.1.9000 Authors@R: c( person("Craig", "Gower-Page", email = "craig.gower-page@roche.com", role = c("aut", "cre")), person("Francois", "Mercier", email = "francois.mercier@roche.com", role = "aut"), From 47d11f867ef280781796b16f552fef9f04a5b74d Mon Sep 17 00:00:00 2001 From: gowerc Date: Thu, 20 Feb 2025 10:00:40 +0000 Subject: [PATCH 8/9] fixed news --- .github/workflows/check.yaml | 6 +++--- NEWS.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 874eefbb..31aec58f 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -73,9 +73,9 @@ jobs: link-checking-method: lychee lychee-additional-args: "" # override the default of excluding private links lychee-fail: true - version: - name: Version Check 🏁 - uses: insightsengineering/r.pkg.template/.github/workflows/version.yaml@main + # version: + # name: Version Check 🏁 + # uses: insightsengineering/r.pkg.template/.github/workflows/version.yaml@main licenses: name: License Check 🃏 uses: insightsengineering/r.pkg.template/.github/workflows/licenses.yaml@main diff --git a/NEWS.md b/NEWS.md index dc837359..be9de36f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,5 @@ -# jmpost Development Version +# jmpost (development version) - Introduced the `saveObject()` method for `JointModelSample` objects in order to serialise them to disk (#431). - Added support for truncated prior distributions e.g. you can now apply a normal prior to a strictly positive parameter and jmpost will take care of adjusting the density accordingly (#429). From 7686e684870d8e72811294e67bd6dc6670bccbfb Mon Sep 17 00:00:00 2001 From: gowerc Date: Thu, 20 Feb 2025 10:01:46 +0000 Subject: [PATCH 9/9] reenable version check --- .github/workflows/check.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 31aec58f..874eefbb 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -73,9 +73,9 @@ jobs: link-checking-method: lychee lychee-additional-args: "" # override the default of excluding private links lychee-fail: true - # version: - # name: Version Check 🏁 - # uses: insightsengineering/r.pkg.template/.github/workflows/version.yaml@main + version: + name: Version Check 🏁 + uses: insightsengineering/r.pkg.template/.github/workflows/version.yaml@main licenses: name: License Check 🃏 uses: insightsengineering/r.pkg.template/.github/workflows/licenses.yaml@main