├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── check-standard.yaml │ ├── pkgdown.yaml │ └── test-coverage.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── curve_cont.r ├── curve_cont_auc.r ├── get_kaplan_meier.r ├── helper_functions.r ├── input_checks.r ├── plot_surv_3Dsurface.r ├── plot_surv_animated.r ├── plot_surv_area.r ├── plot_surv_at_t.r ├── plot_surv_contour.r ├── plot_surv_heatmap.r ├── plot_surv_lines.r ├── plot_surv_matrix.r ├── plot_surv_quantiles.r ├── plot_surv_rmst.r ├── plot_surv_rmtl.r └── zzz.r ├── README.md ├── TODO.txt ├── _pkgdown.yml ├── codecov.yml ├── codemeta.json ├── contsurvplot.Rproj ├── cran-comments.md ├── docs ├── .nojekyll ├── 404.html ├── LICENSE.html ├── apple-touch-icon-120x120.png ├── apple-touch-icon-152x152.png ├── apple-touch-icon-180x180.png ├── apple-touch-icon-60x60.png ├── apple-touch-icon-76x76.png ├── apple-touch-icon.png ├── articles │ ├── index.html │ ├── introduction.html │ └── introduction_files │ │ └── figure-html │ │ ├── unnamed-chunk-10-1.png │ │ ├── unnamed-chunk-11-1.png │ │ ├── unnamed-chunk-12-1.png │ │ ├── unnamed-chunk-13-1.png │ │ ├── unnamed-chunk-14-1.png │ │ ├── unnamed-chunk-15-1.png │ │ ├── unnamed-chunk-16-1.png │ │ ├── unnamed-chunk-17-1.png │ │ ├── unnamed-chunk-18-1.png │ │ ├── unnamed-chunk-19-1.png │ │ ├── unnamed-chunk-20-1.png │ │ ├── unnamed-chunk-21-1.png │ │ ├── unnamed-chunk-22-1.png │ │ ├── unnamed-chunk-26-1.png │ │ ├── unnamed-chunk-27-1.png │ │ ├── unnamed-chunk-7-1.png │ │ ├── unnamed-chunk-8-1.png │ │ └── unnamed-chunk-9-1.png ├── authors.html ├── deps │ ├── bootstrap-5.1.3 │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ └── bootstrap.min.css │ ├── data-deps.txt │ └── jquery-3.6.0 │ │ ├── jquery-3.6.0.js │ │ ├── jquery-3.6.0.min.js │ │ └── jquery-3.6.0.min.map ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── index.html ├── link.svg ├── logo.png ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── Rplot001.png │ ├── Rplot002.png │ ├── Rplot003.png │ ├── Rplot004.png │ ├── contsurvplot-package.html │ ├── curve_cont.html │ ├── figures │ │ ├── example_area.png │ │ ├── example_contour.png │ │ ├── example_quantiles.png │ │ └── logo.png │ ├── gganim_plot0001.png │ ├── gganim_plot0002.png │ ├── gganim_plot0003.png │ ├── gganim_plot0004.png │ ├── gganim_plot0005.png │ ├── gganim_plot0006.png │ ├── gganim_plot0007.png │ ├── gganim_plot0008.png │ ├── gganim_plot0009.png │ ├── gganim_plot0010.png │ ├── gganim_plot0011.png │ ├── gganim_plot0012.png │ ├── gganim_plot0013.png │ ├── gganim_plot0014.png │ ├── gganim_plot0015.png │ ├── gganim_plot0016.png │ ├── gganim_plot0017.png │ ├── gganim_plot0018.png │ ├── gganim_plot0019.png │ ├── gganim_plot0020.png │ ├── gganim_plot0021.png │ ├── gganim_plot0022.png │ ├── gganim_plot0023.png │ ├── gganim_plot0024.png │ ├── gganim_plot0025.png │ ├── gganim_plot0026.png │ ├── gganim_plot0027.png │ ├── gganim_plot0028.png │ ├── gganim_plot0029.png │ ├── gganim_plot0030.png │ ├── gganim_plot0031.png │ ├── gganim_plot0032.png │ ├── gganim_plot0033.png │ ├── gganim_plot0034.png │ ├── gganim_plot0035.png │ ├── gganim_plot0036.png │ ├── gganim_plot0037.png │ ├── gganim_plot0038.png │ ├── gganim_plot0039.png │ ├── gganim_plot0040.png │ ├── gganim_plot0041.png │ ├── gganim_plot0042.png │ ├── gganim_plot0043.png │ ├── gganim_plot0044.png │ ├── gganim_plot0045.png │ ├── gganim_plot0046.png │ ├── gganim_plot0047.png │ ├── gganim_plot0048.png │ ├── gganim_plot0049.png │ ├── gganim_plot0050.png │ ├── gganim_plot0051.png │ ├── gganim_plot0052.png │ ├── gganim_plot0053.png │ ├── gganim_plot0054.png │ ├── gganim_plot0055.png │ ├── gganim_plot0056.png │ ├── gganim_plot0057.png │ ├── gganim_plot0058.png │ ├── gganim_plot0059.png │ ├── gganim_plot0060.png │ ├── gganim_plot0061.png │ ├── gganim_plot0062.png │ ├── gganim_plot0063.png │ ├── gganim_plot0064.png │ ├── gganim_plot0065.png │ ├── gganim_plot0066.png │ ├── gganim_plot0067.png │ ├── gganim_plot0068.png │ ├── gganim_plot0069.png │ ├── gganim_plot0070.png │ ├── gganim_plot0071.png │ ├── gganim_plot0072.png │ ├── gganim_plot0073.png │ ├── gganim_plot0074.png │ ├── gganim_plot0075.png │ ├── gganim_plot0076.png │ ├── gganim_plot0077.png │ ├── gganim_plot0078.png │ ├── gganim_plot0079.png │ ├── gganim_plot0080.png │ ├── gganim_plot0081.png │ ├── gganim_plot0082.png │ ├── gganim_plot0083.png │ ├── gganim_plot0084.png │ ├── gganim_plot0085.png │ ├── gganim_plot0086.png │ ├── gganim_plot0087.png │ ├── gganim_plot0088.png │ ├── gganim_plot0089.png │ ├── gganim_plot0090.png │ ├── gganim_plot0091.png │ ├── gganim_plot0092.png │ ├── gganim_plot0093.png │ ├── gganim_plot0094.png │ ├── gganim_plot0095.png │ ├── gganim_plot0096.png │ ├── gganim_plot0097.png │ ├── gganim_plot0098.png │ ├── gganim_plot0099.png │ ├── gganim_plot0100.png │ ├── index.html │ ├── libs │ │ ├── crosstalk-1.2.0 │ │ │ ├── css │ │ │ │ └── crosstalk.min.css │ │ │ ├── js │ │ │ │ ├── crosstalk.js │ │ │ │ ├── crosstalk.js.map │ │ │ │ ├── crosstalk.min.js │ │ │ │ └── crosstalk.min.js.map │ │ │ └── scss │ │ │ │ └── crosstalk.scss │ │ ├── htmlwidgets-1.5.4 │ │ │ └── htmlwidgets.js │ │ ├── plotly-binding-4.10.0 │ │ │ └── plotly.js │ │ ├── plotly-htmlwidgets-css-2.5.1 │ │ │ └── plotly-htmlwidgets.css │ │ ├── plotly-main-2.5.1 │ │ │ └── plotly-latest.min.js │ │ └── typedarray-0.1 │ │ │ └── typedarray.min.js │ ├── plot_surv_3Dsurface-1.png │ ├── plot_surv_3Dsurface-2.png │ ├── plot_surv_3Dsurface.html │ ├── plot_surv_animated.html │ ├── plot_surv_area-1.png │ ├── plot_surv_area-2.png │ ├── plot_surv_area-3.png │ ├── plot_surv_area-4.png │ ├── plot_surv_area.html │ ├── plot_surv_at_t-1.png │ ├── plot_surv_at_t-2.png │ ├── plot_surv_at_t.html │ ├── plot_surv_contour-1.png │ ├── plot_surv_contour-2.png │ ├── plot_surv_contour-3.png │ ├── plot_surv_contour.html │ ├── plot_surv_heatmap-1.png │ ├── plot_surv_heatmap-2.png │ ├── plot_surv_heatmap-3.png │ ├── plot_surv_heatmap-4.png │ ├── plot_surv_heatmap.html │ ├── plot_surv_lines-1.png │ ├── plot_surv_lines-2.png │ ├── plot_surv_lines-3.png │ ├── plot_surv_lines.html │ ├── plot_surv_quantiles-1.png │ ├── plot_surv_quantiles-2.png │ ├── plot_surv_quantiles-3.png │ ├── plot_surv_quantiles.html │ ├── plot_surv_rmst-1.png │ ├── plot_surv_rmst-2.png │ ├── plot_surv_rmst-3.png │ ├── plot_surv_rmst.html │ ├── plot_surv_rmtl-1.png │ ├── plot_surv_rmtl-2.png │ ├── plot_surv_rmtl-3.png │ └── plot_surv_rmtl.html ├── search.json └── sitemap.xml ├── inst ├── CITATION └── testdata │ ├── sim150.Rds │ └── sim500.Rds ├── man ├── contsurvplot-package.Rd ├── curve_cont.Rd ├── figures │ ├── example_area.png │ ├── example_contour.png │ ├── example_quantiles.png │ └── logo.png ├── plot_surv_3Dsurface.Rd ├── plot_surv_animated.Rd ├── plot_surv_area.Rd ├── plot_surv_at_t.Rd ├── plot_surv_contour.Rd ├── plot_surv_heatmap.Rd ├── plot_surv_lines.Rd ├── plot_surv_matrix.Rd ├── plot_surv_quantiles.Rd ├── plot_surv_rmst.Rd └── plot_surv_rmtl.Rd ├── pkgdown └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── tests ├── testthat.R └── testthat │ ├── Rplots.pdf │ ├── _snaps │ ├── plot_surv_3Dsurface │ │ ├── plot-at-t.svg │ │ ├── plot-change-horizon.svg │ │ ├── plot-cif.svg │ │ ├── plot-custom-non-interactive.svg │ │ └── plot-defaults.svg │ ├── plot_surv_area │ │ ├── plot-at-t.svg │ │ ├── plot-change-horizon.svg │ │ ├── plot-cif.svg │ │ ├── plot-custom-colors.svg │ │ ├── plot-defaults.svg │ │ ├── plot-discrete-bins.svg │ │ ├── plot-discrete-round.svg │ │ ├── plot-lots-of-stuff.svg │ │ ├── plot-sep-lines.svg │ │ ├── plot-with-group.svg │ │ ├── plot-with-kaplan-meier.svg │ │ └── plot-with-nonmonotonic.svg │ ├── plot_surv_at_t │ │ ├── plot-change-horizon.svg │ │ ├── plot-cif.svg │ │ ├── plot-custom-colors.svg │ │ ├── plot-defaults.svg │ │ ├── plot-lots-of-stuff.svg │ │ ├── plot-with-ci-multiple-t.svg │ │ ├── plot-with-ci-one-t.svg │ │ └── plot-with-group.svg │ ├── plot_surv_contour │ │ ├── plot-at-t.svg │ │ ├── plot-change-horizon.svg │ │ ├── plot-cif.svg │ │ ├── plot-custom-colors.svg │ │ ├── plot-defaults.svg │ │ ├── plot-lots-of-stuff.svg │ │ ├── plot-panel-border-axis-dist.svg │ │ └── plot-with-group.svg │ ├── plot_surv_heatmap │ │ ├── plot-at-t.svg │ │ ├── plot-change-horizon.svg │ │ ├── plot-cif.svg │ │ ├── plot-contour-lines.svg │ │ ├── plot-custom-colors.svg │ │ ├── plot-defaults.svg │ │ ├── plot-lots-of-stuff.svg │ │ ├── plot-panel-border-axis-dist.svg │ │ └── plot-with-group.svg │ ├── plot_surv_lines │ │ ├── plot-at-t.svg │ │ ├── plot-change-horizon.svg │ │ ├── plot-cif.svg │ │ ├── plot-cont-color.svg │ │ ├── plot-custom-colors.svg │ │ ├── plot-defaults.svg │ │ ├── plot-kaplan-meier.svg │ │ ├── plot-lots-of-stuff.svg │ │ ├── plot-with-ci.svg │ │ └── plot-with-group.svg │ ├── plot_surv_matrix │ │ ├── plot-change-border-stuff.svg │ │ ├── plot-change-fixed-t.svg │ │ ├── plot-change-horizon.svg │ │ ├── plot-change-n-col-and-n-row.svg │ │ ├── plot-change-numbers-stuff.svg │ │ ├── plot-cif.svg │ │ ├── plot-custom-colors.svg │ │ ├── plot-defaults.svg │ │ ├── plot-panel-border-axis-dist.svg │ │ └── plot-using-group.svg │ ├── plot_surv_quantiles │ │ ├── plot-change-horizon.svg │ │ ├── plot-custom-colors.svg │ │ ├── plot-defaults.svg │ │ ├── plot-lots-of-stuff.svg │ │ ├── plot-single-colors.svg │ │ └── plot-with-group.svg │ ├── plot_surv_rmst │ │ ├── plot-change-horizon.svg │ │ ├── plot-custom-colors.svg │ │ ├── plot-defaults.svg │ │ ├── plot-lots-of-stuff.svg │ │ └── plot-with-group.svg │ └── plot_surv_rmtl │ │ ├── plot-change-horizon.svg │ │ ├── plot-custom-colors.svg │ │ ├── plot-defaults.svg │ │ ├── plot-lots-of-stuff.svg │ │ └── plot-with-group.svg │ ├── test_.onAttach.r │ ├── test_check_horizon.r │ ├── test_check_inputs_curve_cont.r │ ├── test_check_inputs_plots.r │ ├── test_check_inputs_surv_matrix.r │ ├── test_curve_cont.r │ ├── test_get_kaplan_meier.r │ ├── test_plot_surv_3Dsurface.r │ ├── test_plot_surv_animated.r │ ├── test_plot_surv_area.r │ ├── test_plot_surv_at_t.r │ ├── test_plot_surv_contour.r │ ├── test_plot_surv_heatmap.r │ ├── test_plot_surv_lines.r │ ├── test_plot_surv_matrix.r │ ├── test_plot_surv_quantiles.r │ ├── test_plot_surv_rmst.r │ ├── test_plot_surv_rmtl.r │ ├── test_prepare_inputdata.r │ └── test_read_from_step_function.r └── vignettes ├── .gitignore └── introduction.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^LICENSE\.md$ 4 | ^\.github$ 5 | ^codemeta\.json$ 6 | ^_pkgdown\.yml$ 7 | ^docs$ 8 | ^pkgdown$ 9 | ^codecov\.yml$ 10 | ^cran-comments\.md$ 11 | ^CRAN-SUBMISSION$ 12 | ^TODO\.txt$ 13 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/check-standard.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macos-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | 31 | steps: 32 | - uses: actions/checkout@v3 33 | 34 | - uses: r-lib/actions/setup-pandoc@v2 35 | 36 | - uses: r-lib/actions/setup-r@v2 37 | with: 38 | r-version: ${{ matrix.config.r }} 39 | http-user-agent: ${{ matrix.config.http-user-agent }} 40 | use-public-rspm: true 41 | 42 | - uses: r-lib/actions/setup-r-dependencies@v2 43 | with: 44 | extra-packages: any::rcmdcheck 45 | needs: check 46 | 47 | - uses: r-lib/actions/check-r-package@v2 48 | with: 49 | upload-snapshots: true 50 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | steps: 23 | - uses: actions/checkout@v3 24 | 25 | - uses: r-lib/actions/setup-pandoc@v2 26 | 27 | - uses: r-lib/actions/setup-r@v2 28 | with: 29 | use-public-rspm: true 30 | 31 | - uses: r-lib/actions/setup-r-dependencies@v2 32 | with: 33 | extra-packages: any::pkgdown, local::. 34 | needs: website 35 | 36 | - name: Build site 37 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 38 | shell: Rscript {0} 39 | 40 | - name: Deploy to GitHub pages 🚀 41 | if: github.event_name != 'pull_request' 42 | uses: JamesIves/github-pages-deploy-action@v4.4.1 43 | with: 44 | clean: false 45 | branch: gh-pages 46 | folder: docs 47 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: any::covr 27 | needs: coverage 28 | 29 | - name: Test coverage 30 | run: covr::codecov(quiet = FALSE) 31 | shell: Rscript {0} 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | docs 6 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: contsurvplot 2 | Title: Visualize the Effect of a Continuous Variable on a Time-to-Event Outcome 3 | Version: 0.2.1 4 | Authors@R: 5 | person("Robin", "Denz", , "robin.denz@rub.de", role = c("aut", "cre")) 6 | Maintainer: Robin Denz 7 | Description: Graphically display the (causal) effect of a continuous variable on a time-to-event outcome 8 | using multiple different types of plots based on g-computation. Those functions 9 | include, among others, survival area plots, survival contour plots, survival quantile plots and 10 | 3D surface plots. Due to the use of g-computation, all plot allow confounder-adjustment naturally. 11 | For details, see Robin Denz, Nina Timmesfeld (2023) . 12 | License: GPL (>= 3) 13 | URL: https://github.com/RobinDenz1/contsurvplot, 14 | https://robindenz1.github.io/contsurvplot/ 15 | BugReports: https://github.com/RobinDenz1/contsurvplot/issues 16 | Imports: 17 | ggplot2 (>= 3.4.0), 18 | dplyr, 19 | rlang, 20 | riskRegression, 21 | foreach 22 | Suggests: 23 | survival, 24 | pammtools, 25 | gganimate, 26 | transformr, 27 | plotly, 28 | reshape2, 29 | doParallel, 30 | knitr, 31 | rmarkdown, 32 | testthat (>= 3.0.0), 33 | vdiffr (>= 1.0.0), 34 | covr 35 | VignetteBuilder: 36 | knitr 37 | Config/testthat/edition: 3 38 | Contact: 39 | Encoding: UTF-8 40 | Roxygen: list(markdown = TRUE) 41 | RoxygenNote: 7.2.3 42 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(curve_cont) 4 | export(plot_surv_3Dsurface) 5 | export(plot_surv_animated) 6 | export(plot_surv_area) 7 | export(plot_surv_at_t) 8 | export(plot_surv_contour) 9 | export(plot_surv_heatmap) 10 | export(plot_surv_lines) 11 | export(plot_surv_matrix) 12 | export(plot_surv_quantiles) 13 | export(plot_surv_rmst) 14 | export(plot_surv_rmtl) 15 | importFrom(dplyr,"%>%") 16 | importFrom(foreach,"%dopar%") 17 | importFrom(rlang,.data) 18 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # contsurvplot 0.1.0 2 | 3 | * This is the first release of this package 4 | * Added a reference to the main paper to the description file 5 | 6 | # contsurvplot 0.2.0 7 | 8 | Enhancements: 9 | 10 | * Installation instructions in vignette and README were updated to include CRAN 11 | * Re-worked the documentation page of the `curve_cont` function 12 | 13 | Bug fixes: 14 | 15 | * plot_surv_animated now uses `gganimate::transition_manual()` internally, ruling out interpolation errors 16 | * There are no slight differences in the outlines of the areas when using `plot_surv_area` with `discrete=TRUE` and `discrete=FALSE` anymore 17 | 18 | New Features: 19 | 20 | * Added `plot_surv_matrix` function 21 | * Added support for bootstrap standard error and confidence interval calculation in the `curve_cont` function 22 | * Added support for causal contrasts in `curve_cont` function, which also makes it possible to use those directly in all plot functions 23 | * Added support for bootstrap confidence intervals in the `plot_surv_at_t`, `plot_surv_lines` and `plot_surv_animated` functions 24 | * Added support for plotting Kaplan-Meier curves as reference in `plot_surv_area`, `plot_surv_animated`, `plot_surv_lines` 25 | * Added the `monotonic` argument in the `plot_surv_area` function to allow plotting curved relationships 26 | * Vignette now includes `plot_surv_matrix` function 27 | 28 | # contsurvplot 0.2.1 29 | 30 | Documentation: 31 | 32 | * Updated citation information to include published manuscript 33 | -------------------------------------------------------------------------------- /R/curve_cont_auc.r: -------------------------------------------------------------------------------- 1 | 2 | ## small function to estimate rmtl from plotdata 3 | cont_surv_auc <- function(plotdata, tau) { 4 | 5 | plotdata$group <- as.factor(plotdata$cont) 6 | plotdata$surv <- plotdata$est 7 | plotdata$est <- NULL 8 | plotdata$cont <- NULL 9 | 10 | levs <- levels(plotdata$group) 11 | 12 | out <- vector(mode="list", length=length(tau)*length(levs)) 13 | count <- 0 14 | for (i in seq_len(length(tau))) { 15 | for (j in seq_len(length(levs))) { 16 | count <- count + 1 17 | 18 | data_j <- plotdata[plotdata$group==levs[j], ] 19 | 20 | # constrain function end 21 | latest <- read_from_step_function(tau[i], data_j, est="surv", time="time") 22 | data_j <- data_j[data_j$time <= tau[i], ] 23 | data_j$group <- NULL 24 | 25 | if (!tau[i] %in% data_j$time) { 26 | temp <- data.frame(time=tau[i], 27 | surv=latest) 28 | data_j <- rbind(data_j, temp) 29 | } 30 | 31 | # calculate rmst 32 | area <- stepfun_integral(x=data_j$time, y=data_j$surv) 33 | 34 | row <- data.frame(cont=as.numeric(as.character(levs[j])), 35 | auc=area, 36 | tau=tau[i]) 37 | out[[count]] <- row 38 | } 39 | } 40 | out <- dplyr::bind_rows(out) 41 | out$tau <- as.factor(out$tau) 42 | 43 | return(out) 44 | } 45 | 46 | curve_cont_auc <- function(data, variable, model, horizon=NULL, 47 | group=NULL, cause=1, cif=FALSE, 48 | tau, ...) { 49 | 50 | # default horizon 51 | if (is.null(horizon)) { 52 | horizon <- seq(min(data[, variable]), max(data[, variable]), 53 | length.out=100) 54 | } 55 | 56 | # needed points in time 57 | fixed_t <- c(0, sort(unique(data[, time][data[, status] >= 1]))) 58 | 59 | # get survival probabilities / CIFs 60 | plotdata <- curve_cont(data=data, 61 | variable=variable, 62 | group=group, 63 | model=model, 64 | horizon=horizon, 65 | times=fixed_t, 66 | na.action="na.fail", 67 | event_time=time, 68 | event_status=status, 69 | cif=cif, 70 | cause=cause, 71 | ...) 72 | 73 | if (is.null(group)) { 74 | out <- cont_surv_auc(plotdata=plotdata, tau=tau) 75 | } else { 76 | group_levs <- levels(plotdata$group) 77 | out <- vector(mode="list", length=length(group_levs)) 78 | for (i in seq_len(length(group_levs))) { 79 | temp <- plotdata[plotdata$group==group_levs[i], ] 80 | out_i <- cont_surv_auc(plotdata=temp, tau=tau) 81 | out_i$group <- group_levs[i] 82 | out[[i]] <- out_i 83 | } 84 | out <- dplyr::bind_rows(out) 85 | } 86 | 87 | return(out) 88 | } 89 | 90 | -------------------------------------------------------------------------------- /R/get_kaplan_meier.r: -------------------------------------------------------------------------------- 1 | 2 | ## wrapper function to get an overall kaplan-meier estimate 3 | get_kaplan_meier <- function(time, status, group=NULL, data, conf_int=FALSE, 4 | conf_type="plain", conf_level=0.95, 5 | cif=FALSE, fixed_t=NULL, ...) { 6 | # get formula 7 | if (is.null(group)) { 8 | form <- stats::as.formula(paste0("survival::Surv(", time, ", ", 9 | status, ") ~ 1")) 10 | } else { 11 | form <- stats::as.formula(paste0("survival::Surv(", time, ", ", 12 | status, ") ~ ", group)) 13 | } 14 | 15 | # estimate kaplan-meier 16 | survf <- survival::survfit(formula=form, data=data, se.fit=conf_int, 17 | conf.int=conf_level, conf.type=conf_type, ...) 18 | 19 | km_dat <- data.frame(time=survf$time, 20 | est=survf$surv) 21 | 22 | # add group variable, if specified 23 | if (!is.null(group)) { 24 | km_group <- c() 25 | for (strat in names(survf$strata)) { 26 | km_group <- c(km_group, rep(strat, survf$strata[strat])) 27 | } 28 | km_group <- gsub(paste0(group, "="), "", km_group) 29 | km_dat$group <- factor(km_group, levels=levels(data[, group])) 30 | } 31 | 32 | # add confidence interval 33 | if (conf_int) { 34 | km_dat$ci_lower <- survf$lower 35 | km_dat$ci_upper <- survf$upper 36 | } 37 | 38 | # add rows at t = 0 39 | if (is.null(group) & conf_int) { 40 | row_0 <- data.frame(time=0, est=1, ci_lower=1, ci_upper=1) 41 | } else if (is.null(group)) { 42 | row_0 <- data.frame(time=0, est=1) 43 | } else if (!is.null(group) & conf_int) { 44 | row_0 <- data.frame(time=0, est=1, group=levels(data[, group]), 45 | ci_lower=1, ci_upper=1) 46 | } else { 47 | row_0 <- data.frame(time=0, est=1, group=levels(data[, group])) 48 | } 49 | km_dat <- rbind(row_0, km_dat) 50 | 51 | # read at specific points in time 52 | # NOTE: this ignores confidence intervals and se, because those are never 53 | # used when using fixed_t 54 | if (!is.null(fixed_t)) { 55 | km_dat <- km_at_t(data=km_dat, times=fixed_t, group=group) 56 | } 57 | 58 | # turn to cif 59 | if (cif) { 60 | km_dat$est <- 1 - km_dat$est 61 | if ("ci_lower" %in% colnames(km_dat)) { 62 | km_dat$ci_lower <- 1 - km_dat$ci_lower 63 | km_dat$ci_upper <- 1 - km_dat$ci_upper 64 | } 65 | } 66 | 67 | return(km_dat) 68 | } 69 | 70 | ## function to get kaplan-meier estimates at t using interpolation 71 | km_at_t <- function(data, times, group) { 72 | 73 | d_ref <- data[, c("time", "est")] 74 | 75 | if (is.null(group)) { 76 | d_ref <- d_ref[order(d_ref$time), ] 77 | d_ref <- data.frame(time=times, 78 | est=vapply(X=times, 79 | FUN=read_from_step_function, 80 | FUN.VALUE=numeric(1), 81 | data=d_ref, 82 | est="est")) 83 | } else { 84 | levs <- unique(data$group) 85 | out <- vector(mode="list", length=length(levs)) 86 | for (i in seq_len(length(levs))) { 87 | d_temp <- d_ref[data$group==levs[i], ] 88 | d_temp <- d_temp[order(d_temp$time), ] 89 | d_temp <- data.frame(time=times, 90 | est=vapply(X=times, 91 | FUN=read_from_step_function, 92 | FUN.VALUE=numeric(1), 93 | data=d_temp, 94 | est="est")) 95 | d_temp$group <- levs[i] 96 | out[[i]] <- d_temp 97 | } 98 | d_ref <- dplyr::bind_rows(out) 99 | } 100 | 101 | return(d_ref) 102 | } 103 | -------------------------------------------------------------------------------- /R/helper_functions.r: -------------------------------------------------------------------------------- 1 | 2 | ## keep only the covariates needed for the analysis 3 | ## this has to be done in order to correctly use na.action 4 | remove_unnecessary_covars <- function(data, time, status, variable, 5 | group, model) { 6 | 7 | # extract variables from outcome model 8 | if (inherits(model, c("coxph", "mexhaz"))) { 9 | model_vars <- all.vars(model$formula) 10 | } else if (inherits(model, c("CauseSpecificCox", "FGR", "aalen", 11 | "cox.aalen", "flexsurvreg", 12 | "pecCforest", "prodlim", 13 | "psm", "randomForest", 14 | "riskRegression", "selectCox", 15 | "glm", "ols", "rfsrc", 16 | "penfitS3", "gbm", 17 | "singleEventCB", "fcrr", 18 | "comprisk"))) { 19 | model_vars <- all.vars(model$call$formula) 20 | } else if (inherits(model, "pecRpart")) { 21 | model_vars <- all.vars(model$rpart$terms) 22 | } else if (inherits(model, "ranger")) { 23 | model_vars <- all.vars(model$call[[2]]) 24 | } else { 25 | model_vars <- NULL 26 | } 27 | 28 | # covariates that are always needed 29 | needed_covars <- c(time, status, variable, model_vars, group) 30 | 31 | # remove duplicates 32 | needed_covars <- unique(needed_covars) 33 | 34 | # filter data 35 | data <- dplyr::select(data, dplyr::all_of(needed_covars)) 36 | 37 | return(data) 38 | } 39 | 40 | ## composite function to prepare the data for further use 41 | prepare_inputdata <- function(data, time, status, variable, group, model, 42 | na.action) { 43 | 44 | # keep only needed columns 45 | data <- remove_unnecessary_covars(data=data, time=time, status=status, 46 | variable=variable, model=model, 47 | group=group) 48 | 49 | # perform na.action 50 | if (is.function(na.action)) { 51 | data <- na.action(data) 52 | } else { 53 | na.action <- get(na.action) 54 | data <- na.action(data) 55 | } 56 | 57 | if (nrow(data)==0) { 58 | stop("There is no data left after removing the missing values.") 59 | } 60 | 61 | return(data) 62 | } 63 | 64 | ## use only data.frame methods, no tibbles etc. 65 | use_data.frame <- function(data) { 66 | # correct data type 67 | if (!inherits(data, "data.frame")) { 68 | stop("'data' must be a data.frame object.") 69 | } else { 70 | data <- as.data.frame(data) 71 | } 72 | return(data) 73 | } 74 | 75 | ## takes a value x at which to read from the step function 76 | ## and step function data from which to read it 77 | read_from_step_function <- function(x, data, est="surv", time="time") { 78 | 79 | # keep only data with non-missing est 80 | data <- data[which(!is.na(data[, est])), ] 81 | 82 | # no extrapolation 83 | if (x > max(data[, time])) { 84 | return(NA) 85 | } 86 | 87 | # otherwise get value 88 | check <- data[which(data[, time] <= x), ] 89 | if (nrow(check)==0) { 90 | if (est=="surv") { 91 | val <- 1 92 | } else if (est=="cif") { 93 | val <- 0 94 | } else { 95 | val <- NA 96 | } 97 | } else { 98 | val <- check[, est][which(check[, time]==max(check[, time]))][1] 99 | } 100 | return(val) 101 | } 102 | 103 | ## calculate exact integral of a step function 104 | stepfun_integral <- function(x, y) { 105 | area <- 0 106 | for (i in seq_len((length(x)-1))) { 107 | x1 <- x[i] 108 | x2 <- x[i+1] 109 | rect_area <- (x2 - x1) * y[i] 110 | area <- area + rect_area 111 | } 112 | return(area) 113 | } 114 | -------------------------------------------------------------------------------- /R/plot_surv_3Dsurface.r: -------------------------------------------------------------------------------- 1 | 2 | ## function to plot the continuous survival area as a 3D surface 3 | #' @importFrom dplyr %>% 4 | #' @export 5 | plot_surv_3Dsurface <- function(time, status, variable, data, model, 6 | cif=FALSE, na.action=options()$na.action, 7 | horizon=NULL, fixed_t=NULL, max_t=Inf, 8 | interactive=FALSE, 9 | xlab="Time", ylab="Survival Probability", 10 | zlab=variable, ticktype="detailed", 11 | theta=120, phi=20, col="green", shade=0.5, 12 | ...) { 13 | requireNamespace("reshape2") 14 | 15 | data <- use_data.frame(data) 16 | 17 | check_inputs_plots(time=time, status=status, variable=variable, 18 | data=data, model=model, na.action=na.action, 19 | horizon=horizon, fixed_t=fixed_t, max_t=max_t, 20 | discrete=TRUE, panel_border=TRUE, t=1, tau=1, 21 | group=NULL) 22 | 23 | data <- prepare_inputdata(data=data, time=time, status=status, 24 | variable=variable, model=model, 25 | group=NULL, na.action=na.action) 26 | 27 | if (is.null(fixed_t)) { 28 | fixed_t <- seq(min(data[, time]), max(data[, time]), length.out=100) 29 | } 30 | if (is.null(horizon)) { 31 | horizon <- seq(min(data[, variable]), max(data[, variable]), length.out=40) 32 | } 33 | 34 | # only show up to max_t 35 | fixed_t <- fixed_t[fixed_t <= max_t] 36 | 37 | # get plotdata 38 | plotdata <- curve_cont(data=data, 39 | variable=variable, 40 | group=NULL, 41 | model=model, 42 | horizon=horizon, 43 | times=fixed_t, 44 | na.action="na.fail", 45 | cif=cif, 46 | event_time=time, 47 | event_status=status, 48 | ...) 49 | # transform 50 | plot_matrix <- t(reshape2::acast(plotdata, cont~time, value.var="est")) 51 | 52 | if (interactive) { 53 | requireNamespace("plotly") 54 | 55 | p <- plotly::plot_ly(x=as.numeric(colnames(plot_matrix)), 56 | y=as.numeric(rownames(plot_matrix)), 57 | z=plot_matrix) %>% 58 | plotly::add_surface() %>% 59 | plotly::layout( 60 | scene=list( 61 | xaxis=list(title=zlab), 62 | yaxis=list(title=xlab), 63 | zaxis=list(title=ylab) 64 | )) 65 | return(p) 66 | } else { 67 | p <- graphics::persp(x=as.numeric(colnames(plot_matrix)), 68 | y=as.numeric(rownames(plot_matrix)), 69 | z=t(plot_matrix), 70 | xlab=zlab, 71 | ylab=xlab, 72 | zlab=ylab, 73 | ticktype=ticktype, 74 | theta=theta, 75 | phi=phi, 76 | col=col, 77 | shade=shade) 78 | return(invisible(p)) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /R/plot_surv_animated.r: -------------------------------------------------------------------------------- 1 | 2 | ## function to draw one survival curve or CIF, and animate the continuous 3 | ## variable either as a gif or a slider 4 | #' @importFrom rlang .data 5 | #' @export 6 | plot_surv_animated <- function(time, status, variable, group=NULL, data, model, 7 | cif=FALSE, conf_int=FALSE, conf_level=0.95, 8 | n_boot=300, na.action=options()$na.action, 9 | horizon=NULL, fixed_t=NULL, max_t=Inf, 10 | slider=TRUE, 11 | size=1, color="black", linetype="solid", alpha=1, 12 | xlab="Time", ylab="Survival Probability", 13 | title=NULL, subtitle=NULL, 14 | gg_theme=ggplot2::theme_bw(), 15 | facet_args=list(), ci_alpha=0.4, 16 | kaplan_meier=FALSE, km_size=0.5, 17 | km_linetype="solid", km_alpha=1, 18 | km_color="black", km_ci=FALSE, 19 | km_ci_type="plain", km_ci_level=0.95, 20 | km_ci_alpha=0.4, ...) { 21 | 22 | data <- use_data.frame(data) 23 | 24 | check_inputs_plots(time=time, status=status, variable=variable, 25 | data=data, model=model, na.action=na.action, 26 | horizon=horizon, fixed_t=fixed_t, max_t=max_t, 27 | discrete=TRUE, panel_border=TRUE, t=1, tau=1, 28 | group=group) 29 | 30 | data <- prepare_inputdata(data=data, time=time, status=status, 31 | variable=variable, model=model, 32 | group=group, na.action=na.action) 33 | 34 | if (is.null(fixed_t)) { 35 | fixed_t <- c(0, sort(unique(data[, time][data[, status]==1]))) 36 | } 37 | if (is.null(horizon)) { 38 | horizon <- seq(min(data[, variable]), max(data[, variable]), length.out=40) 39 | } 40 | 41 | # only show up to max_t 42 | fixed_t <- fixed_t[fixed_t <= max_t] 43 | 44 | # get plotdata 45 | plotdata <- curve_cont(data=data, 46 | variable=variable, 47 | group=group, 48 | model=model, 49 | horizon=horizon, 50 | times=fixed_t, 51 | na.action="na.fail", 52 | cif=cif, 53 | event_time=time, 54 | event_status=status, 55 | conf_int=conf_int, 56 | conf_level=conf_level, 57 | n_boot=n_boot, 58 | ...) 59 | 60 | # correct label 61 | if (cif & ylab=="Survival Probability") { 62 | ylab <- "Cumulative Incidence" 63 | } 64 | 65 | # plot it 66 | if (slider) { 67 | p <- ggplot2::ggplot(plotdata, ggplot2::aes(x=.data$time, y=.data$est, 68 | frame=.data$cont)) 69 | } else { 70 | p <- ggplot2::ggplot(plotdata, ggplot2::aes(x=.data$time, y=.data$est)) 71 | } 72 | 73 | if (conf_int & slider) { 74 | stop("Showing confidence intervals is currently not supported when using", 75 | " slider=TRUE.") 76 | } else if (conf_int) { 77 | requireNamespace("pammtools") 78 | 79 | p <- p + pammtools::geom_stepribbon(ggplot2::aes(x=.data$time, 80 | y=.data$est, 81 | ymin=.data$ci_lower, 82 | ymax=.data$ci_upper), 83 | alpha=ci_alpha, inherit.aes=FALSE, 84 | fill=color) 85 | } 86 | 87 | p <- p + ggplot2::geom_step(linewidth=size, color=color, linetype=linetype, 88 | alpha=alpha) + 89 | ggplot2::labs(x=xlab, y=ylab, title=title, subtitle=subtitle) + 90 | gg_theme 91 | 92 | # add kaplan-meier curve if specified 93 | if (kaplan_meier) { 94 | km_dat <- get_kaplan_meier(time=time, status=status, group=group, 95 | data=data, conf_int=km_ci, 96 | conf_type=km_ci_type, conf_level=km_ci_level, 97 | cif=cif) 98 | if (km_ci & slider) { 99 | stop("Showing confidence intervals is currently not supported when using", 100 | " slider=TRUE.") 101 | } else if (km_ci) { 102 | requireNamespace("pammtools") 103 | 104 | p <- p + pammtools::geom_stepribbon(data=km_dat, 105 | ggplot2::aes(x=.data$time, 106 | y=.data$est, 107 | ymin=.data$ci_lower, 108 | ymax=.data$ci_upper), 109 | fill=km_color, alpha=km_ci_alpha, 110 | inherit.aes=FALSE) 111 | } 112 | p <- p + ggplot2::geom_step(data=km_dat, ggplot2::aes(x=.data$time, 113 | y=.data$est), 114 | linewidth=km_size, color=km_color, 115 | alpha=km_alpha, linetype=km_linetype, 116 | inherit.aes=FALSE) 117 | } 118 | 119 | # facet plot by factor variable 120 | if (!is.null(group)) { 121 | facet_args$facets <- stats::as.formula("~ group") 122 | facet_obj <- do.call(ggplot2::facet_wrap, facet_args) 123 | p <- p + facet_obj 124 | } 125 | 126 | if (slider) { 127 | requireNamespace("plotly") 128 | 129 | return(plotly::ggplotly(p)) 130 | } else { 131 | requireNamespace("gganimate") 132 | requireNamespace("transformr") 133 | 134 | if (is.null(title)) { 135 | title <- variable 136 | } 137 | 138 | p <- p + gganimate::transition_manual(frames=.data$cont) + 139 | ggplot2::labs(title=paste0(title, ": {frame}")) 140 | } 141 | 142 | return(p) 143 | } 144 | -------------------------------------------------------------------------------- /R/plot_surv_at_t.r: -------------------------------------------------------------------------------- 1 | 2 | ## function to plot the survival or failure probability of a fixed point in time 3 | ## as a function of a continuous variable 4 | #' @importFrom rlang .data 5 | #' @export 6 | plot_surv_at_t <- function(time, status, variable, group=NULL, data, model, 7 | cif=FALSE, conf_int=FALSE, conf_level=0.95, 8 | n_boot=300, na.action=options()$na.action, 9 | t, horizon=NULL, 10 | size=1, linetype="solid", alpha=1, 11 | xlab=variable, ylab="Survival Probability at t", 12 | title=NULL, subtitle=NULL, 13 | legend.title="t", legend.position="right", 14 | gg_theme=ggplot2::theme_bw(), 15 | facet_args=list(), ci_alpha=0.4, ...) { 16 | 17 | data <- use_data.frame(data) 18 | 19 | check_inputs_plots(time=time, status=status, variable=variable, 20 | data=data, model=model, na.action=na.action, 21 | horizon=horizon, fixed_t=NULL, max_t=Inf, 22 | discrete=TRUE, panel_border=TRUE, t=t, tau=1, 23 | group=group) 24 | 25 | data <- prepare_inputdata(data=data, time=time, status=status, 26 | variable=variable, model=model, 27 | group=group, na.action=na.action) 28 | 29 | if (is.null(horizon)) { 30 | horizon <- seq(min(data[, variable]), max(data[, variable]), 31 | length.out=100) 32 | } 33 | 34 | # get plotdata 35 | plotdata <- curve_cont(data=data, 36 | variable=variable, 37 | group=group, 38 | model=model, 39 | horizon=horizon, 40 | times=t, 41 | na.action="na.fail", 42 | cif=cif, 43 | event_time=time, 44 | event_status=status, 45 | conf_int=conf_int, 46 | conf_level=conf_level, 47 | n_boot=n_boot, 48 | ...) 49 | plotdata$time <- as.factor(plotdata$time) 50 | 51 | # plot them 52 | p <- ggplot2::ggplot(plotdata, ggplot2::aes(x=.data$cont, y=.data$est, 53 | color=.data$time)) 54 | 55 | if (length(t)==1) { 56 | p$mapping$colour <- NULL 57 | } 58 | 59 | # correct label 60 | if (cif & ylab=="Survival Probability at t") { 61 | ylab <- "Cumulative Incidence at t" 62 | } 63 | 64 | if (conf_int & length(t)==1) { 65 | p <- p + ggplot2::geom_ribbon(ggplot2::aes(ymin=.data$ci_lower, 66 | ymax=.data$ci_upper), 67 | fill="grey", alpha=ci_alpha, linewidth=0) 68 | } else if (conf_int) { 69 | p <- p + ggplot2::geom_ribbon(ggplot2::aes(x=.data$cont, 70 | y=.data$est, 71 | ymin=.data$ci_lower, 72 | ymax=.data$ci_upper, 73 | fill=.data$time), 74 | alpha=ci_alpha, linewidth=0, 75 | inherit.aes=FALSE) 76 | } 77 | 78 | p <- p + ggplot2::geom_line(linewidth=size, linetype=linetype, alpha=alpha) + 79 | ggplot2::labs(x=xlab, y=ylab, title=title, subtitle=subtitle, 80 | fill=legend.title, color=legend.title) + 81 | gg_theme + 82 | ggplot2::theme(legend.position=legend.position) 83 | 84 | # facet plot by factor variable 85 | if (!is.null(group)) { 86 | facet_args$facets <- stats::as.formula("~ group") 87 | facet_obj <- do.call(ggplot2::facet_wrap, facet_args) 88 | p <- p + facet_obj 89 | } 90 | 91 | return(p) 92 | } 93 | -------------------------------------------------------------------------------- /R/plot_surv_contour.r: -------------------------------------------------------------------------------- 1 | 2 | ## A contour plot of time vs. continuous covariate with color grading 3 | ## showing the survival or failure probability 4 | #' @importFrom rlang .data 5 | #' @export 6 | plot_surv_contour <- function(time, status, variable, group=NULL, data, model, 7 | cif=FALSE, na.action=options()$na.action, 8 | horizon=NULL, fixed_t=NULL, max_t=Inf, 9 | size=0.1, linetype="solid", alpha=1, 10 | bins=NULL, binwidth=NULL, breaks=NULL, 11 | custom_colors=NULL, 12 | xlab="Time", ylab=variable, 13 | title=NULL, subtitle=NULL, 14 | legend.title="S(t)", legend.position="right", 15 | gg_theme=ggplot2::theme_bw(), facet_args=list(), 16 | panel_border=FALSE, axis_dist=0, 17 | ...) { 18 | 19 | data <- use_data.frame(data) 20 | 21 | check_inputs_plots(time=time, status=status, variable=variable, 22 | data=data, model=model, na.action=na.action, 23 | horizon=horizon, fixed_t=fixed_t, max_t=max_t, 24 | discrete=TRUE, panel_border=panel_border, t=1, tau=1, 25 | group=group) 26 | 27 | data <- prepare_inputdata(data=data, time=time, status=status, 28 | variable=variable, model=model, 29 | group=group, na.action=na.action) 30 | 31 | if (is.null(fixed_t)) { 32 | fixed_t <- seq(min(data[, time]), max(data[, time]), length.out=100) 33 | } 34 | if (is.null(horizon)) { 35 | horizon <- seq(min(data[, variable]), max(data[, variable]), length.out=40) 36 | } 37 | 38 | # only show up to max_t 39 | fixed_t <- fixed_t[fixed_t <= max_t] 40 | 41 | # get plotdata 42 | plotdata <- curve_cont(data=data, 43 | variable=variable, 44 | model=model, 45 | group=group, 46 | horizon=horizon, 47 | times=fixed_t, 48 | na.action="na.fail", 49 | cif=cif, 50 | event_time=time, 51 | event_status=status, 52 | ...) 53 | 54 | # correct label 55 | if (cif & legend.title=="S(t)") { 56 | legend.title <- "F(t)" 57 | } 58 | 59 | # plot it 60 | p <- ggplot2::ggplot(plotdata, ggplot2::aes(x=.data$time, y=.data$cont, 61 | z=.data$est)) + 62 | ggplot2::geom_contour_filled(linewidth=size, alpha=alpha, bins=bins, 63 | binwidth=binwidth, breaks=breaks) + 64 | ggplot2::labs(x=xlab, y=ylab, title=title, subtitle=subtitle, 65 | fill=legend.title) + 66 | gg_theme + 67 | ggplot2::theme(legend.position=legend.position) + 68 | ggplot2::scale_x_continuous(expand=c(axis_dist, axis_dist)) + 69 | ggplot2::scale_y_continuous(expand=c(axis_dist, axis_dist)) 70 | 71 | if (!panel_border) { 72 | p <- p + ggplot2::theme(panel.border=ggplot2::element_blank()) 73 | } 74 | if (!is.null(custom_colors)) { 75 | p <- p + ggplot2::scale_fill_manual(values=custom_colors) 76 | } 77 | # facet plot by factor variable 78 | if (!is.null(group)) { 79 | facet_args$facets <- stats::as.formula("~ group") 80 | facet_obj <- do.call(ggplot2::facet_wrap, facet_args) 81 | p <- p + facet_obj 82 | } 83 | return(p) 84 | } 85 | -------------------------------------------------------------------------------- /R/plot_surv_heatmap.r: -------------------------------------------------------------------------------- 1 | 2 | ## A heatmap of time vs. continuous covariate with color grading 3 | ## showing the survival or failure probability 4 | #' @importFrom rlang .data 5 | #' @export 6 | plot_surv_heatmap <- function(time, status, variable, group=NULL, data, model, 7 | cif=FALSE, na.action=options()$na.action, 8 | horizon=NULL, fixed_t=NULL, max_t=Inf, 9 | start_color=NULL, end_color=NULL, 10 | alpha=1, xlab="Time", ylab=variable, 11 | title=NULL, subtitle=NULL, 12 | legend.title="S(t)", legend.position="right", 13 | gg_theme=ggplot2::theme_bw(), facet_args=list(), 14 | panel_border=FALSE, axis_dist=0, 15 | interpolate=TRUE, 16 | contour_lines=FALSE, contour_color="white", 17 | contour_size=0.3, contour_linetype="dashed", 18 | ...) { 19 | 20 | data <- use_data.frame(data) 21 | 22 | check_inputs_plots(time=time, status=status, variable=variable, 23 | data=data, model=model, na.action=na.action, 24 | horizon=horizon, fixed_t=fixed_t, max_t=max_t, 25 | discrete=TRUE, panel_border=panel_border, t=1, tau=1, 26 | group=group) 27 | 28 | data <- prepare_inputdata(data=data, time=time, status=status, 29 | variable=variable, model=model, 30 | group=group, na.action=na.action) 31 | 32 | if (is.null(fixed_t)) { 33 | fixed_t <- seq(min(data[, time]), max(data[, time]), length.out=100) 34 | } 35 | if (is.null(horizon)) { 36 | horizon <- seq(min(data[, variable]), max(data[, variable]), length.out=40) 37 | } 38 | 39 | # only show up to max_t 40 | fixed_t <- fixed_t[fixed_t <= max_t] 41 | 42 | # get plotdata 43 | plotdata <- curve_cont(data=data, 44 | variable=variable, 45 | model=model, 46 | group=group, 47 | horizon=horizon, 48 | times=fixed_t, 49 | na.action="na.fail", 50 | cif=cif, 51 | event_time=time, 52 | event_status=status, 53 | ...) 54 | 55 | # correct label 56 | if (cif & legend.title=="S(t)") { 57 | legend.title <- "F(t)" 58 | } 59 | 60 | # plot it 61 | p <- ggplot2::ggplot(plotdata, ggplot2::aes(x=.data$time, y=.data$cont, 62 | fill=.data$est)) + 63 | ggplot2::geom_raster(alpha=alpha, interpolate=interpolate) + 64 | ggplot2::labs(x=xlab, y=ylab, title=title, subtitle=subtitle, 65 | fill=legend.title) + 66 | gg_theme + 67 | ggplot2::theme(legend.position=legend.position) + 68 | ggplot2::scale_x_continuous(expand=c(axis_dist, axis_dist)) + 69 | ggplot2::scale_y_continuous(expand=c(axis_dist, axis_dist)) 70 | 71 | if (!is.null(start_color) & !is.null(end_color)) { 72 | p <- p + ggplot2::scale_fill_gradient(low=start_color, high=end_color) 73 | } 74 | if (!panel_border) { 75 | p <- p + ggplot2::theme(panel.border=ggplot2::element_blank()) 76 | } 77 | if (contour_lines) { 78 | p <- p + ggplot2::geom_contour(ggplot2::aes(x=.data$time, 79 | y=.data$cont, 80 | z=.data$est), 81 | colour=contour_color, 82 | linewidth=contour_size, 83 | linetype=contour_linetype, 84 | alpha=alpha, 85 | inherit.aes=FALSE) 86 | } 87 | # facet plot by factor variable 88 | if (!is.null(group)) { 89 | facet_args$facets <- stats::as.formula("~ group") 90 | facet_obj <- do.call(ggplot2::facet_wrap, facet_args) 91 | p <- p + facet_obj 92 | } 93 | return(p) 94 | } 95 | -------------------------------------------------------------------------------- /R/plot_surv_lines.r: -------------------------------------------------------------------------------- 1 | 2 | ## function to simply draw many survival curves or CIFs, one for each x-value 3 | #' @importFrom rlang .data 4 | #' @export 5 | plot_surv_lines <- function(time, status, variable, group=NULL, data, model, 6 | cif=FALSE, conf_int=FALSE, conf_level=0.95, 7 | n_boot=300, na.action=options()$na.action, 8 | horizon=NULL, fixed_t=NULL, max_t=Inf, 9 | discrete=TRUE, custom_colors=NULL, 10 | start_color="blue", end_color="red", 11 | size=1, linetype="solid", alpha=1, 12 | xlab="Time", ylab="Survival Probability", 13 | title=NULL, subtitle=NULL, 14 | legend.title=variable, legend.position="right", 15 | gg_theme=ggplot2::theme_bw(), facet_args=list(), 16 | ci_alpha=0.4, kaplan_meier=FALSE, km_size=0.5, 17 | km_linetype="solid", km_alpha=1, 18 | km_color="black", km_ci=FALSE, 19 | km_ci_type="plain", km_ci_level=0.95, 20 | km_ci_alpha=0.4, ...) { 21 | 22 | data <- use_data.frame(data) 23 | 24 | check_inputs_plots(time=time, status=status, variable=variable, 25 | data=data, model=model, na.action=na.action, 26 | horizon=horizon, fixed_t=fixed_t, max_t=max_t, 27 | discrete=discrete, panel_border=TRUE, t=1, tau=1, 28 | group=group) 29 | 30 | data <- prepare_inputdata(data=data, time=time, status=status, 31 | variable=variable, model=model, 32 | group=group, na.action=na.action) 33 | 34 | if (is.null(fixed_t)) { 35 | fixed_t <- c(0, sort(unique(data[, time][data[, status]==1]))) 36 | } 37 | if (is.null(horizon)) { 38 | horizon <- seq(min(data[, variable]), max(data[, variable]), length.out=12) 39 | } 40 | 41 | # only show up to max_t 42 | fixed_t <- fixed_t[fixed_t <= max_t] 43 | 44 | # get plotdata 45 | plotdata <- curve_cont(data=data, 46 | variable=variable, 47 | model=model, 48 | group=group, 49 | horizon=horizon, 50 | times=fixed_t, 51 | na.action="na.fail", 52 | cif=cif, 53 | event_time=time, 54 | event_status=status, 55 | conf_int=conf_int, 56 | conf_level=conf_level, 57 | n_boot=n_boot, 58 | ...) 59 | # plot it 60 | if (!discrete) { 61 | # create enough colors 62 | colgrad_fun <- grDevices::colorRampPalette(c(start_color, end_color)) 63 | colgrad <- colgrad_fun(length(horizon)) 64 | } else { 65 | plotdata$cont <- as.factor(plotdata$cont) 66 | } 67 | 68 | # correct label 69 | if (cif & ylab=="Survival Probability") { 70 | ylab <- "Cumulative Incidence" 71 | } 72 | 73 | # plot it 74 | p <- ggplot2::ggplot(plotdata, ggplot2::aes(x=.data$time, y=.data$est, 75 | color=.data$cont, 76 | group=as.factor(.data$cont))) 77 | # add confidence intervals 78 | if (conf_int) { 79 | requireNamespace("pammtools") 80 | 81 | p <- p + pammtools::geom_stepribbon(ggplot2::aes(x=.data$time, 82 | y=.data$est, 83 | ymin=.data$ci_lower, 84 | ymax=.data$ci_upper, 85 | fill=.data$cont), 86 | alpha=ci_alpha, inherit.aes=FALSE) 87 | } 88 | 89 | p <- p + 90 | ggplot2::geom_step(linewidth=size, linetype=linetype, alpha=alpha) + 91 | ggplot2::labs(x=xlab, y=ylab, title=title, subtitle=subtitle, 92 | fill=legend.title, color=legend.title) + 93 | gg_theme + 94 | ggplot2::theme(legend.position=legend.position) 95 | 96 | # add continuous of discrete color scale 97 | if (!discrete) { 98 | p <- p + ggplot2::scale_color_gradient(low=start_color, high=end_color) 99 | } else if (!is.null(custom_colors)) { 100 | p <- p + ggplot2::scale_colour_manual(values=custom_colors) 101 | if (conf_int) { 102 | p <- p + ggplot2::scale_fill_manual(values=custom_colors) 103 | } 104 | } 105 | # add kaplan-meier estimates 106 | if (kaplan_meier) { 107 | km_dat <- get_kaplan_meier(time=time, status=status, group=group, 108 | data=data, conf_int=km_ci, 109 | conf_type=km_ci_type, conf_level=km_ci_level, 110 | cif=cif) 111 | if (km_ci) { 112 | requireNamespace("pammtools") 113 | 114 | p <- p + pammtools::geom_stepribbon(data=km_dat, 115 | ggplot2::aes(x=.data$time, 116 | y=.data$est, 117 | ymin=.data$ci_lower, 118 | ymax=.data$ci_upper), 119 | fill=km_color, alpha=km_ci_alpha, 120 | inherit.aes=FALSE) 121 | } 122 | p <- p + ggplot2::geom_step(data=km_dat, ggplot2::aes(x=.data$time, 123 | y=.data$est), 124 | linewidth=km_size, color=km_color, 125 | alpha=km_alpha, linetype=km_linetype, 126 | inherit.aes=FALSE) 127 | } 128 | # facet plot by factor variable 129 | if (!is.null(group)) { 130 | facet_args$facets <- stats::as.formula("~ group") 131 | facet_obj <- do.call(ggplot2::facet_wrap, facet_args) 132 | p <- p + facet_obj 133 | } 134 | 135 | return(p) 136 | } 137 | -------------------------------------------------------------------------------- /R/plot_surv_quantiles.r: -------------------------------------------------------------------------------- 1 | 2 | ## small function to obtain the survival time quantiles from 3 | ## estimated plotdata 4 | cont_surv_quantiles <- function(plotdata, p) { 5 | 6 | plotdata$group <- as.factor(plotdata$cont) 7 | plotdata$surv <- plotdata$est 8 | 9 | levs <- unique(plotdata$group) 10 | 11 | out <- vector(mode="list", length=length(levs)) 12 | for (i in seq_len(length(levs))) { 13 | temp_dat <- plotdata[plotdata$group==levs[i],] 14 | temp_dat$group <- NULL 15 | 16 | val <- vapply(X=p, FUN=read_from_step_function, FUN.VALUE=numeric(1), 17 | data=temp_dat, est="time", time="surv") 18 | out[[i]] <- data.frame(p=p, group=levs[i], q_surv=val) 19 | } 20 | surv_q <- dplyr::bind_rows(out) 21 | 22 | surv_q$group <- as.numeric(as.character(surv_q$group)) 23 | surv_q$p <- as.factor(surv_q$p) 24 | 25 | return(surv_q) 26 | } 27 | 28 | ## function to plot survival time quantiles as they evolve over values of 29 | ## the continuous variable 30 | #' @importFrom rlang .data 31 | #' @export 32 | plot_surv_quantiles <- function(time, status, variable, group=NULL, data, model, 33 | na.action=options()$na.action, 34 | p=0.5, horizon=NULL, 35 | size=1, linetype="solid", alpha=1, 36 | custom_colors=NULL, single_color=NULL, 37 | xlab=variable, ylab="Survival Time Quantile", 38 | title=NULL, subtitle=NULL, 39 | legend.title=variable, legend.position="right", 40 | gg_theme=ggplot2::theme_bw(), facet_args=list(), 41 | ...) { 42 | 43 | data <- use_data.frame(data) 44 | 45 | check_inputs_plots(time=time, status=status, variable=variable, 46 | data=data, model=model, na.action=na.action, 47 | horizon=horizon, fixed_t=NULL, max_t=Inf, 48 | discrete=TRUE, panel_border=TRUE, t=1, tau=1, 49 | group=group) 50 | 51 | data <- prepare_inputdata(data=data, time=time, status=status, 52 | variable=variable, model=model, 53 | group=group, na.action=na.action) 54 | 55 | if (is.null(horizon)) { 56 | horizon <- seq(min(data[, variable]), max(data[, variable]), length.out=40) 57 | } 58 | 59 | # get plotdata 60 | fixed_t <- c(0, sort(unique(data[, time][data[, status]==1]))) 61 | plotdata <- curve_cont(data=data, 62 | variable=variable, 63 | model=model, 64 | group=group, 65 | horizon=horizon, 66 | times=fixed_t, 67 | na.action="na.fail", 68 | event_time=time, 69 | event_status=status, 70 | ...) 71 | 72 | # use the adjustedCurves package to calculate survival time quantiles 73 | if (is.null(group)) { 74 | surv_q <- cont_surv_quantiles(plotdata=plotdata, p=p) 75 | } else { 76 | group_levs <- levels(plotdata$group) 77 | surv_q <- vector(mode="list", length=length(group_levs)) 78 | for (i in seq_len(length(group_levs))) { 79 | temp <- plotdata[plotdata$group==group_levs[i], ] 80 | out_i <- cont_surv_quantiles(plotdata=temp, p=p) 81 | out_i$facet_var <- group_levs[i] 82 | surv_q[[i]] <- out_i 83 | } 84 | surv_q <- dplyr::bind_rows(surv_q) 85 | } 86 | 87 | # plot them 88 | plt <- ggplot2::ggplot(surv_q, ggplot2::aes(x=.data$group, y=.data$q_surv, 89 | color=.data$p, group=.data$p)) 90 | 91 | if (length(p)==1) { 92 | plt$mapping$colour <- NULL 93 | } 94 | 95 | if (!is.null(single_color)) { 96 | gg_lines <- ggplot2::geom_step(linewidth=size, linetype=linetype, 97 | alpha=alpha, color=single_color) 98 | } else { 99 | gg_lines <- ggplot2::geom_step(linewidth=size, linetype=linetype, 100 | alpha=alpha) 101 | } 102 | 103 | plt <- plt + gg_lines + 104 | ggplot2::labs(x=xlab, y=ylab, title=title, subtitle=subtitle, 105 | fill=legend.title) + 106 | gg_theme + 107 | ggplot2::theme(legend.position=legend.position) 108 | 109 | if (is.null(single_color) & !is.null(custom_colors)) { 110 | plt <- plt + ggplot2::scale_colour_manual(values=custom_colors) 111 | } 112 | # facet plot by factor variable 113 | if (!is.null(group)) { 114 | facet_args$facets <- stats::as.formula("~ facet_var") 115 | facet_obj <- do.call(ggplot2::facet_wrap, facet_args) 116 | plt <- plt + facet_obj 117 | } 118 | return(plt) 119 | } 120 | -------------------------------------------------------------------------------- /R/plot_surv_rmst.r: -------------------------------------------------------------------------------- 1 | 2 | ## function to plot restricted mean survival times as they evolve over values of 3 | ## the continuous variable 4 | #' @importFrom rlang .data 5 | #' @export 6 | plot_surv_rmst <- function(time, status, variable, group=NULL, 7 | data, model, na.action=options()$na.action, 8 | tau, horizon=NULL, custom_colors=NULL, 9 | size=1, linetype="solid", alpha=1, color="black", 10 | xlab=variable, ylab="Restricted Mean Survival Time", 11 | title=NULL, subtitle=NULL, 12 | legend.title=variable, legend.position="right", 13 | gg_theme=ggplot2::theme_bw(), 14 | facet_args=list(), ...) { 15 | requireNamespace("dplyr") 16 | 17 | data <- use_data.frame(data) 18 | 19 | check_inputs_plots(time=time, status=status, variable=variable, 20 | data=data, model=model, na.action=na.action, 21 | horizon=horizon, fixed_t=NULL, max_t=Inf, 22 | discrete=TRUE, panel_border=TRUE, t=1, tau=tau, 23 | group=group) 24 | 25 | data <- prepare_inputdata(data=data, time=time, status=status, 26 | variable=variable, model=model, 27 | group=group, na.action=na.action) 28 | 29 | if (is.null(horizon)) { 30 | horizon <- seq(min(data[, variable]), max(data[, variable]), 31 | length.out=100) 32 | } 33 | 34 | # get plotdata 35 | fixed_t <- c(0, sort(unique(data[, time][data[, status]==1]))) 36 | plotdata <- curve_cont(data=data, 37 | variable=variable, 38 | group=group, 39 | model=model, 40 | horizon=horizon, 41 | times=fixed_t, 42 | na.action="na.fail", 43 | event_time=time, 44 | event_status=status, 45 | ...) 46 | 47 | # calculate RMST values 48 | if (is.null(group)) { 49 | out <- cont_surv_auc(plotdata=plotdata, tau=tau) 50 | } else { 51 | group_levs <- levels(plotdata$group) 52 | out <- vector(mode="list", length=length(group_levs)) 53 | for (i in seq_len(length(group_levs))) { 54 | temp <- plotdata[plotdata$group==group_levs[i], ] 55 | out_i <- cont_surv_auc(plotdata=temp, tau=tau) 56 | out_i$group <- group_levs[i] 57 | out[[i]] <- out_i 58 | } 59 | out <- dplyr::bind_rows(out) 60 | } 61 | 62 | # plot them 63 | p <- ggplot2::ggplot(out, ggplot2::aes(x=.data$cont, y=.data$auc, 64 | color=.data$tau)) 65 | 66 | if (length(tau)==1) { 67 | p$mapping$colour <- NULL 68 | gg_line <- ggplot2::geom_line(linewidth=size, linetype=linetype, 69 | alpha=alpha, color=color) 70 | } else { 71 | gg_line <- ggplot2::geom_line(linewidth=size, linetype=linetype, 72 | alpha=alpha) 73 | } 74 | 75 | p <- p + gg_line + 76 | ggplot2::labs(x=xlab, y=ylab, title=title, subtitle=subtitle, 77 | fill=legend.title) + 78 | gg_theme + 79 | ggplot2::theme(legend.position=legend.position) 80 | 81 | if (length(tau) > 1 & !is.null(custom_colors)) { 82 | p <- p + ggplot2::scale_colour_manual(values=custom_colors) 83 | } 84 | # facet plot by factor variable 85 | if (!is.null(group)) { 86 | facet_args$facets <- stats::as.formula("~ group") 87 | facet_obj <- do.call(ggplot2::facet_wrap, facet_args) 88 | p <- p + facet_obj 89 | } 90 | 91 | return(p) 92 | } 93 | -------------------------------------------------------------------------------- /R/plot_surv_rmtl.r: -------------------------------------------------------------------------------- 1 | 2 | ## function to plot the restricted mean time lost as it evolves over values of 3 | ## the continuous variable 4 | #' @importFrom rlang .data 5 | #' @export 6 | plot_surv_rmtl <- function(time, status, variable, group=NULL, 7 | data, model, na.action=options()$na.action, 8 | tau, horizon=NULL, custom_colors=NULL, 9 | size=1, linetype="solid", alpha=1, color="black", 10 | xlab=variable, ylab="Restricted Mean Time Lost", 11 | title=NULL, subtitle=NULL, 12 | legend.title=variable, legend.position="right", 13 | gg_theme=ggplot2::theme_bw(), 14 | facet_args=list(), ...) { 15 | requireNamespace("dplyr") 16 | 17 | data <- use_data.frame(data) 18 | 19 | check_inputs_plots(time=time, status=status, variable=variable, 20 | data=data, model=model, na.action=na.action, 21 | horizon=horizon, fixed_t=NULL, max_t=Inf, 22 | discrete=TRUE, panel_border=TRUE, t=1, tau=tau, 23 | group=group) 24 | 25 | data <- prepare_inputdata(data=data, time=time, status=status, 26 | variable=variable, model=model, 27 | group=group, na.action=na.action) 28 | 29 | if (is.null(horizon)) { 30 | horizon <- seq(min(data[, variable]), max(data[, variable]), 31 | length.out=100) 32 | } 33 | 34 | # get plotdata 35 | fixed_t <- c(0, sort(unique(data[, time][data[, status] >= 1]))) 36 | plotdata <- curve_cont(data=data, 37 | variable=variable, 38 | group=group, 39 | model=model, 40 | horizon=horizon, 41 | times=fixed_t, 42 | na.action="na.fail", 43 | cif=TRUE, 44 | event_time=time, 45 | event_status=status, 46 | ...) 47 | 48 | # calculate RMTL values 49 | if (is.null(group)) { 50 | out <- cont_surv_auc(plotdata=plotdata, tau=tau) 51 | } else { 52 | group_levs <- levels(plotdata$group) 53 | out <- vector(mode="list", length=length(group_levs)) 54 | for (i in seq_len(length(group_levs))) { 55 | temp <- plotdata[plotdata$group==group_levs[i], ] 56 | out_i <- cont_surv_auc(plotdata=temp, tau=tau) 57 | out_i$group <- group_levs[i] 58 | out[[i]] <- out_i 59 | } 60 | out <- dplyr::bind_rows(out) 61 | } 62 | 63 | # plot them 64 | p <- ggplot2::ggplot(out, ggplot2::aes(x=.data$cont, y=.data$auc, 65 | color=.data$tau)) 66 | 67 | if (length(tau)==1) { 68 | p$mapping$colour <- NULL 69 | gg_line <- ggplot2::geom_line(linewidth=size, linetype=linetype, 70 | alpha=alpha, color=color) 71 | } else { 72 | gg_line <- ggplot2::geom_line(linewidth=size, linetype=linetype, 73 | alpha=alpha) 74 | } 75 | 76 | p <- p + gg_line + 77 | ggplot2::labs(x=xlab, y=ylab, title=title, subtitle=subtitle, 78 | fill=legend.title) + 79 | gg_theme + 80 | ggplot2::theme(legend.position=legend.position) 81 | 82 | if (length(tau) > 1 & !is.null(custom_colors)) { 83 | p <- p + ggplot2::scale_colour_manual(values=custom_colors) 84 | } 85 | # facet plot by factor variable 86 | if (!is.null(group)) { 87 | facet_args$facets <- stats::as.formula("~ group") 88 | facet_obj <- do.call(ggplot2::facet_wrap, facet_args) 89 | p <- p + facet_obj 90 | } 91 | 92 | return(p) 93 | } 94 | -------------------------------------------------------------------------------- /R/zzz.r: -------------------------------------------------------------------------------- 1 | 2 | .onAttach <- function(libname, pkgname) { 3 | cit <- paste0('Denz R, Timmesfeld N (2023). "Visualizing the', 4 | " (Causal) Effect of a Continuous Variable on a", 5 | ' Time-To-Event Outcome." Epidemiology, 34 (5).', 6 | " doi: 10.1097/EDE.0000000000001630.") 7 | packageStartupMessage("Please cite as: \n\n", cit) 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) 3 | [![](https://www.r-pkg.org/badges/version/contsurvplot?color=green)](https://cran.r-project.org/package=contsurvplot) 4 | [![](http://cranlogs.r-pkg.org/badges/grand-total/contsurvplot?color=blue)](https://cran.r-project.org/package=contsurvplot) 5 | [![R-CMD-check](https://github.com/RobinDenz1/contsurvplot/workflows/R-CMD-check/badge.svg)](https://github.com/RobinDenz1/contsurvplot/actions) 6 | [![Codecov test coverage](https://codecov.io/gh/RobinDenz1/contsurvplot/branch/main/graph/badge.svg)](https://app.codecov.io/gh/RobinDenz1/contsurvplot?branch=main) 7 | [![](https://img.shields.io/badge/doi-10.1097/EDE.0000000000001630-green.svg)](https://doi.org/10.1097/EDE.0000000000001630) 8 | 9 | 10 | # contsurvplot 11 | 12 | Author: Robin Denz 13 | 14 | ## Description 15 | 16 | `contsurvplot` is an R-Package which can be used to visualize the causal effect of a continuous variable on a time-to-event outcome. 17 | It includes multiple different plot types, such as survival area plots, contour plots, heatmaps, survival quantile plots and more. 18 | All of them can be adjusted for confounders and all of them have a lot of build in options to customize them according to the users needs. 19 | Also, most of the plot functions are based on the `ggplot2` package, allowing the user to use the standard `ggplot2` syntax to customize the plots further. 20 | 21 | ## Installation 22 | 23 | The stable release version can be installed directly from CRAN using: 24 | 25 | ```R 26 | install.packages("contsurvplot") 27 | ``` 28 | 29 | Alternatively, the development version can be installed using the `devtools` R-Package: 30 | 31 | ```R 32 | library(devtools) 33 | 34 | devtools::install_github("RobinDenz1/contsurvplot") 35 | ``` 36 | 37 | or the `remotes` R-Package: 38 | 39 | ```R 40 | library(remotes) 41 | 42 | remotes::install_github("RobinDenz1/contsurvplot") 43 | ``` 44 | 45 | ## Bug Reports and Feature Requests 46 | 47 | If you encounter any bugs or have any specific feature requests, please file an [Issue](https://github.com/RobinDenz1/contsurvplot/issues). 48 | 49 | ## Examples 50 | 51 | Here are two quick examples using the `colon` dataset from the `survival` R-Package. 52 | Suppose we want to visualize the effect of the number of lymph nodes with detectable cancer (column `nodes`) on the survival time. 53 | A survival area plot can be produced using the following code: 54 | 55 | ```R 56 | library(contsurvplot) 57 | library(ggplot2) 58 | library(survival) 59 | library(riskRegression) 60 | 61 | # load colon data 62 | data(cancer) 63 | 64 | # fit cox model, adjusting for age and sex 65 | model <- coxph(Surv(time, status) ~ age + sex + nodes, data=colon, x=TRUE) 66 | 67 | # plot survival area 68 | plot_surv_area(time="time", 69 | status="status", 70 | variable="nodes", 71 | data=colon, 72 | model=model) 73 | 74 | ``` 75 | 76 | 77 | Alternatively, we can plot a contour plot to visualize the effect: 78 | 79 | ```R 80 | plot_surv_contour(time="time", 81 | status="status", 82 | variable="nodes", 83 | data=colon, 84 | model=model) 85 | ``` 86 | 87 | 88 | Or we can use a simple plot of the median survival time as a function of `nodes`: 89 | 90 | ```R 91 | plot_surv_quantiles(time="time", 92 | status="status", 93 | variable="nodes", 94 | data=colon, 95 | model=model, 96 | p=0.5) 97 | ``` 98 | 99 | 100 | More examples can be found in the documentation and the vignette. 101 | 102 | ## Citation 103 | 104 | The main paper associated with this R-Package is: 105 | 106 | Robin Denz, Nina Timmesfeld (2023). *Visualizing the (causal) effect of a continuous variable on a time-to-event outcome*. Epidemiology. 34.5 107 | 108 | In addition, some relevant literature can be found in the documentation pages. 109 | 110 | ## License 111 | 112 | © 2022 Robin Denz 113 | 114 | The contents of this repository are distributed under the GNU General Public License. You can find the full text of this License in this github repository. Alternatively, see . 115 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | 2 | - add "plotdata" argument to allow the user to directly supply data himself 3 | - refactor auc / median survival calculation functions and export them (with man pages + tests) 4 | - add mid_color option 5 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://robindenz1.github.io/contsurvplot/ 2 | template: 3 | bootstrap: 5 4 | 5 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /contsurvplot.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## R CMD check results 2 | 3 | 0 errors | 0 warnings | 0 notes 4 | 5 | * This is an update. 6 | 7 | The package was tested on Windows 10, macOS and ubuntu using github actions and rhub as well as local machines. 8 | There were no errors or warnings and no notes. 9 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /docs/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | Articles • contsurvplot 6 | Skip to contents 7 | 8 | 9 |
44 |
45 |
48 | 49 | 56 |
57 | 58 | 59 |
62 | 63 | 66 | 67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-12-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-13-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-13-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-14-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-14-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-15-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-15-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-16-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-16-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-17-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-17-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-18-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-18-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-19-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-19-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-20-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-20-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-21-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-21-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-22-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-22-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-26-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-26-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-27-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-27-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/articles/introduction_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/deps/data-deps.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/favicon-16x16.png -------------------------------------------------------------------------------- /docs/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/favicon-32x32.png -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/favicon.ico -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/logo.png -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('nav.navbar').headroom(); 6 | 7 | Toc.init({ 8 | $nav: $("#toc"), 9 | $scope: $("main h2, main h3, main h4, main h5, main h6") 10 | }); 11 | 12 | if ($('#toc').length) { 13 | $('body').scrollspy({ 14 | target: '#toc', 15 | offset: $("nav.navbar").outerHeight() + 1 16 | }); 17 | } 18 | 19 | // Activate popovers 20 | $('[data-bs-toggle="popover"]').popover({ 21 | container: 'body', 22 | html: true, 23 | trigger: 'focus', 24 | placement: "top", 25 | sanitize: false, 26 | }); 27 | 28 | $('[data-bs-toggle="tooltip"]').tooltip(); 29 | 30 | /* Clipboard --------------------------*/ 31 | 32 | function changeTooltipMessage(element, msg) { 33 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 34 | element.setAttribute('data-original-title', msg); 35 | $(element).tooltip('show'); 36 | element.setAttribute('data-original-title', tooltipOriginalTitle); 37 | } 38 | 39 | if(ClipboardJS.isSupported()) { 40 | $(document).ready(function() { 41 | var copyButton = ""; 42 | 43 | $("div.sourceCode").addClass("hasCopyButton"); 44 | 45 | // Insert copy buttons: 46 | $(copyButton).prependTo(".hasCopyButton"); 47 | 48 | // Initialize tooltips: 49 | $('.btn-copy-ex').tooltip({container: 'body'}); 50 | 51 | // Initialize clipboard: 52 | var clipboard = new ClipboardJS('[data-clipboard-copy]', { 53 | text: function(trigger) { 54 | return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); 55 | } 56 | }); 57 | 58 | clipboard.on('success', function(e) { 59 | changeTooltipMessage(e.trigger, 'Copied!'); 60 | e.clearSelection(); 61 | }); 62 | 63 | clipboard.on('error', function() { 64 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 65 | }); 66 | 67 | }); 68 | } 69 | 70 | /* Search marking --------------------------*/ 71 | var url = new URL(window.location.href); 72 | var toMark = url.searchParams.get("q"); 73 | var mark = new Mark("main#main"); 74 | if (toMark) { 75 | mark.mark(toMark, { 76 | accuracy: { 77 | value: "complementary", 78 | limiters: [",", ".", ":", "/"], 79 | } 80 | }); 81 | } 82 | 83 | /* Search --------------------------*/ 84 | /* Adapted from https://github.com/rstudio/bookdown/blob/2d692ba4b61f1e466c92e78fd712b0ab08c11d31/inst/resources/bs4_book/bs4_book.js#L25 */ 85 | // Initialise search index on focus 86 | var fuse; 87 | $("#search-input").focus(async function(e) { 88 | if (fuse) { 89 | return; 90 | } 91 | 92 | $(e.target).addClass("loading"); 93 | var response = await fetch($("#search-input").data("search-index")); 94 | var data = await response.json(); 95 | 96 | var options = { 97 | keys: ["what", "text", "code"], 98 | ignoreLocation: true, 99 | threshold: 0.1, 100 | includeMatches: true, 101 | includeScore: true, 102 | }; 103 | fuse = new Fuse(data, options); 104 | 105 | $(e.target).removeClass("loading"); 106 | }); 107 | 108 | // Use algolia autocomplete 109 | var options = { 110 | autoselect: true, 111 | debug: true, 112 | hint: false, 113 | minLength: 2, 114 | }; 115 | var q; 116 | async function searchFuse(query, callback) { 117 | await fuse; 118 | 119 | var items; 120 | if (!fuse) { 121 | items = []; 122 | } else { 123 | q = query; 124 | var results = fuse.search(query, { limit: 20 }); 125 | items = results 126 | .filter((x) => x.score <= 0.75) 127 | .map((x) => x.item); 128 | if (items.length === 0) { 129 | items = [{dir:"Sorry 😿",previous_headings:"",title:"No results found.",what:"No results found.",path:window.location.href}]; 130 | } 131 | } 132 | callback(items); 133 | } 134 | $("#search-input").autocomplete(options, [ 135 | { 136 | name: "content", 137 | source: searchFuse, 138 | templates: { 139 | suggestion: (s) => { 140 | if (s.title == s.what) { 141 | return `${s.dir} >
${s.title}
`; 142 | } else if (s.previous_headings == "") { 143 | return `${s.dir} >
${s.title}
> ${s.what}`; 144 | } else { 145 | return `${s.dir} >
${s.title}
> ${s.previous_headings} > ${s.what}`; 146 | } 147 | }, 148 | }, 149 | }, 150 | ]).on('autocomplete:selected', function(event, s) { 151 | window.location.href = s.path + "?q=" + q + "#" + s.id; 152 | }); 153 | }); 154 | })(window.jQuery || window.$) 155 | 156 | 157 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: '2.18' 2 | pkgdown: 2.0.6 3 | pkgdown_sha: ~ 4 | articles: 5 | introduction: introduction.html 6 | last_built: 2022-08-09T12:32Z 7 | urls: 8 | reference: https://robindenz1.github.io/contsurvplot/reference 9 | article: https://robindenz1.github.io/contsurvplot/articles 10 | 11 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/Rplot002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/Rplot002.png -------------------------------------------------------------------------------- /docs/reference/Rplot003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/Rplot003.png -------------------------------------------------------------------------------- /docs/reference/Rplot004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/Rplot004.png -------------------------------------------------------------------------------- /docs/reference/figures/example_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/figures/example_area.png -------------------------------------------------------------------------------- /docs/reference/figures/example_contour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/figures/example_contour.png -------------------------------------------------------------------------------- /docs/reference/figures/example_quantiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/figures/example_quantiles.png -------------------------------------------------------------------------------- /docs/reference/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/figures/logo.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0001.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0002.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0003.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0004.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0005.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0006.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0007.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0008.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0009.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0010.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0011.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0012.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0013.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0014.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0015.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0016.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0017.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0018.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0019.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0020.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0021.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0021.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0022.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0023.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0023.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0024.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0025.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0025.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0026.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0026.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0027.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0027.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0028.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0028.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0029.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0029.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0030.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0031.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0031.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0032.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0032.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0033.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0033.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0034.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0034.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0035.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0035.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0036.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0036.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0037.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0037.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0038.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0038.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0039.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0039.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0040.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0040.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0041.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0041.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0042.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0042.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0043.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0043.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0044.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0044.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0045.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0045.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0046.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0046.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0047.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0047.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0048.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0049.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0049.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0050.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0050.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0051.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0051.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0052.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0052.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0053.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0053.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0054.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0054.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0055.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0055.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0056.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0056.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0057.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0057.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0058.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0058.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0059.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0059.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0060.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0060.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0061.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0061.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0062.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0062.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0063.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0063.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0064.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0064.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0065.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0065.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0066.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0066.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0067.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0067.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0068.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0068.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0069.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0069.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0070.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0070.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0071.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0071.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0072.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0072.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0073.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0073.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0074.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0074.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0075.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0075.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0076.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0076.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0077.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0077.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0078.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0078.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0079.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0079.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0080.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0081.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0081.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0082.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0082.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0083.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0083.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0084.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0084.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0085.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0085.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0086.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0086.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0087.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0087.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0088.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0088.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0089.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0089.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0090.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0090.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0091.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0091.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0092.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0092.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0093.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0093.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0094.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0094.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0095.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0095.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0096.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0096.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0097.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0097.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0098.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0098.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0099.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0099.png -------------------------------------------------------------------------------- /docs/reference/gganim_plot0100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/gganim_plot0100.png -------------------------------------------------------------------------------- /docs/reference/libs/crosstalk-1.2.0/css/crosstalk.min.css: -------------------------------------------------------------------------------- 1 | .container-fluid.crosstalk-bscols{margin-left:-30px;margin-right:-30px;white-space:normal}body>.container-fluid.crosstalk-bscols{margin-left:auto;margin-right:auto}.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:inline-block;padding-right:12px;vertical-align:top}@media only screen and (max-width: 480px){.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:block;padding-right:inherit}}.crosstalk-input{margin-bottom:15px}.crosstalk-input .control-label{margin-bottom:0;vertical-align:middle}.crosstalk-input input[type="checkbox"]{margin:4px 0 0;margin-top:1px;line-height:normal}.crosstalk-input .checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.crosstalk-input .checkbox>label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.crosstalk-input .checkbox input[type="checkbox"],.crosstalk-input .checkbox-inline input[type="checkbox"]{position:absolute;margin-top:2px;margin-left:-20px}.crosstalk-input .checkbox+.checkbox{margin-top:-5px}.crosstalk-input .checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.crosstalk-input .checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px} 2 | -------------------------------------------------------------------------------- /docs/reference/libs/crosstalk-1.2.0/scss/crosstalk.scss: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | 29 | /* Relevant BS3 styles to make filter_checkbox() look reasonable without Bootstrap */ 30 | .crosstalk-input { 31 | margin-bottom: 15px; /* a la .form-group */ 32 | .control-label { 33 | margin-bottom: 0; 34 | vertical-align: middle; 35 | } 36 | input[type="checkbox"] { 37 | margin: 4px 0 0; 38 | margin-top: 1px; 39 | line-height: normal; 40 | } 41 | .checkbox { 42 | position: relative; 43 | display: block; 44 | margin-top: 10px; 45 | margin-bottom: 10px; 46 | } 47 | .checkbox > label{ 48 | padding-left: 20px; 49 | margin-bottom: 0; 50 | font-weight: 400; 51 | cursor: pointer; 52 | } 53 | .checkbox input[type="checkbox"], 54 | .checkbox-inline input[type="checkbox"] { 55 | position: absolute; 56 | margin-top: 2px; 57 | margin-left: -20px; 58 | } 59 | .checkbox + .checkbox { 60 | margin-top: -5px; 61 | } 62 | .checkbox-inline { 63 | position: relative; 64 | display: inline-block; 65 | padding-left: 20px; 66 | margin-bottom: 0; 67 | font-weight: 400; 68 | vertical-align: middle; 69 | cursor: pointer; 70 | } 71 | .checkbox-inline + .checkbox-inline { 72 | margin-top: 0; 73 | margin-left: 10px; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /docs/reference/libs/plotly-htmlwidgets-css-2.5.1/plotly-htmlwidgets.css: -------------------------------------------------------------------------------- 1 | /* 2 | just here so that plotly works 3 | correctly with ioslides. 4 | see https://github.com/ropensci/plotly/issues/463 5 | */ 6 | 7 | slide:not(.current) .plotly.html-widget{ 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /docs/reference/plot_surv_3Dsurface-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_3Dsurface-1.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_3Dsurface-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_3Dsurface-2.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_area-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_area-1.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_area-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_area-2.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_area-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_area-3.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_area-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_area-4.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_at_t-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_at_t-1.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_at_t-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_at_t-2.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_contour-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_contour-1.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_contour-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_contour-2.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_contour-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_contour-3.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_heatmap-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_heatmap-1.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_heatmap-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_heatmap-2.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_heatmap-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_heatmap-3.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_heatmap-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_heatmap-4.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_lines-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_lines-1.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_lines-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_lines-2.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_lines-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_lines-3.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_quantiles-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_quantiles-1.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_quantiles-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_quantiles-2.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_quantiles-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_quantiles-3.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_rmst-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_rmst-1.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_rmst-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_rmst-2.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_rmst-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_rmst-3.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_rmtl-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_rmtl-1.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_rmtl-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_rmtl-2.png -------------------------------------------------------------------------------- /docs/reference/plot_surv_rmtl-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/docs/reference/plot_surv_rmtl-3.png -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://robindenz1.github.io/contsurvplot/404.html 5 | 6 | 7 | https://robindenz1.github.io/contsurvplot/articles/index.html 8 | 9 | 10 | https://robindenz1.github.io/contsurvplot/articles/introduction.html 11 | 12 | 13 | https://robindenz1.github.io/contsurvplot/authors.html 14 | 15 | 16 | https://robindenz1.github.io/contsurvplot/index.html 17 | 18 | 19 | https://robindenz1.github.io/contsurvplot/LICENSE.html 20 | 21 | 22 | https://robindenz1.github.io/contsurvplot/reference/contsurvplot-package.html 23 | 24 | 25 | https://robindenz1.github.io/contsurvplot/reference/curve_cont.html 26 | 27 | 28 | https://robindenz1.github.io/contsurvplot/reference/index.html 29 | 30 | 31 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_3Dsurface.html 32 | 33 | 34 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_animated.html 35 | 36 | 37 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_area.html 38 | 39 | 40 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_at_t.html 41 | 42 | 43 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_contour.html 44 | 45 | 46 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_heatmap.html 47 | 48 | 49 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_lines.html 50 | 51 | 52 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_quantiles.html 53 | 54 | 55 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_rmst.html 56 | 57 | 58 | https://robindenz1.github.io/contsurvplot/reference/plot_surv_rmtl.html 59 | 60 | 61 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | year <- sub("-.*", "", meta$Date) 2 | note <- sprintf("R package version %s", meta$Version) 3 | 4 | bibentry(bibtype = "Article", 5 | title = "Visualizing the (Causal) Effect of a Continuous Variable on a Time-To-Event Outcome", 6 | author = c(person("Robin", "Denz"), 7 | person("Nina", "Timmesfeld")), 8 | journal = "Epidemiology", 9 | year = 2023, 10 | volume = 34, 11 | number = 5, 12 | url = "https://doi.org/10.1097/EDE.0000000000001630") -------------------------------------------------------------------------------- /inst/testdata/sim150.Rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/inst/testdata/sim150.Rds -------------------------------------------------------------------------------- /inst/testdata/sim500.Rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/inst/testdata/sim500.Rds -------------------------------------------------------------------------------- /man/contsurvplot-package.Rd: -------------------------------------------------------------------------------- 1 | \name{contsurvplot-package} 2 | \alias{contsurvplot-package} 3 | 4 | \title{ 5 | Visualize the Effect of a Continuous Variable on a Time-To-Event Outcome 6 | } 7 | \description{ 8 | 9 | \strong{\emph{What is this package about?}} 10 | 11 | This package provides different plotting routines to visualize the (causal) effect of a continuous variable on a time-to-event outcome using a previously fit model and g-computation. Unlike simpler alternatives, such as plotting survival curves for some categories, these plots always correspond to the results obtained by the time-to-event model and give an accurate depiction of the causal effect, if all assumptions are met. 12 | 13 | \strong{\emph{What features are included in this package?}} 14 | 15 | The package includes 11 different plot functions, most based on the \pkg{ggplot2} package. Those 11 plotting routines include \emph{value specific survival curves}, \emph{landmark survival probability plots}, \emph{survival time quantile plots}, \emph{survival probability heatmaps}, and \emph{survival area plots}, among others. A description and comparison of these plots can be found in the article associated with this R-package (Denz & Timmesfeld 2022). 16 | 17 | \strong{\emph{What does a typical workflow using this package look like?}} 18 | 19 | All the user has to do is fit a time-to-event model, such as the cox-model, including the continuous variable of interest (and possibly confounders) and plug it into one of the plot functions included in this package. Many different kind of models are supported. See \code{\link[contsurvplot]{curve_cont}} for more details. 20 | 21 | \strong{\emph{What type of plot should I use?}} 22 | 23 | There is no general answer to this question, but we would usually suggest using a plot method that is able to visualize the causal survival probability both as a function of time and as a function of the continuous variable. The \code{\link[contsurvplot]{plot_surv_area}}, \code{\link[contsurvplot]{plot_surv_heatmap}} and \code{\link[contsurvplot]{plot_surv_contour}} functions do just that. More discussion about this topic can be found in the vignette and the associated paper. 24 | 25 | \strong{\emph{What is the difference between displaying causal effects and associations?}} 26 | 27 | The plots generated by this package offer different ways to depict the association between a continuous variable and a time-to-event outcome. Under certain causal identifiability assumptions, which are described in detail in our article on this topic (see references), this association can be endowed with a causal interpretation. Under these assumptions, the estimates can be interpreted as the survival probability that would have been observed if all individuals in the target population had received a specific level of the continuous variable. If these assumptions are not met, this interpretation is invalid. 28 | 29 | \strong{\emph{Where can I get more information?}} 30 | 31 | The documentation pages contain a lot of information, relevant examples and literature references. Additional examples can be found in the vignette of this package, which can be accessed using \code{vignette(topic="introduction", package="contsurvplot")}. We also published a preprint of the article about this package on arXiv (see references), which contains an in-depth discussion about the plots and how to interpret them. 32 | 33 | \strong{\emph{I want to suggest a new feature / I want to report a bug. Where can I do this?}} 34 | 35 | Bug reports, suggestions and feature requests are highly welcome. Please file an issue on the official github page () or contact the author directly using the supplied e-mail address. 36 | 37 | } 38 | \references{ 39 | Robin Denz, Nina Timmesfeld (2023). "Visualizing the (Causal) Effect of a Continuous Variable on a Time-To-Event Outcome". In: Epidemiology 34.5 40 | 41 | James Robins. A New Approach to Causal Inference in Mortality Studies with a Sustained Exposure Period: Application to Control of the Healthy Worker Survivor Effect. Mathematical Modelling (1986) 7, pages 1393-1512. 42 | } 43 | \author{ 44 | Robin Denz (robin.denz@rub.de) 45 | } 46 | -------------------------------------------------------------------------------- /man/figures/example_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/man/figures/example_area.png -------------------------------------------------------------------------------- /man/figures/example_contour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/man/figures/example_contour.png -------------------------------------------------------------------------------- /man/figures/example_quantiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/man/figures/example_quantiles.png -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/man/figures/logo.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(contsurvplot) 2 | library(survival) 3 | library(testthat) 4 | 5 | test_check("contsurvplot") 6 | -------------------------------------------------------------------------------- /tests/testthat/Rplots.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/tests/testthat/Rplots.pdf -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_3Dsurface/plot-at-t.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/tests/testthat/_snaps/plot_surv_3Dsurface/plot-at-t.svg -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_3Dsurface/plot-change-horizon.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/tests/testthat/_snaps/plot_surv_3Dsurface/plot-change-horizon.svg -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_3Dsurface/plot-cif.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/tests/testthat/_snaps/plot_surv_3Dsurface/plot-cif.svg -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_3Dsurface/plot-custom-non-interactive.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/tests/testthat/_snaps/plot_surv_3Dsurface/plot-custom-non-interactive.svg -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_3Dsurface/plot-defaults.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinDenz1/contsurvplot/d56dc53f0199049a0ac4595902c67020114c1241/tests/testthat/_snaps/plot_surv_3Dsurface/plot-defaults.svg -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_at_t/plot-change-horizon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 0.575 49 | 0.600 50 | 0.625 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 30 59 | 40 60 | 50 61 | 60 62 | x3 63 | Survival Probability at t 64 | 65 | 66 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_at_t/plot-cif.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 0.35 48 | 0.40 49 | 0.45 50 | 0.50 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 20 59 | 40 60 | 60 61 | x3 62 | Cumulative Incidence at t 63 | 64 | 65 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_at_t/plot-lots-of-stuff.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 0.65 35 | 0.70 36 | 0.75 37 | 0.80 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 20 47 | 40 48 | 60 49 | x 50 | y 51 | Subtitle 52 | Title 53 | 54 | 55 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_quantiles/plot-lots-of-stuff.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 20 35 | 22 36 | 24 37 | 26 38 | 28 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 20 49 | 40 50 | 60 51 | x 52 | y 53 | Subtitle 54 | Title 55 | 56 | 57 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/plot_surv_rmtl/plot-lots-of-stuff.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 12 35 | 13 36 | 14 37 | 15 38 | 16 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 20 49 | 40 50 | 60 51 | x 52 | y 53 | Subtitle 54 | Title 55 | 56 | 57 | -------------------------------------------------------------------------------- /tests/testthat/test_.onAttach.r: -------------------------------------------------------------------------------- 1 | 2 | test_that("package startup message", { 3 | expect_message(.onAttach()) 4 | }) 5 | -------------------------------------------------------------------------------- /tests/testthat/test_check_horizon.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | 7 | test_that("wrong type", { 8 | expect_error(check_horizon(horizon="a", 9 | data=sim_dat, 10 | variable="x2"), 11 | "'horizon' must be a numeric vector with at least one value or NULL.") 12 | }) 13 | 14 | test_that("NA in horizon", { 15 | expect_error(check_horizon(horizon=c(1, 2, NA), 16 | data=sim_dat, 17 | variable="x2"), 18 | "Missing values in 'horizon' are not allowed.") 19 | }) 20 | 21 | test_that("too small", { 22 | expect_warning(check_horizon(horizon=c(-100, 2), 23 | data=sim_dat, 24 | variable="x2"), 25 | paste0("Some values in 'horizon' are smaller than the", 26 | " minimum observed in 'data', which might lead to problems.")) 27 | }) 28 | 29 | test_that("too big", { 30 | expect_warning(check_horizon(horizon=c(100, 2), 31 | data=sim_dat, 32 | variable="x2"), 33 | paste0("Some values in 'horizon' are bigger than the", 34 | " maximum observed in 'data', which might lead to problems.")) 35 | }) 36 | -------------------------------------------------------------------------------- /tests/testthat/test_get_kaplan_meier.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | test_that("standard case", { 12 | out <- get_kaplan_meier(time="time", status="event", data=sim_dat) 13 | expect_true(is.data.frame(out)) 14 | expect_true(ncol(out)==2 & nrow(out)==151) 15 | }) 16 | 17 | test_that("with conf_int", { 18 | out <- get_kaplan_meier(time="time", status="event", data=sim_dat, 19 | conf_int=TRUE) 20 | expect_true(is.data.frame(out)) 21 | expect_true(ncol(out)==4 & nrow(out)==151) 22 | }) 23 | 24 | test_that("with group", { 25 | out <- get_kaplan_meier(time="time", status="event", data=sim_dat, 26 | group="group") 27 | expect_true(is.data.frame(out)) 28 | expect_true(ncol(out)==3 & nrow(out)==152) 29 | }) 30 | 31 | test_that("with group and conf_int", { 32 | out <- get_kaplan_meier(time="time", status="event", data=sim_dat, 33 | conf_int=TRUE, group="group") 34 | expect_true(is.data.frame(out)) 35 | expect_true(ncol(out)==5 & nrow(out)==152) 36 | }) 37 | 38 | test_that("with conf_int and cif", { 39 | out <- get_kaplan_meier(time="time", status="event", data=sim_dat, 40 | conf_int=TRUE, cif=TRUE) 41 | expect_true(is.data.frame(out)) 42 | expect_true(ncol(out)==4 & nrow(out)==151) 43 | }) 44 | 45 | test_that("fixed_t", { 46 | out <- get_kaplan_meier(time="time", status="event", data=sim_dat, 47 | fixed_t=c(22, 40)) 48 | expect_true(is.data.frame(out)) 49 | expect_true(ncol(out)==2 & nrow(out)==2 & all(out$time==c(22, 40))) 50 | }) 51 | 52 | test_that("fixed_t, with group", { 53 | out <- get_kaplan_meier(time="time", status="event", data=sim_dat, 54 | group="group", fixed_t=c(22, 40)) 55 | expect_true(is.data.frame(out)) 56 | expect_true(ncol(out)==3 & nrow(out)==4 & all(out$time==c(22, 40, 22, 40))) 57 | }) 58 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_3Dsurface.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | 7 | model <- survival::coxph(survival::Surv(time, event) ~ x3, data=sim_dat, x=TRUE) 8 | 9 | test_that("plot, defaults", { 10 | plt <- plot_surv_3Dsurface(time="time", status="event", variable="x3", 11 | data=sim_dat, model=model) 12 | expect_true(is.matrix(plt)) 13 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 14 | }) 15 | 16 | test_that("plot, cif", { 17 | plt <- plot_surv_3Dsurface(time="time", status="event", variable="x3", 18 | data=sim_dat, model=model, cif=TRUE, 19 | na.action=na.omit) 20 | expect_true(is.matrix(plt)) 21 | vdiffr::expect_doppelganger("plot, cif", fig=plt) 22 | }) 23 | 24 | test_that("plot, change horizon", { 25 | plt <- plot_surv_3Dsurface(time="time", status="event", variable="x3", 26 | data=sim_dat, model=model, horizon=seq(30, 60, 1)) 27 | expect_true(is.matrix(plt)) 28 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 29 | }) 30 | 31 | test_that("plot, at t", { 32 | plt <- plot_surv_3Dsurface(time="time", status="event", variable="x3", 33 | data=sim_dat, model=model, fixed_t=seq(0, 30, 1)) 34 | expect_true(is.matrix(plt)) 35 | vdiffr::expect_doppelganger("plot, at t", fig=plt) 36 | }) 37 | 38 | test_that("plot, custom non-interactive", { 39 | plt <- plot_surv_3Dsurface(time="time", status="event", variable="x3", 40 | data=sim_dat, model=model, col="red", 41 | ticktype="simple", phi=30, theta=200, shade=0.3) 42 | expect_true(is.matrix(plt)) 43 | vdiffr::expect_doppelganger("plot, custom non-interactive", fig=plt) 44 | }) 45 | 46 | test_that("plot, interactive", { 47 | plt <- plot_surv_3Dsurface(time="time", status="event", variable="x3", 48 | data=sim_dat, model=model, color="red", 49 | interactive=TRUE) 50 | expect_s3_class(plt, "plotly") 51 | }) 52 | 53 | test_that("plot, interactive + args", { 54 | plt <- plot_surv_3Dsurface(time="time", status="event", variable="x3", 55 | data=sim_dat, model=model, color="red", 56 | interactive=TRUE, xlab="x", ylab="y", zlab="z", 57 | cif=TRUE) 58 | expect_s3_class(plt, "plotly") 59 | }) 60 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_animated.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | test_that("plot, defaults", { 12 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 13 | data=sim_dat, model=model) 14 | expect_s3_class(plt, "plotly") 15 | }) 16 | 17 | test_that("plot, kaplan_meier", { 18 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 19 | data=sim_dat, model=model, kaplan_meier=TRUE, 20 | km_size=1, km_alpha=0.8, km_linetype="dashed", 21 | km_color="red") 22 | expect_s3_class(plt, "plotly") 23 | }) 24 | 25 | test_that("plot, cif", { 26 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 27 | data=sim_dat, model=model, cif=TRUE) 28 | expect_s3_class(plt, "plotly") 29 | }) 30 | 31 | test_that("plot, change horizon", { 32 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 33 | data=sim_dat, model=model, horizon=seq(30, 60, 1)) 34 | expect_s3_class(plt, "plotly") 35 | }) 36 | 37 | test_that("plot, at t", { 38 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 39 | data=sim_dat, model=model, fixed_t=seq(0, 30, 1), 40 | na.action=na.omit) 41 | expect_s3_class(plt, "plotly") 42 | }) 43 | 44 | test_that("plot, custom color", { 45 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 46 | data=sim_dat, model=model, color="red") 47 | expect_s3_class(plt, "plotly") 48 | }) 49 | 50 | test_that("plot, no slider", { 51 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 52 | data=sim_dat, model=model, color="red", 53 | slider=FALSE) 54 | expect_s3_class(plt, "gganim") 55 | }) 56 | 57 | test_that("plot, no slider, kaplan_meier", { 58 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 59 | data=sim_dat, model=model, color="red", 60 | slider=FALSE, kaplan_meier=TRUE, 61 | km_size=1, km_alpha=0.8, km_linetype="dashed", 62 | km_color="red", km_ci=TRUE, km_ci_type="log", 63 | km_ci_level=0.9, km_ci_alpha=0.3) 64 | expect_s3_class(plt, "gganim") 65 | }) 66 | 67 | test_that("plot, no slider, with ci", { 68 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 69 | data=sim_dat, model=model, color="red", 70 | slider=FALSE, conf_int=TRUE, n_boot=3) 71 | expect_s3_class(plt, "gganim") 72 | }) 73 | 74 | test_that("plot, with group", { 75 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 76 | group="group", data=sim_dat, model=model) 77 | expect_s3_class(plt, "plotly") 78 | }) 79 | 80 | test_that("plot, lots of stuff", { 81 | plt <- plot_surv_animated(time="time", status="event", variable="x3", 82 | data=sim_dat, model=model, cif=TRUE, 83 | linetype="dashed", alpha=0.8, title="Title", 84 | subtitle="Subtitle", xlab="x", ylab="y", 85 | gg_theme=ggplot2::theme_classic()) 86 | expect_s3_class(plt, "plotly") 87 | }) 88 | 89 | test_that("error when trying conf_int with slider", { 90 | expect_error(plot_surv_animated(time="time", status="event", variable="x3", 91 | group="group", data=sim_dat, model=model, 92 | conf_int=TRUE, n_boot=2), 93 | paste0("Showing confidence intervals is currently not ", 94 | "supported when using slider=TRUE.")) 95 | }) 96 | 97 | test_that("error when trying km_ci with slider", { 98 | expect_error(plot_surv_animated(time="time", status="event", variable="x3", 99 | group="group", data=sim_dat, model=model, 100 | kaplan_meier=TRUE, km_ci=TRUE), 101 | paste0("Showing confidence intervals is currently not ", 102 | "supported when using slider=TRUE.")) 103 | }) 104 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_area.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | sim_dat$x4 <- sim_dat$x3 12 | sim_dat$x4[sim_dat$x4 > 30] <- sim_dat$x4[sim_dat$x4 > 30] - 100 13 | model2 <- survival::coxph(survival::Surv(time, event) ~ splines::bs(x4, df=3), 14 | data=sim_dat, x=TRUE) 15 | 16 | test_that("plot, defaults", { 17 | plt <- plot_surv_area(time="time", status="event", variable="x3", 18 | data=sim_dat, model=model) 19 | expect_s3_class(plt, "ggplot") 20 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 21 | }) 22 | 23 | test_that("plot, with group", { 24 | plt <- plot_surv_area(time="time", status="event", variable="x3", 25 | group="group", data=sim_dat, model=model) 26 | expect_s3_class(plt, "ggplot") 27 | vdiffr::expect_doppelganger("plot, with group", fig=plt) 28 | }) 29 | 30 | test_that("plot, with nonmonotonic", { 31 | plt <- plot_surv_area(time="time", status="event", variable="x4", 32 | monotonic=FALSE, data=sim_dat, model=model2) 33 | expect_s3_class(plt, "ggplot") 34 | vdiffr::expect_doppelganger("plot, with nonmonotonic", fig=plt) 35 | }) 36 | 37 | test_that("plot, cif", { 38 | plt <- plot_surv_area(time="time", status="event", variable="x3", 39 | data=sim_dat, model=model, cif=TRUE, 40 | na.action=na.omit) 41 | expect_s3_class(plt, "ggplot") 42 | vdiffr::expect_doppelganger("plot, cif", fig=plt) 43 | }) 44 | 45 | test_that("plot, change horizon", { 46 | plt <- plot_surv_area(time="time", status="event", variable="x3", 47 | data=sim_dat, model=model, horizon=seq(30, 60, 1)) 48 | expect_s3_class(plt, "ggplot") 49 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 50 | }) 51 | 52 | test_that("plot, at t", { 53 | plt <- plot_surv_area(time="time", status="event", variable="x3", 54 | data=sim_dat, model=model, fixed_t=seq(0, 30, 1)) 55 | expect_s3_class(plt, "ggplot") 56 | vdiffr::expect_doppelganger("plot, at t", fig=plt) 57 | }) 58 | 59 | test_that("plot, custom colors", { 60 | plt <- plot_surv_area(time="time", status="event", variable="x3", 61 | data=sim_dat, model=model, start_color="grey", 62 | end_color="black") 63 | expect_s3_class(plt, "ggplot") 64 | vdiffr::expect_doppelganger("plot, custom colors", fig=plt) 65 | }) 66 | 67 | test_that("plot, discrete + bins", { 68 | plt <- plot_surv_area(time="time", status="event", variable="x3", 69 | data=sim_dat, model=model, discrete=TRUE, bins=4) 70 | expect_s3_class(plt, "ggplot") 71 | vdiffr::expect_doppelganger("plot, discrete + bins", fig=plt) 72 | }) 73 | 74 | test_that("plot, discrete round", { 75 | plt <- plot_surv_area(time="time", status="event", variable="x3", 76 | data=sim_dat, model=model, discrete=TRUE, bins=4, 77 | label_digits=3) 78 | expect_s3_class(plt, "ggplot") 79 | vdiffr::expect_doppelganger("plot, discrete round", fig=plt) 80 | }) 81 | 82 | test_that("plot, sep_lines", { 83 | plt <- plot_surv_area(time="time", status="event", variable="x3", 84 | data=sim_dat, model=model, discrete=TRUE, 85 | sep_lines=TRUE, sep_size=0.2, sep_color="green", 86 | sep_linetype="dashed") 87 | expect_s3_class(plt, "ggplot") 88 | vdiffr::expect_doppelganger("plot, sep_lines", fig=plt) 89 | }) 90 | 91 | test_that("plot, with kaplan_meier", { 92 | plt <- plot_surv_area(time="time", status="event", variable="x3", 93 | data=sim_dat, model=model, discrete=TRUE, 94 | kaplan_meier=TRUE, km_size=1, km_color="white", 95 | km_alpha=0.8, km_linetype="dashed") 96 | expect_s3_class(plt, "ggplot") 97 | vdiffr::expect_doppelganger("plot, with kaplan_meier", fig=plt) 98 | }) 99 | 100 | test_that("plot, lots of stuff", { 101 | plt <- plot_surv_area(time="time", status="event", variable="x3", 102 | data=sim_dat, model=model, start_color="grey", 103 | end_color="black", cif=TRUE, discrete=TRUE, 104 | bins=4, sep_lines=TRUE, sep_size=0.2, title="Title", 105 | subtitle="Subtitle", xlab="x", ylab="y", 106 | legend.title="legend", legend.position="bottom", 107 | gg_theme=ggplot2::theme_classic()) 108 | expect_s3_class(plt, "ggplot") 109 | vdiffr::expect_doppelganger("plot, lots of stuff", fig=plt) 110 | }) 111 | 112 | test_that("using group with monotonic=FALSE", { 113 | expect_error(plot_surv_area(time="time", status="event", variable="x3", 114 | monotonic=FALSE, group="group", 115 | data=sim_dat, model=model), 116 | "The 'group' argument cannot be used with monotonic=FALSE.") 117 | }) 118 | 119 | test_that("using discrete with monotonic=FALSE", { 120 | expect_warning(plot_surv_area(time="time", status="event", variable="x3", 121 | monotonic=FALSE, discrete=TRUE, 122 | data=sim_dat, model=model), 123 | paste0("To obtain valid results when using monotonic=FALSE, the", 124 | " 'horizon' should contain at least 40 distinct values.")) 125 | }) 126 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_at_t.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | set.seed(34) 12 | 13 | test_that("plot, defaults", { 14 | plt <- plot_surv_at_t(time="time", status="event", variable="x3", 15 | data=sim_dat, model=model, t=20) 16 | expect_s3_class(plt, "ggplot") 17 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 18 | }) 19 | 20 | test_that("plot, with ci, one t", { 21 | plt <- plot_surv_at_t(time="time", status="event", variable="x3", 22 | data=sim_dat, model=model, t=20, conf_int=TRUE, 23 | n_boot=3) 24 | expect_s3_class(plt, "ggplot") 25 | vdiffr::expect_doppelganger("plot, with ci, one t", fig=plt) 26 | }) 27 | 28 | test_that("plot, with ci, multiple t", { 29 | plt <- plot_surv_at_t(time="time", status="event", variable="x3", 30 | data=sim_dat, model=model, t=c(20, 25), conf_int=TRUE, 31 | n_boot=3) 32 | expect_s3_class(plt, "ggplot") 33 | vdiffr::expect_doppelganger("plot, with ci, multiple t", fig=plt) 34 | }) 35 | 36 | test_that("plot, cif", { 37 | plt <- plot_surv_at_t(time="time", status="event", variable="x3", 38 | data=sim_dat, model=model, cif=TRUE, t=20, 39 | na.action=na.omit) 40 | expect_s3_class(plt, "ggplot") 41 | vdiffr::expect_doppelganger("plot, cif", fig=plt) 42 | }) 43 | 44 | test_that("plot, change horizon", { 45 | plt <- plot_surv_at_t(time="time", status="event", variable="x3", 46 | data=sim_dat, model=model, horizon=seq(30, 60, 1), 47 | t=20) 48 | expect_s3_class(plt, "ggplot") 49 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 50 | }) 51 | 52 | test_that("plot, custom colors", { 53 | plt <- plot_surv_at_t(time="time", status="event", variable="x3", 54 | data=sim_dat, model=model, t=c(7, 20, 45), 55 | custom_colors=c("black", "red", "green")) 56 | expect_s3_class(plt, "ggplot") 57 | vdiffr::expect_doppelganger("plot, custom colors", fig=plt) 58 | }) 59 | 60 | test_that("plot, with group", { 61 | plt <- plot_surv_at_t(time="time", status="event", variable="x3", 62 | group="group", data=sim_dat, model=model, t=20) 63 | expect_s3_class(plt, "ggplot") 64 | vdiffr::expect_doppelganger("plot, with group", fig=plt) 65 | }) 66 | 67 | test_that("plot, lots of stuff", { 68 | plt <- plot_surv_at_t(time="time", status="event", variable="x3", 69 | data=sim_dat, model=model, cif=TRUE, t=35, 70 | linetype="dashed", alpha=0.8, title="Title", 71 | subtitle="Subtitle", xlab="x", ylab="y", 72 | gg_theme=ggplot2::theme_classic()) 73 | expect_s3_class(plt, "ggplot") 74 | vdiffr::expect_doppelganger("plot, lots of stuff", fig=plt) 75 | }) 76 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_contour.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | # NOTE: The expect_doppelganger() tests sometimes do not work properly 12 | # for contour plots for unknown reasons. The output looks the same, 13 | # but gets flagged as different by ubuntu for example. Skipped. 14 | 15 | # to skip tests on github 16 | skip_on_actions <- function() { 17 | if (!identical(Sys.getenv("GITHUB_ACTIONS"), "true")) { 18 | return(invisible(TRUE)) 19 | } 20 | skip("On GitHub Actions") 21 | } 22 | 23 | test_that("plot, defaults", { 24 | plt <- plot_surv_contour(time="time", status="event", variable="x3", 25 | data=sim_dat, model=model) 26 | expect_s3_class(plt, "ggplot") 27 | skip_on_cran() 28 | skip_on_covr() 29 | skip_on_actions() 30 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 31 | }) 32 | 33 | test_that("plot, with group", { 34 | plt <- plot_surv_contour(time="time", status="event", variable="x3", 35 | group="group", data=sim_dat, model=model) 36 | expect_s3_class(plt, "ggplot") 37 | skip_on_cran() 38 | skip_on_covr() 39 | skip_on_actions() 40 | vdiffr::expect_doppelganger("plot, with group", fig=plt) 41 | }) 42 | 43 | test_that("plot, cif", { 44 | plt <- plot_surv_contour(time="time", status="event", variable="x3", 45 | data=sim_dat, model=model, cif=TRUE) 46 | expect_s3_class(plt, "ggplot") 47 | skip_on_cran() 48 | skip_on_covr() 49 | skip_on_actions() 50 | vdiffr::expect_doppelganger("plot, cif", fig=plt) 51 | }) 52 | 53 | test_that("plot, change horizon", { 54 | plt <- plot_surv_contour(time="time", status="event", variable="x3", 55 | data=sim_dat, model=model, horizon=seq(30, 60, 1)) 56 | expect_s3_class(plt, "ggplot") 57 | skip_on_cran() 58 | skip_on_covr() 59 | skip_on_actions() 60 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 61 | }) 62 | 63 | test_that("plot, at t", { 64 | plt <- plot_surv_contour(time="time", status="event", variable="x3", 65 | data=sim_dat, model=model, fixed_t=seq(0, 30, 1)) 66 | expect_s3_class(plt, "ggplot") 67 | skip_on_cran() 68 | skip_on_covr() 69 | skip_on_actions() 70 | vdiffr::expect_doppelganger("plot, at t", fig=plt) 71 | }) 72 | 73 | test_that("plot, custom colors", { 74 | plt <- plot_surv_contour(time="time", status="event", variable="x3", 75 | data=sim_dat, model=model, bins=5, 76 | custom_colors=c("black", "grey", "red", "yellow", 77 | "green")) 78 | expect_s3_class(plt, "ggplot") 79 | skip_on_cran() 80 | skip_on_covr() 81 | skip_on_actions() 82 | vdiffr::expect_doppelganger("plot, custom colors", fig=plt) 83 | }) 84 | 85 | test_that("plot, panel_border / axis_dist", { 86 | plt <- plot_surv_contour(time="time", status="event", variable="x3", 87 | data=sim_dat, model=model, panel_border=TRUE, 88 | axis_dist=0.1, na.action=na.omit) 89 | expect_s3_class(plt, "ggplot") 90 | skip_on_cran() 91 | skip_on_covr() 92 | skip_on_actions() 93 | vdiffr::expect_doppelganger("plot, panel_border / axis_dist", fig=plt) 94 | }) 95 | 96 | test_that("plot, lots of stuff", { 97 | plt <- plot_surv_contour(time="time", status="event", variable="x3", 98 | data=sim_dat, model=model, start_color="grey", 99 | end_color="black", cif=TRUE, contour_lines=TRUE, 100 | contour_size=1, contour_linetype="dotdash", 101 | title="Title", subtitle="Subtitle", 102 | xlab="x", ylab="y", 103 | legend.title="legend", legend.position="bottom", 104 | gg_theme=ggplot2::theme_classic()) 105 | expect_s3_class(plt, "ggplot") 106 | skip_on_cran() 107 | skip_on_covr() 108 | skip_on_actions() 109 | vdiffr::expect_doppelganger("plot, lots of stuff", fig=plt) 110 | }) 111 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_heatmap.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | # to skip tests on github 12 | skip_on_actions <- function() { 13 | if (!identical(Sys.getenv("GITHUB_ACTIONS"), "true")) { 14 | return(invisible(TRUE)) 15 | } 16 | skip("On GitHub Actions") 17 | } 18 | 19 | test_that("plot, defaults", { 20 | plt <- plot_surv_heatmap(time="time", status="event", variable="x3", 21 | data=sim_dat, model=model) 22 | expect_s3_class(plt, "ggplot") 23 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 24 | }) 25 | 26 | test_that("plot, with group", { 27 | plt <- plot_surv_heatmap(time="time", status="event", variable="x3", 28 | group="group", data=sim_dat, model=model) 29 | expect_s3_class(plt, "ggplot") 30 | vdiffr::expect_doppelganger("plot, with group", fig=plt) 31 | }) 32 | 33 | test_that("plot, cif", { 34 | plt <- plot_surv_heatmap(time="time", status="event", variable="x3", 35 | data=sim_dat, model=model, cif=TRUE) 36 | expect_s3_class(plt, "ggplot") 37 | vdiffr::expect_doppelganger("plot, cif", fig=plt) 38 | }) 39 | 40 | test_that("plot, change horizon", { 41 | plt <- plot_surv_heatmap(time="time", status="event", variable="x3", 42 | data=sim_dat, model=model, horizon=seq(30, 60, 1)) 43 | expect_s3_class(plt, "ggplot") 44 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 45 | }) 46 | 47 | test_that("plot, at t", { 48 | plt <- plot_surv_heatmap(time="time", status="event", variable="x3", 49 | data=sim_dat, model=model, fixed_t=seq(0, 30, 1)) 50 | expect_s3_class(plt, "ggplot") 51 | vdiffr::expect_doppelganger("plot, at t", fig=plt) 52 | }) 53 | 54 | test_that("plot, custom colors", { 55 | plt <- plot_surv_heatmap(time="time", status="event", variable="x3", 56 | data=sim_dat, model=model, start_color="grey", 57 | end_color="black") 58 | expect_s3_class(plt, "ggplot") 59 | vdiffr::expect_doppelganger("plot, custom colors", fig=plt) 60 | }) 61 | 62 | test_that("plot, panel_border / axis_dist", { 63 | plt <- plot_surv_heatmap(time="time", status="event", variable="x3", 64 | data=sim_dat, model=model, panel_border=TRUE, 65 | axis_dist=0.1) 66 | expect_s3_class(plt, "ggplot") 67 | vdiffr::expect_doppelganger("plot, panel_border / axis_dist", fig=plt) 68 | }) 69 | 70 | test_that("plot, contour_lines", { 71 | plt <- plot_surv_heatmap(time="time", status="event", variable="x3", 72 | data=sim_dat, model=model, contour_lines=TRUE, 73 | contour_size=1, contour_linetype="solid", 74 | na.action=na.omit) 75 | expect_s3_class(plt, "ggplot") 76 | skip_on_cran() 77 | skip_on_covr() 78 | skip_on_actions() 79 | vdiffr::expect_doppelganger("plot, contour_lines", fig=plt) 80 | }) 81 | 82 | test_that("plot, lots of stuff", { 83 | plt <- plot_surv_heatmap(time="time", status="event", variable="x3", 84 | data=sim_dat, model=model, start_color="grey", 85 | end_color="black", cif=TRUE, contour_lines=TRUE, 86 | contour_size=1, contour_linetype="dotdash", 87 | title="Title", subtitle="Subtitle", 88 | xlab="x", ylab="y", 89 | legend.title="legend", legend.position="bottom", 90 | gg_theme=ggplot2::theme_classic()) 91 | expect_s3_class(plt, "ggplot") 92 | vdiffr::expect_doppelganger("plot, lots of stuff", fig=plt) 93 | }) 94 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_lines.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | test_that("plot, defaults", { 12 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 13 | data=sim_dat, model=model) 14 | expect_s3_class(plt, "ggplot") 15 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 16 | }) 17 | 18 | test_that("plot, kaplan_meier", { 19 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 20 | data=sim_dat, model=model, kaplan_meier=TRUE, 21 | km_color="black", km_size=1, km_linetype="dashed", 22 | km_alpha=0.8, km_ci=TRUE, km_ci_type="log", 23 | km_ci_level=0.9, km_ci_alpha=0.4) 24 | expect_s3_class(plt, "ggplot") 25 | vdiffr::expect_doppelganger("plot, kaplan_meier", fig=plt) 26 | }) 27 | 28 | test_that("plot, with ci", { 29 | set.seed(455) 30 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 31 | data=sim_dat, model=model, conf_int=TRUE, 32 | n_boot=3, horizon=c(10, 30)) 33 | expect_s3_class(plt, "ggplot") 34 | vdiffr::expect_doppelganger("plot, with ci", fig=plt) 35 | }) 36 | 37 | test_that("plot, with group", { 38 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 39 | group="group", data=sim_dat, model=model) 40 | expect_s3_class(plt, "ggplot") 41 | vdiffr::expect_doppelganger("plot, with group", fig=plt) 42 | }) 43 | 44 | test_that("plot, cif", { 45 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 46 | data=sim_dat, model=model, cif=TRUE) 47 | expect_s3_class(plt, "ggplot") 48 | vdiffr::expect_doppelganger("plot, cif", fig=plt) 49 | }) 50 | 51 | test_that("plot, change horizon", { 52 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 53 | data=sim_dat, model=model, horizon=seq(30, 60, 1)) 54 | expect_s3_class(plt, "ggplot") 55 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 56 | }) 57 | 58 | test_that("plot, at t", { 59 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 60 | data=sim_dat, model=model, fixed_t=seq(0, 30, 1)) 61 | expect_s3_class(plt, "ggplot") 62 | vdiffr::expect_doppelganger("plot, at t", fig=plt) 63 | }) 64 | 65 | test_that("plot, custom colors", { 66 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 67 | data=sim_dat, model=model, horizon=c(7, 20, 45), 68 | custom_colors=c("black", "red", "green"), 69 | na.action=na.omit) 70 | expect_s3_class(plt, "ggplot") 71 | vdiffr::expect_doppelganger("plot, custom colors", fig=plt) 72 | }) 73 | 74 | test_that("plot, cont color", { 75 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 76 | data=sim_dat, model=model, discrete=FALSE, 77 | start_color="red", end_color="green") 78 | expect_s3_class(plt, "ggplot") 79 | vdiffr::expect_doppelganger("plot, cont color", fig=plt) 80 | }) 81 | 82 | test_that("plot, lots of stuff", { 83 | plt <- plot_surv_lines(time="time", status="event", variable="x3", 84 | data=sim_dat, model=model, cif=TRUE, discrete=TRUE, 85 | linetype="dashed", alpha=0.8, title="Title", 86 | subtitle="Subtitle", xlab="x", ylab="y", 87 | gg_theme=ggplot2::theme_classic()) 88 | expect_s3_class(plt, "ggplot") 89 | vdiffr::expect_doppelganger("plot, lots of stuff", fig=plt) 90 | }) 91 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_matrix.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | test_that("plot, defaults", { 12 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 13 | data=sim_dat, model=model) 14 | expect_s3_class(plt, "ggplot") 15 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 16 | }) 17 | 18 | test_that("plot, cif", { 19 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 20 | data=sim_dat, model=model, cif=TRUE) 21 | expect_s3_class(plt, "ggplot") 22 | vdiffr::expect_doppelganger("plot, cif", fig=plt) 23 | }) 24 | 25 | test_that("plot, change horizon", { 26 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 27 | data=sim_dat, model=model, horizon=seq(30, 60, 1)) 28 | expect_s3_class(plt, "ggplot") 29 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 30 | }) 31 | 32 | test_that("plot, change fixed_t", { 33 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 34 | data=sim_dat, model=model, fixed_t=seq(0, 30, 1)) 35 | expect_s3_class(plt, "ggplot") 36 | vdiffr::expect_doppelganger("plot, change fixed_t", fig=plt) 37 | }) 38 | 39 | test_that("plot, custom colors", { 40 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 41 | data=sim_dat, model=model, start_color="grey", 42 | end_color="black") 43 | expect_s3_class(plt, "ggplot") 44 | vdiffr::expect_doppelganger("plot, custom colors", fig=plt) 45 | }) 46 | 47 | test_that("plot, panel_border / axis_dist", { 48 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 49 | data=sim_dat, model=model, panel_border=TRUE, 50 | axis_dist=0.1) 51 | expect_s3_class(plt, "ggplot") 52 | vdiffr::expect_doppelganger("plot, panel_border / axis_dist", fig=plt) 53 | }) 54 | 55 | test_that("plot, change n_col and n_row", { 56 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 57 | data=sim_dat, model=model, n_row=5, n_col=5) 58 | expect_s3_class(plt, "ggplot") 59 | vdiffr::expect_doppelganger("plot, change n_col and n_row", fig=plt) 60 | }) 61 | 62 | test_that("plot, change border stuff", { 63 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 64 | data=sim_dat, model=model, border_color="black", 65 | border_size=2) 66 | expect_s3_class(plt, "ggplot") 67 | vdiffr::expect_doppelganger("plot, change border stuff", fig=plt) 68 | }) 69 | 70 | test_that("plot, change numbers stuff", { 71 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 72 | data=sim_dat, model=model, 73 | number_color="black", number_digits=1, 74 | number_size=5, number_fontface="italic", 75 | number_family="serif") 76 | expect_s3_class(plt, "ggplot") 77 | vdiffr::expect_doppelganger("plot, change numbers stuff", fig=plt) 78 | }) 79 | 80 | test_that("plot, using group", { 81 | plt <- plot_surv_matrix(time="time", status="event", variable="x3", 82 | data=sim_dat, model=model, group="group") 83 | expect_s3_class(plt, "ggplot") 84 | vdiffr::expect_doppelganger("plot, using group", fig=plt) 85 | }) 86 | 87 | test_that("n_col too big", { 88 | expect_error(plot_surv_matrix(time="time", status="event", variable="x3", 89 | data=sim_dat, model=model, n_col=105), 90 | paste0("'n_col' must be smaller than length(fixed_t). ", 91 | "Decrease n_col or increase the number of points ", 92 | "in time used in the estimation."), fixed=TRUE) 93 | }) 94 | 95 | test_that("n_row too big", { 96 | expect_error(plot_surv_matrix(time="time", status="event", variable="x3", 97 | data=sim_dat, model=model, n_row=105), 98 | paste0("'n_row' must be smaller than length(horizon). ", 99 | "Decrease n_row or increase the number of values ", 100 | "in horizon used in the estimation."), fixed=TRUE) 101 | }) 102 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_quantiles.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | test_that("plot, defaults", { 12 | plt <- plot_surv_quantiles(time="time", status="event", variable="x3", 13 | data=sim_dat, model=model) 14 | expect_s3_class(plt, "ggplot") 15 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 16 | }) 17 | 18 | test_that("plot, with group", { 19 | plt <- plot_surv_quantiles(time="time", status="event", variable="x3", 20 | group="group", data=sim_dat, model=model) 21 | expect_s3_class(plt, "ggplot") 22 | vdiffr::expect_doppelganger("plot, with group", fig=plt) 23 | }) 24 | 25 | test_that("plot, change horizon", { 26 | plt <- plot_surv_quantiles(time="time", status="event", variable="x3", 27 | data=sim_dat, model=model, horizon=seq(30, 60, 1)) 28 | expect_s3_class(plt, "ggplot") 29 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 30 | }) 31 | 32 | test_that("plot, custom colors", { 33 | plt <- plot_surv_quantiles(time="time", status="event", variable="x3", 34 | data=sim_dat, model=model, p=c(0.25, 0.5, 0.75), 35 | custom_colors=c("black", "red", "green")) 36 | expect_s3_class(plt, "ggplot") 37 | vdiffr::expect_doppelganger("plot, custom colors", fig=plt) 38 | }) 39 | 40 | test_that("plot, single color", { 41 | plt <- plot_surv_quantiles(time="time", status="event", variable="x3", 42 | data=sim_dat, model=model, p=c(0.25, 0.5, 0.75), 43 | single_color="blue", na.action=na.omit) 44 | expect_s3_class(plt, "ggplot") 45 | vdiffr::expect_doppelganger("plot, single colors", fig=plt) 46 | }) 47 | 48 | test_that("plot, lots of stuff", { 49 | plt <- plot_surv_quantiles(time="time", status="event", variable="x3", 50 | data=sim_dat, model=model, 51 | linetype="dashed", alpha=0.8, title="Title", 52 | subtitle="Subtitle", xlab="x", ylab="y", 53 | gg_theme=ggplot2::theme_classic()) 54 | expect_s3_class(plt, "ggplot") 55 | vdiffr::expect_doppelganger("plot, lots of stuff", fig=plt) 56 | }) 57 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_rmst.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | test_that("plot, defaults", { 12 | plt <- plot_surv_rmst(time="time", status="event", variable="x3", 13 | data=sim_dat, model=model, tau=35) 14 | expect_s3_class(plt, "ggplot") 15 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 16 | }) 17 | 18 | test_that("plot, with group", { 19 | plt <- plot_surv_rmst(time="time", status="event", variable="x3", 20 | group="group", data=sim_dat, model=model, tau=35) 21 | expect_s3_class(plt, "ggplot") 22 | vdiffr::expect_doppelganger("plot, with group", fig=plt) 23 | }) 24 | 25 | test_that("plot, change horizon", { 26 | plt <- plot_surv_rmst(time="time", status="event", variable="x3", 27 | data=sim_dat, model=model, horizon=seq(30, 60, 1), 28 | tau=35, na.action=na.omit) 29 | expect_s3_class(plt, "ggplot") 30 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 31 | }) 32 | 33 | test_that("plot, custom_colors", { 34 | plt <- plot_surv_rmst(time="time", status="event", variable="x3", 35 | data=sim_dat, model=model, tau=c(20, 35), 36 | custom_colors=c("green", "grey")) 37 | expect_s3_class(plt, "ggplot") 38 | vdiffr::expect_doppelganger("plot, custom_colors", fig=plt) 39 | }) 40 | 41 | test_that("plot, lots of stuff", { 42 | plt <- plot_surv_rmst(time="time", status="event", variable="x3", 43 | data=sim_dat, model=model, tau=c(20, 37, 50), 44 | linetype="dashed", alpha=0.8, title="Title", 45 | subtitle="Subtitle", xlab="x", ylab="y", 46 | gg_theme=ggplot2::theme_classic()) 47 | expect_s3_class(plt, "ggplot") 48 | vdiffr::expect_doppelganger("plot, lots of stuff", fig=plt) 49 | }) 50 | -------------------------------------------------------------------------------- /tests/testthat/test_plot_surv_rmtl.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | test_that("plot, defaults", { 12 | plt <- plot_surv_rmtl(time="time", status="event", variable="x3", 13 | data=sim_dat, model=model, tau=35) 14 | expect_s3_class(plt, "ggplot") 15 | vdiffr::expect_doppelganger("plot, defaults", fig=plt) 16 | }) 17 | 18 | test_that("plot, with group", { 19 | plt <- plot_surv_rmtl(time="time", status="event", variable="x3", 20 | group="group", data=sim_dat, model=model, tau=35) 21 | expect_s3_class(plt, "ggplot") 22 | vdiffr::expect_doppelganger("plot, with group", fig=plt) 23 | }) 24 | 25 | test_that("plot, change horizon", { 26 | plt <- plot_surv_rmtl(time="time", status="event", variable="x3", 27 | data=sim_dat, model=model, horizon=seq(30, 60, 1), 28 | tau=35, na.action=na.omit) 29 | expect_s3_class(plt, "ggplot") 30 | vdiffr::expect_doppelganger("plot, change horizon", fig=plt) 31 | }) 32 | 33 | test_that("plot, custom_colors", { 34 | plt <- plot_surv_rmtl(time="time", status="event", variable="x3", 35 | data=sim_dat, model=model, tau=c(20, 35), 36 | custom_colors=c("green", "grey")) 37 | expect_s3_class(plt, "ggplot") 38 | vdiffr::expect_doppelganger("plot, custom_colors", fig=plt) 39 | }) 40 | 41 | test_that("plot, lots of stuff", { 42 | plt <- plot_surv_rmtl(time="time", status="event", variable="x3", 43 | data=sim_dat, model=model, tau=37, 44 | linetype="dashed", alpha=0.8, title="Title", 45 | subtitle="Subtitle", xlab="x", ylab="y", 46 | gg_theme=ggplot2::theme_classic()) 47 | expect_s3_class(plt, "ggplot") 48 | vdiffr::expect_doppelganger("plot, lots of stuff", fig=plt) 49 | }) 50 | -------------------------------------------------------------------------------- /tests/testthat/test_prepare_inputdata.r: -------------------------------------------------------------------------------- 1 | 2 | suppressMessages(requireNamespace("survival")) 3 | 4 | sim_dat <- readRDS(system.file("testdata", "sim150.Rds", 5 | package="contsurvplot")) 6 | sim_dat$group <- as.factor(sim_dat$group) 7 | 8 | model <- survival::coxph(survival::Surv(time, event) ~ x3 + group, 9 | data=sim_dat, x=TRUE) 10 | 11 | model_glm <- glm(time ~ x3 + x1 + group, data=sim_dat) 12 | model_pecRpart <- list(rpart=list(terms=time ~ x3 + x1 + group)) 13 | class(model_pecRpart) <- "pecRpart" 14 | model_ranger <- list(call=list(A="something", B=time ~ x3 + x1 + group)) 15 | class(model_ranger) <- "ranger" 16 | 17 | test_that("glm model", { 18 | dat_clean <- prepare_inputdata(data=sim_dat, 19 | time="time", 20 | status="event", 21 | variable="x3", 22 | group=NULL, 23 | model=model_glm, 24 | na.action="na.omit") 25 | expect_true(nrow(sim_dat)==nrow(dat_clean)) 26 | expect_true(ncol(dat_clean)==5) 27 | }) 28 | 29 | test_that("pecRpart model", { 30 | dat_clean <- prepare_inputdata(data=sim_dat, 31 | time="time", 32 | status="event", 33 | variable="x3", 34 | group=NULL, 35 | model=model_pecRpart, 36 | na.action="na.omit") 37 | expect_true(nrow(sim_dat)==nrow(dat_clean)) 38 | expect_true(ncol(dat_clean)==5) 39 | }) 40 | 41 | test_that("ranger model", { 42 | dat_clean <- prepare_inputdata(data=sim_dat, 43 | time="time", 44 | status="event", 45 | variable="x3", 46 | group=NULL, 47 | model=model_ranger, 48 | na.action="na.omit") 49 | expect_true(nrow(sim_dat)==nrow(dat_clean)) 50 | expect_true(ncol(dat_clean)==5) 51 | }) 52 | 53 | test_that("NULL model", { 54 | dat_clean <- prepare_inputdata(data=sim_dat, 55 | time="time", 56 | status="event", 57 | variable="x3", 58 | group=NULL, 59 | model="A", 60 | na.action="na.omit") 61 | expect_true(nrow(sim_dat)==nrow(dat_clean)) 62 | expect_true(ncol(dat_clean)==3) 63 | }) 64 | 65 | test_that("wrong data", { 66 | expect_error(use_data.frame("A"), 67 | "'data' must be a data.frame object.") 68 | }) 69 | 70 | sim_dat$group <- NA 71 | 72 | test_that("no data left after na.action", { 73 | expect_error(prepare_inputdata(data=sim_dat, 74 | time="time", 75 | status="event", 76 | variable="x3", 77 | group=NULL, 78 | model=model, 79 | na.action="na.omit"), 80 | "There is no data left after removing the missing values.") 81 | }) 82 | -------------------------------------------------------------------------------- /tests/testthat/test_read_from_step_function.r: -------------------------------------------------------------------------------- 1 | 2 | test_dat <- data.frame(time=c(0.01, 0.1, 0.2, 0.3, 0.6, 0.63), 3 | surv=c(0.999, 0.99, 0.8, 0.76, 0.5, 0.3), 4 | cif=1-c(1, 0.99, 0.8, 0.76, 0.5, 0.3)) 5 | 6 | test_that("surv, t = 0, start", { 7 | out <- read_from_step_function(0, data=test_dat, est="surv") 8 | expect_equal(out, 1) 9 | }) 10 | 11 | test_that("cif, t = 0, start", { 12 | out <- read_from_step_function(0, data=test_dat, est="cif") 13 | expect_equal(out, 0) 14 | }) 15 | 16 | test_that("surv, t = 0.2, on jump", { 17 | out <- read_from_step_function(0.2, data=test_dat, est="surv") 18 | expect_equal(out, 0.8) 19 | }) 20 | 21 | test_that("cif, t = 0.2, on jump", { 22 | out <- read_from_step_function(0.2, data=test_dat, est="cif") 23 | expect_equal(out, 0.2) 24 | }) 25 | 26 | test_that("surv, t = 0.4, in slope = 0", { 27 | out <- read_from_step_function(0.4, data=test_dat, est="surv") 28 | expect_equal(out, 0.76) 29 | }) 30 | 31 | test_that("cif, t = 0.4, in slope = 0", { 32 | out <- read_from_step_function(0.4, data=test_dat, est="cif") 33 | expect_equal(out, 0.24) 34 | }) 35 | 36 | test_that("surv, t = 0.63, end", { 37 | out <- read_from_step_function(0.63, data=test_dat, est="surv") 38 | expect_equal(out, 0.3) 39 | }) 40 | 41 | test_that("cif, t = 0.63, end", { 42 | out <- read_from_step_function(0.63, data=test_dat, est="cif") 43 | expect_equal(out, 0.7) 44 | }) 45 | 46 | test_that("surv, t = 0.64, no extrapolation", { 47 | out <- read_from_step_function(0.64, data=test_dat, est="surv") 48 | expect_true(is.na(out)) 49 | }) 50 | 51 | test_that("cif, t = 0.64, no extrapolation", { 52 | out <- read_from_step_function(0.64, data=test_dat, est="cif") 53 | expect_true(is.na(out)) 54 | }) 55 | 56 | test_dat$est <- test_dat$surv 57 | 58 | test_that("est, t = 0, start", { 59 | out <- read_from_step_function(0, data=test_dat, est="est") 60 | expect_true(is.na(out)) 61 | }) 62 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | --------------------------------------------------------------------------------