├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ └── recheck.yml ├── .gitignore ├── .travis.yml ├── CONDUCT.md ├── DESCRIPTION ├── LICENSE ├── Makefile ├── NAMESPACE ├── NEWS.md ├── R ├── bootstrap.R ├── check_boundaries.R ├── check_dates.R ├── check_dots.R ├── check_groups.R ├── check_interval.R ├── check_timespan.R ├── check_week.R ├── conversion.R ├── cumulate.R ├── dim.R ├── estimate_peak.R ├── extract_info.R ├── find_peak.R ├── fit.R ├── fit_optim_split.R ├── get_counts.R ├── get_dates.R ├── get_fit.R ├── get_info.R ├── get_interval.R ├── get_n.R ├── get_timespan.R ├── get_week.R ├── group_names.R ├── incidence.R ├── internals.R ├── make_breaks.R ├── make_incidence.R ├── palettes.R ├── plot.R ├── pool.R ├── print.R ├── scale_x_incidence.R ├── subset.R ├── trim_observations.R ├── valid_interval.R └── zzz.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── appveyor.yml ├── artwork ├── banner.png ├── logo │ ├── logo.png │ └── logo.svg └── workflow │ ├── workflow.svg │ └── workflow_script.R ├── bug_reports └── issue_34.R ├── codecov.yml ├── cran-comments.md ├── demo ├── 00Index └── incidence-demo.R ├── docs ├── 404.html ├── CONDUCT.html ├── LICENSE-text.html ├── articles │ ├── conversions.html │ ├── conversions_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ └── figure-html │ │ │ ├── example-1.png │ │ │ ├── iso-1.png │ │ │ ├── long-1.png │ │ │ ├── unnamed-chunk-3-1.png │ │ │ ├── unnamed-chunk-3-2.png │ │ │ └── unnamed-chunk-4-1.png │ ├── customize_plot.html │ ├── customize_plot_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ └── figure-html │ │ │ ├── EPIET1-1.png │ │ │ ├── colors1-1.png │ │ │ ├── colors2-1.png │ │ │ ├── colors3-1.png │ │ │ ├── default-1.png │ │ │ ├── default-2.png │ │ │ ├── default-3.png │ │ │ ├── grid1-1.png │ │ │ ├── grid2-1.png │ │ │ ├── incidence_pal1-1.png │ │ │ ├── label-bins-1.png │ │ │ ├── legend1-1.png │ │ │ ├── pal2-1.png │ │ │ ├── palettes-1.png │ │ │ ├── palettes-2.png │ │ │ ├── saturday-epiweek-1.png │ │ │ ├── saturday-epiweek2-1.png │ │ │ ├── saturday-epiweek3-1.png │ │ │ ├── scales1-1.png │ │ │ ├── scales2-1.png │ │ │ └── scales_breaks-1.png │ ├── incidence_class.html │ ├── incidence_class_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ └── figure-html │ │ │ ├── i-1.png │ │ │ └── sex-1.png │ ├── incidence_fit_class.html │ ├── incidence_fit_class_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ └── figure-html │ │ │ ├── combine-1.png │ │ │ ├── fit_dates-1.png │ │ │ ├── fit_gender-1.png │ │ │ ├── incidence_by_gender-1.png │ │ │ ├── incidence_fit_list-1.png │ │ │ └── list_stuff-1.png │ ├── index.html │ ├── overview.html │ └── overview_files │ │ ├── accessible-code-block-0.0.1 │ │ └── empty-anchor.js │ │ └── figure-html │ │ ├── fit.both-1.png │ │ ├── fit1-1.png │ │ ├── gender-1.png │ │ ├── groupsub-1.png │ │ ├── hosp-1.png │ │ ├── i7outcome-1.png │ │ ├── incid1-1.png │ │ ├── interv-1.png │ │ ├── interv-2.png │ │ ├── interv-3.png │ │ ├── middle-1.png │ │ ├── optim-1.png │ │ ├── optim-2.png │ │ ├── optim2-1.png │ │ ├── optim2-2.png │ │ ├── stripes-1.png │ │ ├── tail-1.png │ │ ├── unnamed-chunk-2-1.png │ │ └── unnamed-chunk-3-1.png ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── figs │ ├── fit-plot-1-1.png │ ├── fit-plot-2-1.png │ ├── fit1-1.png │ ├── gender-1.png │ ├── i7outcome-1.png │ ├── i7outcome_cum-1.png │ ├── incid1-1.png │ ├── optim-1.png │ ├── optim-2.png │ ├── pipe-fit-1.png │ ├── start-1.png │ └── tail-1.png ├── index.html ├── link.svg ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml └── reference │ ├── accessors.html │ ├── bootstrap-1.png │ ├── bootstrap-2.png │ ├── bootstrap.html │ ├── conversions-1.png │ ├── conversions.html │ ├── cumulate-1.png │ ├── cumulate-2.png │ ├── cumulate.html │ ├── estimate_peak-1.png │ ├── estimate_peak-2.png │ ├── estimate_peak-3.png │ ├── estimate_peak-4.png │ ├── estimate_peak.html │ ├── find_peak-1.png │ ├── find_peak-2.png │ ├── find_peak-3.png │ ├── find_peak.html │ ├── fit-1.png │ ├── fit-2.png │ ├── fit-3.png │ ├── fit-4.png │ ├── fit-5.png │ ├── fit-6.png │ ├── fit-7.png │ ├── fit-8.png │ ├── fit-9.png │ ├── fit.html │ ├── get_counts.html │ ├── get_dates.html │ ├── get_fit.html │ ├── group_names.html │ ├── incidence-1.png │ ├── incidence-2.png │ ├── incidence-3.png │ ├── incidence-4.png │ ├── incidence-5.png │ ├── incidence.html │ ├── index.html │ ├── palettes-1.png │ ├── palettes-2.png │ ├── palettes-3.png │ ├── palettes-4.png │ ├── palettes.html │ ├── plot.incidence-1.png │ ├── plot.incidence-10.png │ ├── plot.incidence-11.png │ ├── plot.incidence-2.png │ ├── plot.incidence-3.png │ ├── plot.incidence-4.png │ ├── plot.incidence-5.png │ ├── plot.incidence-6.png │ ├── plot.incidence-7.png │ ├── plot.incidence-8.png │ ├── plot.incidence-9.png │ ├── plot.incidence.html │ ├── pool.html │ ├── subset-1.png │ ├── subset-2.png │ └── subset.html ├── figs ├── fit-plot-1-1.png ├── fit-plot-2-1.png ├── fit1-1.png ├── gender-1.png ├── i7outcome-1.png ├── i7outcome_cum-1.png ├── incid1-1.png ├── optim-1.png ├── optim-2.png ├── pipe-fit-1.png ├── start-1.png └── tail-1.png ├── incidence.Rproj ├── inst ├── CITATION └── WORDLIST ├── man ├── accessors.Rd ├── bootstrap.Rd ├── conversions.Rd ├── cumulate.Rd ├── estimate_peak.Rd ├── find_peak.Rd ├── fit.Rd ├── get_counts.Rd ├── get_dates.Rd ├── get_fit.Rd ├── group_names.Rd ├── incidence.Rd ├── palettes.Rd ├── plot.incidence.Rd ├── pool.Rd └── subset.Rd ├── misc └── plotly-expl.R ├── tests ├── figs │ ├── deps.txt │ └── test-plotting │ │ ├── epiquares-single-plot.svg │ │ ├── fri-weekly-incidence-with-dates.svg │ │ ├── fri-weekly-incidence-with-labels.svg │ │ ├── grouped-incidence-fit.svg │ │ ├── grouped-incidence-plot-cumulative.svg │ │ ├── grouped-incidence-plot-with-color-palette.svg │ │ ├── grouped-incidence-plot-with-fit.svg │ │ ├── grouped-incidence-plot-with-one-group.svg │ │ ├── grouped-incidence-plot-with-specified-color.svg │ │ ├── grouped-incidence-plot.svg │ │ ├── incidence-fit-list-plot-with-split.svg │ │ ├── incidence-fit-plot-with-split.svg │ │ ├── incidence-fit.svg │ │ ├── incidence-plot-by-month.svg │ │ ├── incidence-plot-by-quarter.svg │ │ ├── incidence-plot-from-posixct-data-with-fit.svg │ │ ├── incidence-plot-from-posixct-data.svg │ │ ├── incidence-plot-with-default-interval-cumulative.svg │ │ ├── incidence-plot-with-default-interval.svg │ │ ├── incidence-plot-with-interval-of-14-days.svg │ │ ├── incidence-plot-with-interval-of-3-days-fit-and-specified-color.svg │ │ ├── incidence-plot-with-isoweek-labels.svg │ │ ├── incidence-plot-with-specified-color-and-alpha.svg │ │ ├── incidence-plot-with-two-fitting-models.svg │ │ ├── incidence-plot-without-isoweek-labels.svg │ │ ├── mon-weekly-incidence-with-dates.svg │ │ ├── mon-weekly-incidence-with-labels.svg │ │ ├── sat-weekly-incidence-with-dates.svg │ │ ├── sat-weekly-incidence-with-labels.svg │ │ ├── split-optimum-plot-pooled.svg │ │ ├── split-optimum-plot.svg │ │ ├── sun-semi-weekly-incidence-with-dates-and-full-breaks.svg │ │ ├── sun-weekly-incidence-with-dates-and-full-breaks.svg │ │ ├── sun-weekly-incidence-with-dates.svg │ │ ├── sun-weekly-incidence-with-labels.svg │ │ ├── thu-weekly-incidence-with-dates.svg │ │ ├── thu-weekly-incidence-with-labels.svg │ │ ├── tue-weekly-incidence-with-dates.svg │ │ ├── tue-weekly-incidence-with-labels.svg │ │ ├── wed-weekly-incidence-with-dates.svg │ │ └── wed-weekly-incidence-with-labels.svg ├── testthat.R └── testthat │ ├── data_cache │ ├── mfcat.rds │ └── mfdat.rds │ ├── rds │ ├── df.rds │ ├── df2.rds │ ├── df3.rds │ ├── df5.rds │ ├── df6.rds │ ├── dfl.rds │ ├── fit.i.rds │ ├── fit.i.sex.rds │ ├── incidence.res1.rds │ ├── incidence.res2.rds │ ├── incidence.res3.rds │ ├── incidence.res4.rds │ ├── incidence.res5.rds │ ├── incidence.res6.rds │ ├── incidence.res7.rds │ ├── incidence.res8.rds │ ├── o.fit.i.rds │ ├── o.fit.i.sex.rds │ ├── print.fit.i.rds │ ├── print.fit.sex.rds │ ├── print1.rds │ ├── print2.rds │ ├── print3.rds │ ├── res.g.1.rds │ ├── res.g.2.rds │ ├── res.g.3.rds │ ├── x.sub1.rds │ ├── x.sub2.rds │ ├── x.sub3.rds │ ├── x.sub4.rds │ ├── x.sub5.rds │ └── y.sub1.rds │ ├── test-accessors.R │ ├── test-bootstrap.R │ ├── test-conversions.R │ ├── test-cumulate.R │ ├── test-fit.R │ ├── test-incidence.R │ ├── test-non-exported.R │ ├── test-palettes.R │ ├── test-plot.R │ ├── test-pool.R │ ├── test-standards.R │ └── test-subset.R └── vignettes ├── conversions.Rmd ├── customize_plot.Rmd ├── figs-class ├── i-1.png └── sex-1.png ├── figs-conversion ├── example-1.png ├── iso-1.png ├── long-1.png ├── unnamed-chunk-3-1.png ├── unnamed-chunk-3-2.png └── unnamed-chunk-4-1.png ├── figs-custom ├── colors1-1.png ├── colors2-1.png ├── colors3-1.png ├── default-1.png ├── default-2.png ├── default-3.png ├── grid1-1.png ├── grid2-1.png ├── incidence_pal1-1.png ├── legend1-1.png ├── pal1-1.png ├── pal2-1.png ├── palettes-1.png ├── palettes-2.png ├── scales1-1.png └── scales2-1.png ├── figs-fit ├── combine-1.png ├── fit_dates-1.png ├── fit_gender-1.png ├── incidence_by_gender-1.png ├── incidence_fit_list-1.png └── list_stuff-1.png ├── figs-overview ├── fit.both-1.png ├── fit1-1.png ├── gender-1.png ├── groupsub-1.png ├── hosp-1.png ├── i7outcome-1.png ├── incid1-1.png ├── interv-1.png ├── interv-2.png ├── interv-3.png ├── middle-1.png ├── optim-1.png ├── optim-2.png ├── optim2-1.png ├── optim2-2.png ├── stripes-1.png ├── tail-1.png ├── unnamed-chunk-2-1.png └── unnamed-chunk-3-1.png ├── incidence_class.Rmd ├── incidence_fit_class.Rmd └── overview.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^CRAN-RELEASE$ 2 | ^cran-comments\.md$ 3 | ^.*\.Rproj$ 4 | ^\.Rproj\.user$ 5 | ^\.travis\.yml$ 6 | ^incidence_.*\.tar\.gz$ 7 | ^Makefile$ 8 | ^README\.Rmd$ 9 | ^update_web\.sh$ 10 | figure/* 11 | artwork/* 12 | ^codecov\.yml$ 13 | figs/* 14 | logo/* 15 | ^README-.*\.png$ 16 | ^CONDUCT\.md$ 17 | ^docs$ 18 | ^misc$ 19 | README.md 20 | README.html 21 | ^appveyor\.yml$ 22 | bug_reports/* 23 | ^revdep/ 24 | ^_pkgdown.yml$ 25 | ^\.github$ 26 | ^CRAN-SUBMISSION$ 27 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.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 | paths: 7 | - 'data/**' 8 | - 'R/**' 9 | - 'inst/**' 10 | - 'man/**' 11 | - 'src/**' 12 | - 'tests/**' 13 | - 'vignettes/**' 14 | - 'DESCRIPTION' 15 | - 'NAMESPACE' 16 | - 'LICENSE' 17 | - '.Rbuildignore' 18 | - '.github/workflows/R-CMD-check.yaml' 19 | merge_group: 20 | pull_request: 21 | branches: [main, master] 22 | paths: 23 | - 'data/**' 24 | - 'R/**' 25 | - 'inst/**' 26 | - 'man/**' 27 | - 'src/**' 28 | - 'tests/**' 29 | - 'vignettes/**' 30 | - 'DESCRIPTION' 31 | - 'NAMESPACE' 32 | - 'LICENSE' 33 | - '.Rbuildignore' 34 | - '.github/workflows/R-CMD-check.yaml' 35 | 36 | name: R-CMD-check 37 | 38 | concurrency: 39 | group: ${{ github.workflow }}-${{ github.ref }} 40 | cancel-in-progress: true 41 | 42 | jobs: 43 | R-CMD-check: 44 | runs-on: ${{ matrix.config.os }} 45 | 46 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 47 | 48 | strategy: 49 | fail-fast: false 50 | matrix: 51 | config: 52 | - {os: macOS-latest, r: 'release'} 53 | - {os: windows-latest, r: 'release'} 54 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 55 | - {os: ubuntu-latest, r: 'release'} 56 | - {os: ubuntu-latest, r: 'oldrel-1'} 57 | 58 | env: 59 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 60 | R_KEEP_PKG_SOURCE: yes 61 | 62 | steps: 63 | - uses: actions/checkout@v4 64 | 65 | - uses: r-lib/actions/setup-pandoc@v2 66 | 67 | - uses: r-lib/actions/setup-r@v2 68 | with: 69 | r-version: ${{ matrix.config.r }} 70 | http-user-agent: ${{ matrix.config.http-user-agent }} 71 | use-public-rspm: true 72 | 73 | - uses: r-lib/actions/setup-r-dependencies@v2 74 | with: 75 | extra-packages: any::rcmdcheck 76 | needs: check 77 | 78 | - uses: r-lib/actions/check-r-package@v2 79 | id: rcmdcheck 80 | with: 81 | upload-snapshots: true 82 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' 83 | 84 | # fail-fast but only if rcmdcheck step fails 85 | - name: Manual fail-fast 86 | env: 87 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 88 | if: always() && steps.rcmdcheck.outcome == 'failure' 89 | run: gh run cancel ${{ github.run_id }} 90 | -------------------------------------------------------------------------------- /.github/workflows/recheck.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: 3 | inputs: 4 | which: 5 | type: choice 6 | description: Which dependents to check 7 | options: 8 | - strong 9 | - most 10 | 11 | name: Reverse dependency check 12 | 13 | jobs: 14 | revdep_check: 15 | name: Reverse check ${{ inputs.which }} dependents 16 | uses: r-devel/recheck/.github/workflows/recheck.yml@v1 17 | with: 18 | which: ${{ inputs.which }} 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | *.tar.gz 5 | *~ 6 | *.swp 7 | inst/doc 8 | README.htmlincidence.Rcheck 9 | incidence.Rcheck/ 10 | README.html 11 | artwork 12 | revdep 13 | 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | language: r 3 | cache: packages 4 | 5 | matrix: 6 | include: 7 | - os: linux 8 | r: release 9 | env: 10 | - R_CODECOV=true 11 | - os: linux 12 | r: devel 13 | - os: linux 14 | r: oldrel 15 | 16 | warnings_are_errors: true 17 | 18 | notifications: 19 | email: 20 | on_success: change 21 | on_failure: change 22 | 23 | after_success: 24 | - if [[ "${R_CODECOV}" ]]; then Rscript -e 'covr::codecov()'; fi 25 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: incidence 2 | Type: Package 3 | Title: Compute, Handle, Plot and Model Incidence of Dated Events 4 | Version: 1.7.5 5 | Authors@R: c( 6 | person("Thibaut", "Jombart", role = c("aut"), email = "thibautjombart@gmail.com"), 7 | person("Zhian N.", "Kamvar", role = "aut", email = "zkamvar@gmail.com", 8 | comment = c(ORCID = "0000-0003-1458-7108")), 9 | person("Rich", "FitzJohn", role = "aut", email = "rich.fitzjohn@gmail.com"), 10 | person("Tim", "Taylor", role = "cre", email = "tim.taylor@hiddenelephants.co.uk", 11 | comment = c(ORCID = "0000-0002-8587-7113")), 12 | person("Jun", "Cai", role = "ctb", email = "cai-j12@mails.tsinghua.edu.cn", 13 | comment = c(ORCID = "0000-0001-9495-1226")), 14 | person("Sangeeta", "Bhatia", role = "ctb", email = "sangeetabhatia03@gmail.com"), 15 | person("Jakob", "Schumacher", role = "ctb"), 16 | person("Juliet R.C.", "Pulliam", role = "ctb", email = "pulliam@sun.ac.za", 17 | comment = c(ORCID = "0000-0003-3314-8223")) 18 | ) 19 | Description: Provides functions and classes to compute, handle and visualise 20 | incidence from dated events for a defined time interval. Dates can be provided 21 | in various standard formats. The class 'incidence' is used to store computed 22 | incidence and can be easily manipulated, subsetted, and plotted. In addition, 23 | log-linear models can be fitted to 'incidence' objects using 'fit'. This 24 | package is part of the RECON () toolkit 25 | for outbreak analysis. 26 | Encoding: UTF-8 27 | License: MIT + file LICENSE 28 | URL: https://www.repidemicsconsortium.org/incidence/ 29 | BugReports: https://github.com/reconhub/incidence/issues 30 | RoxygenNote: 7.3.1 31 | Imports: 32 | ggplot2 (>= 3.3.2), 33 | aweek (>= 0.2.0) 34 | Suggests: 35 | magrittr, 36 | outbreaks, 37 | testthat, 38 | vdiffr, 39 | knitr, 40 | rmarkdown, 41 | scales, 42 | cowplot 43 | VignetteBuilder: knitr 44 | Roxygen: list(markdown = TRUE) 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2016 2 | COPYRIGHT HOLDER: Thibaut Jombart -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PACKAGE := $(shell grep '^Package:' DESCRIPTION | sed -E 's/^Package:[[:space:]]+//') 2 | RSCRIPT = Rscript --no-init-file 3 | 4 | all: install 5 | 6 | test: 7 | ${RSCRIPT} -e 'library(methods); devtools::test()' 8 | 9 | roxygen: 10 | @mkdir -p man 11 | ${RSCRIPT} -e "library(methods); devtools::document()" 12 | 13 | install: 14 | R CMD INSTALL . 15 | 16 | build: 17 | R CMD build . 18 | 19 | check: build 20 | _R_CHECK_CRAN_INCOMING_=FALSE R CMD check --as-cran --no-manual `ls -1tr ${PACKAGE}*gz | tail -n1` 21 | @rm -f `ls -1tr ${PACKAGE}*gz | tail -n1` 22 | @rm -rf ${PACKAGE}.Rcheck 23 | 24 | vignettes/%.Rmd: vignettes/src/%.R 25 | ${RSCRIPT} -e 'library(sowsear); sowsear("$<", output="$@")' 26 | vignettes: vignettes/incidence.Rmd 27 | ${RSCRIPT} -e 'library(methods); devtools::build_vignettes()' 28 | 29 | staticdocs: 30 | @mkdir -p inst/staticdocs 31 | ${RSCRIPT} -e "library(methods); staticdocs::build_site()" 32 | rm -f vignettes/*.html 33 | @rmdir inst/staticdocs 34 | website: staticdocs 35 | ./update_web.sh 36 | 37 | # No real targets! 38 | .PHONY: all test document install vignettes 39 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method("[",incidence) 4 | S3method("group_names<-",default) 5 | S3method("group_names<-",incidence) 6 | S3method(as.data.frame,incidence) 7 | S3method(as.incidence,data.frame) 8 | S3method(as.incidence,matrix) 9 | S3method(as.incidence,numeric) 10 | S3method(cumulate,default) 11 | S3method(cumulate,incidence) 12 | S3method(dim,incidence) 13 | S3method(get_counts,incidence) 14 | S3method(get_dates,default) 15 | S3method(get_dates,incidence) 16 | S3method(get_fit,incidence_fit) 17 | S3method(get_fit,incidence_fit_list) 18 | S3method(get_info,incidence_fit) 19 | S3method(get_info,incidence_fit_list) 20 | S3method(get_interval,default) 21 | S3method(get_interval,incidence) 22 | S3method(get_n,default) 23 | S3method(get_n,incidence) 24 | S3method(get_timespan,default) 25 | S3method(get_timespan,incidence) 26 | S3method(group_names,default) 27 | S3method(group_names,incidence) 28 | S3method(incidence,Date) 29 | S3method(incidence,POSIXt) 30 | S3method(incidence,character) 31 | S3method(incidence,default) 32 | S3method(incidence,integer) 33 | S3method(incidence,numeric) 34 | S3method(plot,incidence) 35 | S3method(plot,incidence_fit) 36 | S3method(plot,incidence_fit_list) 37 | S3method(print,incidence) 38 | S3method(print,incidence_fit) 39 | S3method(print,incidence_fit_list) 40 | S3method(subset,incidence) 41 | export("group_names<-") 42 | export(add_incidence_fit) 43 | export(as.incidence) 44 | export(bootstrap) 45 | export(cumulate) 46 | export(estimate_peak) 47 | export(find_peak) 48 | export(fit) 49 | export(fit_optim_split) 50 | export(get_counts) 51 | export(get_dates) 52 | export(get_fit) 53 | export(get_info) 54 | export(get_interval) 55 | export(get_n) 56 | export(get_timespan) 57 | export(group_names) 58 | export(incidence) 59 | export(incidence_pal1) 60 | export(incidence_pal1_dark) 61 | export(incidence_pal1_light) 62 | export(make_breaks) 63 | export(pool) 64 | export(scale_x_incidence) 65 | importFrom(grDevices,colorRampPalette) 66 | importFrom(graphics,plot) 67 | importFrom(stats,as.ts) 68 | importFrom(utils,head) 69 | importFrom(utils,tail) 70 | -------------------------------------------------------------------------------- /R/bootstrap.R: -------------------------------------------------------------------------------- 1 | #' Bootstrap incidence time series 2 | #' 3 | #' This function can be used to bootstrap `incidence` objects. Bootstrapping is 4 | #' done by sampling with replacement the original input dates. See `details` for 5 | #' more information on how this is implemented. 6 | #' 7 | #' @author Thibaut Jombart \email{thibautjombart@@gmail.com} 8 | #' 9 | #' @md 10 | #' 11 | #' @export 12 | #' 13 | #' @details As original data are not stored in `incidence` objects, the 14 | #' bootstrapping is achieved by multinomial sampling of date bins weighted by 15 | #' their relative incidence. 16 | #' 17 | #' @param x An `incidence` object. 18 | #' 19 | #' @param randomise_groups A `logical` indicating whether groups should be 20 | #' randomised as well in the resampling procedure; respective group sizes will 21 | #' be preserved, but this can be used to remove any group-specific temporal 22 | #' dynamics. If `FALSE` (default), data are resampled within groups. 23 | #' 24 | #' @return An `incidence` object. 25 | #' 26 | #' @seealso [incidence::find_peak] to use estimate peak date using bootstrap 27 | #' 28 | #' @examples 29 | #' 30 | #' if (require(outbreaks) && require(ggplot2)) { withAutoprint({ 31 | #' i <- incidence(fluH7N9_china_2013$date_of_onset) 32 | #' i 33 | #' plot(i) 34 | #' 35 | #' ## one simple bootstrap 36 | #' x <- bootstrap(i) 37 | #' x 38 | #' plot(x) 39 | #' 40 | #' })} 41 | #' 42 | 43 | bootstrap <- function(x, randomise_groups = FALSE) { 44 | if (!inherits(x, "incidence")) { 45 | stop("x is not an incidence object") 46 | } 47 | 48 | ## `counts` is a vector of event counts, meant to be a column of x$counts 49 | boot_one_group <- function(counts) { 50 | sample_(x$dates, size = sum(counts), replace = TRUE, prob = counts) 51 | } 52 | 53 | new_dates <- do.call(c, 54 | lapply(seq.int(ncol(x$counts)), 55 | function(i) boot_one_group(x$counts[, i]))) 56 | group_sizes <- colSums(x$counts) 57 | new_groups <- rep(colnames(x$counts), group_sizes) 58 | 59 | if (randomise_groups) { 60 | new_groups <- sample_(new_groups) 61 | } 62 | 63 | incidence(new_dates, interval = x$interval, groups = new_groups) 64 | 65 | } 66 | -------------------------------------------------------------------------------- /R/check_boundaries.R: -------------------------------------------------------------------------------- 1 | #' A cromulence check for first_date and _last date 2 | #' 3 | #' This will create a boundary from the data if there is none provided. 4 | #' 5 | #' @param dates a vector of dates, integers, or numerics 6 | #' @param boundary a date, integer, numeric, or character string that can resolve to a date 7 | #' @param what "first" or "last" for the first_date and last_date arguments 8 | #' 9 | #' @return a date or integer 10 | #' @noRd 11 | #' @keywords internal 12 | check_boundaries <- function(dates, boundary = NULL, what = "first") { 13 | if (is.null(boundary)) { 14 | MINMAX <- if (what == "first") min else max 15 | boundary <- MINMAX(dates, na.rm = TRUE) 16 | } 17 | msg <- "%s_date (%s) could not be converted to Date." 18 | if (is.character(boundary) && !grepl("^[0-9]{4}-[01][0-9]-[0-3][0-9]$", boundary)) { 19 | msg <- paste(msg, 'Dates must be in ISO 8601 standard format (yyyy-mm-dd).') 20 | stop(sprintf(msg, what, boundary), call. = FALSE) 21 | } 22 | res <- try(check_dates(boundary), silent = TRUE) 23 | if (inherits(res, "try-error")) { 24 | msg <- paste(msg, "Accepted formats are:", 25 | "\n Date, POSIXct, integer, numeric, character.") 26 | stop(sprintf(msg, what, deparse(substitute(boundary))), call. = FALSE) 27 | } 28 | res 29 | } 30 | -------------------------------------------------------------------------------- /R/check_dates.R: -------------------------------------------------------------------------------- 1 | #' Check date cromulence 2 | #' 3 | #' This function checks that usable dates are provided, and set non-finite 4 | #' values to NA. It also makes a few trivial conversions on the fly. 5 | #' 6 | #' @param x a vector that represents dates. Can be in almost any format 7 | #' @param error_on_NA a logical specifing whether or not an error should be 8 | #' thrown if NAs are present in the dates. Defaults to FALSE. 9 | #' @return an object in either integer, Date, or POSIXt 10 | #' @noRd 11 | check_dates <- function(x, error_on_NA = FALSE, ...) { 12 | 13 | if (is.null(x)) { 14 | stop("dates is NULL", call. = FALSE) 15 | } 16 | 17 | if (is.character(x)) { 18 | x <- as.Date(x, ...) 19 | } 20 | 21 | not_finite <- !is.finite(x) 22 | if (sum(not_finite) > 0) { 23 | x[not_finite] <- NA 24 | } 25 | 26 | if (any(is.na(x)) && error_on_NA) { 27 | msg <- "NA detected in the dates" 28 | stop(msg, call. = FALSE) 29 | } 30 | 31 | if (sum(!is.na(x)) < 1) { 32 | stop("At least one (non-NA) date must be provided", call. = FALSE) 33 | } 34 | 35 | if (inherits(x, "Date")) { 36 | check_timespan(x) 37 | return(x) 38 | } 39 | 40 | if (inherits(x, "POSIXt")) { 41 | check_timespan(x) 42 | return(x) 43 | } 44 | 45 | if (is.integer(x)) { 46 | return(x) 47 | } 48 | 49 | if (is.numeric(x)) { 50 | x_ori <- x 51 | x <- as.integer(floor(x)) 52 | if (!isTRUE(note <- all.equal(x, x_ori))) { 53 | msg <- paste0( 54 | "Flooring from non-integer date caused approximations:\n", 55 | note) 56 | warning(msg, call. = FALSE) 57 | } 58 | return(x) 59 | } 60 | 61 | 62 | formats <- c("Date", "POSIXct", "integer", "numeric", "character") 63 | msg <- paste0( 64 | "Input could not be converted to date. Accepted formats are:\n", 65 | paste(formats, collapse = ", ")) 66 | stop(msg) 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /R/check_dots.R: -------------------------------------------------------------------------------- 1 | #' Check the user-fed arguments and give warnings if they are wrong. 2 | #' 3 | #' @param dots a list of user-supplied arguments 4 | #' @param args names of arguments appropriate for the function. 5 | #' 6 | #' @return dots, modified if necessary 7 | #' @noRd 8 | #' @keywords internal 9 | #' 10 | #' @examples 11 | #' dots <- c(hAy = 1, "lsdflk" = 1, "stuperman" = TRUE, iso_week = TRUE) 12 | #' args <- c("superman", "hey", "ho", "lets", "go", "standard") 13 | #' check_dots(dots, args) 14 | check_dots <- function(dots, args) { 15 | if (length(dots) == 0) { 16 | return(dots) 17 | } 18 | dnames <- names(dots) 19 | scores <- utils::adist(paste0("^", dnames), args, fixed = FALSE) < 2 20 | recognized <- rowSums(scores) > 0 21 | msg <- "" 22 | if (sum(scores) > 0) { 23 | words <- apply(scores[recognized, , drop = FALSE], 1, 24 | function(i) paste(args[i], collapse = ", ")) 25 | errs <- paste(format(dnames[recognized]), format(words), sep = " : ") 26 | errs <- paste(errs, collapse = "\n\t") 27 | msg <- sprintf("\n\nPotentially misspelled options:\n\t%s", errs) 28 | } 29 | if (sum(!recognized) > 0) { 30 | dre <- paste(dnames[!recognized & dnames != "iso_week"], collapse = ", ") 31 | msg <- if (dre != "") paste0(msg, "\n\nUnrecognised options:\n\t", dre) else msg 32 | } 33 | if ("iso_week" %in% dnames) { 34 | warning(paste("The parameter `iso_week` has been deprecated as of incidence", 35 | "version 1.3. Please use `standard` instead."), 36 | call. = FALSE 37 | ) 38 | names(dots)[dnames == "iso_week"] <- "standard" 39 | } 40 | MSG <- "Misspelled or unrecognized options were found." 41 | if (msg != "") { 42 | stop(paste(MSG, msg), call. = FALSE) 43 | } 44 | dots 45 | } 46 | -------------------------------------------------------------------------------- /R/check_groups.R: -------------------------------------------------------------------------------- 1 | #' Enforce cromulence of groups 2 | #' 3 | #' This enforces that groups is either: 4 | #' 5 | #' - NULL 6 | #' - a factor and the same length as dates 7 | #' It also treats missing groups (NA) as a separate group is needed. 8 | #' 9 | #' @param x a vector denoting groups 10 | #' @param dates a vector representing dates 11 | #' @param na_as_group a logical indicating whether or not NA should be 12 | #' considered a separate group. 13 | #' @noRd 14 | check_groups <- function(x, dates, na_as_group){ 15 | if (is.null(x)) { 16 | return(NULL) 17 | } 18 | x <- factor(x) 19 | lev <- levels(x) 20 | if (na_as_group && any(is.na(x))) { 21 | x <- as.character(x) 22 | x[is.na(x)] <- "NA" 23 | lev <- c(lev, "NA") 24 | } 25 | if (length(x) != length(dates)) { 26 | stop(sprintf( 27 | "'x' does not have the same length as dates (%d vs %d)", 28 | length(x), 29 | length(dates) 30 | ) 31 | ) 32 | } 33 | factor(x, levels = lev) 34 | } 35 | -------------------------------------------------------------------------------- /R/check_interval.R: -------------------------------------------------------------------------------- 1 | #' Check the interval between bins 2 | #' 3 | #' This enforces that an interval is: 4 | #' - strictly positive 5 | #' - integer (rounded) OR compatibile with date 6 | #' - finite 7 | #' - of length 1 8 | #' 9 | #' @param x an integer or numeric interval 10 | #' @return an integer interval 11 | #' @noRd 12 | check_interval <- function(x, standard = TRUE){ 13 | if (missing(x) || is.null(x)) { 14 | stop("Interval is missing or NULL") 15 | } 16 | if (length(x) != 1L) { 17 | stop(sprintf( 18 | "Exactly one value should be provided as interval (%d provided)", 19 | length(x))) 20 | } 21 | if (!is.finite(x)) { 22 | if (is.character(x)) { 23 | x <- valid_interval_character(x, standard) 24 | } else { 25 | stop("Interval is not finite") 26 | } 27 | } 28 | if (is.numeric(x)) { 29 | x <- as.integer(round(old <- x)) 30 | } 31 | if (x < 1L) { 32 | stop(sprintf( 33 | "Interval must be at least 1 (input: %.3f; after rounding: %d)", 34 | old, x)) 35 | } 36 | x 37 | } 38 | -------------------------------------------------------------------------------- /R/check_timespan.R: -------------------------------------------------------------------------------- 1 | check_timespan <- function(x) { 2 | max_days <- as.difftime(getOption("incidence.max.days"), units = "days") 3 | my_range <- range(x, na.rm = TRUE) 4 | if (diff(my_range) > max_days) { 5 | msg <- paste("The data has a date range of greater than %d days [%s to %s].", 6 | "Please check your data to ensure this is accurate.\n", 7 | "To remove this warning, set the `incidence.max.days` option", 8 | "to Inf:\n\n\toptions(incidence.max.days = Inf)" 9 | ) 10 | msg <- sprintf(msg, 11 | max_days, 12 | as.character(my_range[1]), 13 | as.character(my_range[2])) 14 | warning(msg, immediate. = TRUE, call. = FALSE) 15 | } 16 | invisible() 17 | } 18 | -------------------------------------------------------------------------------- /R/check_week.R: -------------------------------------------------------------------------------- 1 | #' Check for a valid week interval 2 | #' 3 | #' @param the_interval character, integer, or numeric 4 | #' 5 | #' @return a logical value indicating if any of the tests pass 6 | #' @noRd 7 | #' @keywords internal 8 | check_week <- function(the_interval) { 9 | num_week <- is.numeric(the_interval) && the_interval == 7 10 | int_week <- is.integer(the_interval) && the_interval == 7L 11 | char_week <- is.character(the_interval) && grepl("week", the_interval, ignore.case = TRUE) 12 | num_week || int_week || char_week 13 | } 14 | -------------------------------------------------------------------------------- /R/cumulate.R: -------------------------------------------------------------------------------- 1 | #' Compute cumulative 'incidence' 2 | #' 3 | #' `cumulate` is an S3 generic to compute cumulative numbers, with methods 4 | #' for different types of objects: 5 | #' 6 | #' \itemize{ 7 | #' 8 | #' \item default method is a wrapper for `cumsum` 9 | #' 10 | #' \item `incidence` objects: computes cumulative incidence over time 11 | #' 12 | #' \item `projections` objects: same, for `projections` objects, 13 | #' implemented in the similarly named package; see `?cumulate.projections` 14 | #' for more information, after loading the package 15 | #' 16 | #' } 17 | #' 18 | #' 19 | #' @author Thibaut Jombart \email{thibautjombart@@gmail.com} 20 | #' 21 | #' @seealso The [incidence()] function to generate the 'incidence' 22 | #' objects. 23 | #' 24 | #' @param x An incidence object. 25 | #' 26 | #' @export 27 | #' 28 | #' @examples 29 | #' dat <- as.integer(c(0,1,2,2,3,5,7)) 30 | #' group <- factor(c(1, 2, 3, 3, 3, 3, 1)) 31 | #' i <- incidence(dat, groups = group) 32 | #' i 33 | #' plot(i) 34 | #' 35 | #' i_cum <- cumulate(i) 36 | #' i_cum 37 | #' plot(i_cum) 38 | #' 39 | 40 | #' @rdname cumulate 41 | cumulate <- function(x) { 42 | UseMethod("cumulate", x) 43 | } 44 | 45 | 46 | 47 | 48 | #' @rdname cumulate 49 | #' @export 50 | cumulate.default <- function(x) { 51 | cumsum(x) 52 | } 53 | 54 | 55 | 56 | 57 | #' @rdname cumulate 58 | #' @export 59 | cumulate.incidence <- function(x) { 60 | if (isTRUE(x$cumulative)) { 61 | stop("x is already a cumulative incidence") 62 | } 63 | out <- x 64 | out$counts <- apply(x$counts, 2, cumsum) 65 | out$cumulative <- TRUE 66 | out 67 | } 68 | -------------------------------------------------------------------------------- /R/dim.R: -------------------------------------------------------------------------------- 1 | #' @rdname accessors 2 | #' @export 3 | #' @return 4 | #' - `dim()` the dimensions in the number of bins and number of groups 5 | dim.incidence <- function(x) { 6 | dim(x$counts) 7 | } 8 | -------------------------------------------------------------------------------- /R/estimate_peak.R: -------------------------------------------------------------------------------- 1 | #' Estimate the peak date of an incidence curve using bootstrap 2 | #' 3 | #' This function can be used to estimate the peak of an epidemic curve stored as 4 | #' `incidence`, using bootstrap. See [incidence::bootstrap] for more information 5 | #' on the resampling. 6 | #' 7 | #' @author Thibaut Jombart \email{thibautjombart@@gmail.com}, with inputs on 8 | #' caveats from Michael Höhle. 9 | #' 10 | #' @md 11 | #' 12 | #' @export 13 | #' 14 | #' @details Input dates are resampled with replacement to form bootstrapped 15 | #' datasets; the peak is reported for each, resulting in a distribution of 16 | #' peak times. When there are ties for peak incidence, only the first date is 17 | #' reported. 18 | #' 19 | #' Note that the bootstrapping approach used for estimating the peak time makes 20 | #' the following assumptions: 21 | #' 22 | #' - the total number of event is known (no uncertainty on total incidence) 23 | #' - dates with no events (zero incidence) will never be in bootstrapped datasets 24 | #' - the reporting is assumed to be constant over time, i.e. every case is 25 | #' equally likely to be reported 26 | #' 27 | #' @param x An `incidence` object. 28 | #' 29 | #' @param n The number of bootstrap datasets to be generated; defaults to 100. 30 | #' 31 | #' @param alpha The type 1 error chosen for the confidence interval; defaults to 32 | #' 0.05. 33 | #' 34 | #' @return A list containing the following items: 35 | #' 36 | #' - `observed`: the peak incidence of the original dataset 37 | #' - `estimated`: the mean peak time of the bootstrap datasets 38 | #' - `ci`: the confidence interval based on bootstrap datasets 39 | #' - `peaks`: the peak times of the bootstrap datasets 40 | #' 41 | #' @seealso [incidence::bootstrap] for the bootstrapping underlying this 42 | #' approach and [incidence::find_peak] to find the peak in a single 43 | #' `incidence` object. 44 | #' 45 | #' @examples 46 | #' 47 | #' if (require(outbreaks) && require(ggplot2)) { withAutoprint({ 48 | #' i <- incidence(fluH7N9_china_2013$date_of_onset) 49 | #' i 50 | #' plot(i) 51 | #' 52 | #' ## one simple bootstrap 53 | #' x <- bootstrap(i) 54 | #' x 55 | #' plot(x) 56 | #' 57 | #' ## find 95% CI for peak time using bootstrap 58 | #' peak_data <- estimate_peak(i) 59 | #' peak_data 60 | #' summary(peak_data$peaks) 61 | #' 62 | #' ## show confidence interval 63 | #' plot(i) + geom_vline(xintercept = peak_data$ci, col = "red", lty = 2) 64 | #' 65 | #' ## show the distribution of bootstrapped peaks 66 | #' df <- data.frame(peak = peak_data$peaks) 67 | #' plot(i) + geom_density(data = df, 68 | #' aes(x = peak, y = 10 * ..scaled..), 69 | #' alpha = .2, fill = "red", color = "red") 70 | #' 71 | #' })} 72 | #' 73 | 74 | estimate_peak <- function(x, n = 100, alpha = 0.05) { 75 | if (!inherits(x, "incidence")) { 76 | stop("x is not an incidence object") 77 | } 78 | 79 | if (ncol(x$counts) > 1L) { 80 | msg <- paste("'x' is stratified by groups", 81 | "pooling groups before finding peaks", 82 | sep = "\n") 83 | message(msg) 84 | x <- pool(x) 85 | } 86 | 87 | out <- list() 88 | 89 | ## use it to find CI for epidemic peak 90 | out$observed <- find_peak(x) 91 | 92 | ## peaks on 'n' bootstrap samples 93 | peak_boot <- replicate(n, 94 | find_peak(bootstrap(x)), 95 | simplify = FALSE) 96 | 97 | ## convert to vector without losing Date class 98 | peak_boot <- do.call(c, peak_boot) 99 | 100 | ## store relevant stats and sod off 101 | out$estimated <- mean(peak_boot) 102 | QUANTILE <- if(inherits(peak_boot, c("Date", "POSIX"))) quantile_Date else stats::quantile 103 | out$ci <- QUANTILE(peak_boot, c(alpha / 2, 1 - alpha / 2)) 104 | out$peaks <- peak_boot 105 | out 106 | } 107 | -------------------------------------------------------------------------------- /R/extract_info.R: -------------------------------------------------------------------------------- 1 | ## Non-exported function extracting info and predictions from a lm object 2 | ## - reg is a lm object 3 | ## - origin is the first date of the incidence 4 | ## - level is a confidence level, defaulting to .95 5 | 6 | extract_info <- function(reg, origin, level){ 7 | if (is.null(reg)) { 8 | return(NULL) 9 | } 10 | 11 | ## extract growth rates (r) 12 | ## here we need to keep all coefficients when there are interactions 13 | to.keep <- grep("^dates.x.*$", names(stats::coef(reg)), value = TRUE) 14 | r <- stats::coef(reg)[to.keep] 15 | use.groups <- length(r) > 1 16 | if (use.groups) { 17 | names(r) <- reg$xlevels[[1]] # names = levels if groups 18 | } else { 19 | names(r) <- NULL # no names otherwise 20 | } 21 | r.conf <- stats::confint(reg, to.keep, level) 22 | rownames(r.conf) <- names(r) 23 | if (use.groups) { 24 | r[-1] <- r[-1] + r[1] # add coefs to intercept 25 | r.conf[-1,] <- r.conf[-1,] + r.conf[1,] # add coefs to intercept 26 | } 27 | 28 | 29 | ## need to pass new data spanning all dates and groups here 30 | if (use.groups) { 31 | new.data <- expand.grid(sort(unique(reg$model$dates.x)), 32 | levels(reg$model$groups)) 33 | names(new.data) <- c("dates.x", "groups") 34 | } else { 35 | new.data <- data.frame(dates.x = sort(unique(reg$model$dates.x))) 36 | } 37 | pred <- exp(stats::predict(reg, newdata = new.data, interval = "confidence", 38 | level = level)) 39 | ## keep track of dates and groups for plotting 40 | pred <- cbind.data.frame(new.data, pred) 41 | info <- list(r = r, r.conf = r.conf, 42 | pred = pred) 43 | 44 | if (r[1] > 0 ) { # note: choice of doubling vs halving only based on 1st group 45 | info$doubling <- log(2) / r 46 | info$doubling.conf <- log(2) / r.conf 47 | o.names <- colnames(info$doubling.conf) 48 | info$doubling.conf <- info$doubling.conf[, rev(seq_along(o.names)), 49 | drop = FALSE] 50 | colnames(info$doubling.conf) <- o.names 51 | } else { 52 | info$halving <- log(0.5) / r 53 | info$halving.conf <- log(0.5) / r.conf 54 | } 55 | 56 | ## We need to store the date corresponding to 'day 0', as this will be used 57 | ## to create actual dates afterwards (as opposed to mere numbers of days). 58 | ## origin <- min(x$dates) 59 | 60 | ## Dates are reconstructed from info$pred$dates.x and origin). Note that 61 | ## this is approximate, as dates are forced to be integers. A better option 62 | ## would be to convert the dates to numbers, but ggplot2 is no longer 63 | ## consistent when mixing up Date and decimal numbers (it works only in some 64 | ## cases / geom). 65 | dates <- origin + pred$dates.x 66 | info$pred <- cbind.data.frame(dates, info$pred) 67 | out <- list(model = reg, info = info, origin = origin) 68 | class(out) <- "incidence_fit" 69 | out 70 | } 71 | -------------------------------------------------------------------------------- /R/find_peak.R: -------------------------------------------------------------------------------- 1 | #' Find the peak date of an incidence curve 2 | #' 3 | #' This function can be used to find the peak of an epidemic curve stored as an 4 | #' `incidence` object. 5 | #' 6 | #' @author Thibaut Jombart \email{thibautjombart@@gmail.com}, Zhian N. Kamvar 7 | #' \email{zkamvar@@gmail.com} 8 | #' 9 | #' @md 10 | #' 11 | #' @export 12 | #' 13 | #' @param x An `incidence` object. 14 | #' @param pool If `TRUE` (default), any groups will be pooled before finding 15 | #' a peak. If `FALSE`, separate peaks will be found for each group. 16 | #' 17 | #' @return The date of the (first) highest incidence in the data. 18 | #' 19 | #' @seealso [estimate_peak()] for bootstrap estimates of the peak time 20 | #' 21 | #' @examples 22 | #' 23 | #' if (require(outbreaks) && require(ggplot2)) { withAutoprint({ 24 | #' i <- incidence(fluH7N9_china_2013$date_of_onset) 25 | #' i 26 | #' plot(i) 27 | #' 28 | #' ## one simple bootstrap 29 | #' x <- bootstrap(i) 30 | #' x 31 | #' plot(x) 32 | #' 33 | #' ## find 95% CI for peak time using bootstrap 34 | #' find_peak(i) 35 | #' 36 | #' 37 | #' ## show confidence interval 38 | #' plot(i) + geom_vline(xintercept = find_peak(i), col = "red", lty = 2) 39 | #' 40 | #' })} 41 | #' 42 | 43 | find_peak <- function(x, pool = TRUE) { 44 | if (!inherits(x, "incidence")) { 45 | stop("x is not an incidence object") 46 | } 47 | 48 | if (ncol(x$counts) > 1L && pool) { 49 | msg <- paste("'x' is stratified by groups", 50 | "pooling groups before finding peaks", 51 | sep = "\n") 52 | message(msg) 53 | x <- pool(x) 54 | } 55 | the_max <- apply(get_counts(x), 56 | MARGIN = 2L, 57 | FUN = which.max 58 | ) 59 | 60 | out <- stats::setNames(x$dates[the_max], colnames(x$counts)) 61 | out 62 | } 63 | -------------------------------------------------------------------------------- /R/fit_optim_split.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname fit 3 | #' 4 | #' @param window The size, in days, of the time window either side of the 5 | #' split. 6 | #' 7 | #' @param plot A logical indicating whether a plot should be added to the 8 | #' output (`TRUE`, default), showing the mean R2 for various splits. 9 | #' 10 | #' @param separate_split If groups are present, should separate split dates be 11 | #' determined for each group? Defaults to `TRUE`, in which separate split dates 12 | #' and thus, separate models will be constructed for each group. When `FALSE`, 13 | #' the split date will be determined from the pooled data and modelled with the 14 | #' groups as main effects and interactions with date. 15 | #' 16 | fit_optim_split <- function(x, window = x$timespan/4, plot = TRUE, 17 | quiet = TRUE, separate_split = TRUE) { 18 | if (ncol(x$counts) > 1 && separate_split) { 19 | # Calculate split for each group separately -------------------------------- 20 | res <- vector(mode = "list", length = ncol(x$counts)) 21 | names(res) <- colnames(x$counts) 22 | for (i in names(res)) { 23 | res[[i]] <- fit_optim_split(x[, i], separate_split = FALSE, plot = FALSE) 24 | } 25 | 26 | # Rearrange data ----------------------------------------------------------- 27 | # The resulting object will have the follwing structure 28 | # $df 29 | # $plot 30 | # $group1 31 | # $group2 32 | # $split 33 | # $fit 34 | # $group1 35 | # $before 36 | # $after 37 | # $group2 38 | # $before 39 | # $after 40 | dates <- get_dates(x)[[1]] 41 | dfrows <- vapply(res, function(i) nrow(i$df), integer(1)) 42 | out <- list( 43 | df = data.frame(dates = seq(dates, by = 1, length.out = sum(dfrows)), 44 | mean.R2 = vector(mode = "numeric", length = sum(dfrows)), 45 | groups = factor(rep(names(res), dfrows), names(res)), 46 | stringsAsFactors = TRUE 47 | ), 48 | plot = ggplot2::ggplot(), 49 | split = seq(dates, by = 1, length.out = length(res)), 50 | fit = vector(mode = "list", length = length(res)) 51 | ) 52 | names(out$fit) <- names(res) 53 | names(out$plot) <- names(res) 54 | names(out$split) <- names(res) 55 | for (i in names(res)) { 56 | n <- factor(i, names(res)) 57 | out$fit[[i]] <- res[[i]]$fit 58 | out$plot[[i]] <- res[[i]]$plot 59 | out$split[[i]] <- res[[i]]$split 60 | out$fit[[i]]$after$info$pred$groups <- n 61 | out$fit[[i]]$before$info$pred$groups <- n 62 | out$df[out$df$groups == i, ]$dates <- res[[i]]$df$dates 63 | out$df[out$df$groups == i, ]$mean.R2 <- res[[i]]$df$mean.R2 64 | } 65 | if (plot) { 66 | out$plot <- ggplot2::ggplot( 67 | out$df, 68 | ggplot2::aes_string(x = "dates", y = "mean.R2", color = "groups") 69 | ) + 70 | ggplot2::geom_point() + 71 | ggplot2::geom_line() + 72 | ggplot2::geom_text(ggplot2::aes_string(label="dates"), 73 | hjust = -0.1, angle = 35 74 | ) + 75 | ggplot2::ylim(min = min(out$df$mean.R2) - 0.1, max = 1) 76 | } else { 77 | out$plot <- NULL 78 | } 79 | 80 | # Adding attributes for incidence_fit_list --------------------------------- 81 | attr(out$fit, "locations") <- c( 82 | lapply(names(res), c, "before"), 83 | lapply(names(res), c, "after") 84 | ) 85 | class(out$fit) <- "incidence_fit_list" 86 | return(out) 87 | } 88 | date.peak <- x$dates[which.max(pool(x)$counts)] 89 | try.since <- date.peak - window / 2 90 | try.until <- date.peak + window / 2 91 | to.keep <- x$dates >= try.since & x$dates <= try.until 92 | if (sum(to.keep) < 1) { 93 | stop("No date left to try after defining splits to try.") 94 | } 95 | 96 | splits.to.try <- x$dates[to.keep] 97 | need.to.try <- length(splits.to.try) > 1 98 | 99 | f <- function(split) { 100 | fits <- fit(x, split = split, quiet = quiet) 101 | mean(vapply(fits, function(e) summary(e$model)$`adj.r.squared`, double(1)), na.rm = TRUE) 102 | } 103 | 104 | results <- vapply(splits.to.try, f, double(1)) 105 | 106 | ## shape output 107 | df <- data.frame(dates = splits.to.try, mean.R2 = results, stringsAsFactors = TRUE) 108 | split <- if (need.to.try) splits.to.try[which.max(results)] else splits.to.try 109 | fit <- suppressWarnings(fit(x, split = split)) 110 | out <- list(df = df, 111 | split = split, 112 | fit = fit) 113 | 114 | if (plot) { 115 | out$plot <- ggplot2::ggplot( 116 | df, ggplot2::aes_string(x = "dates", y = "mean.R2")) + 117 | ggplot2::geom_point() + ggplot2::geom_line() + 118 | ggplot2::geom_text(ggplot2::aes_string(label="dates"), 119 | hjust=-.1, angle=35) + 120 | ggplot2::ylim(min=min(results)-.1, max=1) 121 | } 122 | 123 | out 124 | } 125 | -------------------------------------------------------------------------------- /R/get_counts.R: -------------------------------------------------------------------------------- 1 | #' Get counts from an incidence object 2 | #' 3 | #' @param x an `incidence` object. 4 | #' @param groups if there are groups, use this to specify a group or groups to 5 | #' subset. Defaults to `NULL` indicating that all groups are returned. 6 | #' 7 | #' @return a matrix of counts where each row represents a date bin 8 | #' @export 9 | #' @examples 10 | #' if (require(outbreaks)) { withAutoprint({ 11 | #' dat <- ebola_sim$linelist$date_of_onset 12 | #' gend <- ebola_sim$linelist$gender 13 | #' i <- incidence(dat, interval = "week", groups = gend) 14 | #' 15 | #' ## Use with an object and no arguments gives the counts matrix 16 | #' head(get_counts(i)) 17 | #' 18 | #' ## Specifying a position or group name will return a matrix subset to that 19 | #' ## group 20 | #' head(get_counts(i, 1L)) 21 | #' head(get_counts(i, "f")) 22 | #' 23 | #' ## Specifying multiple groups allows you to rearrange columns 24 | #' head(get_counts(i, c("m", "f"))) 25 | #' 26 | #' ## If you want a vector, you can use drop 27 | #' drop(get_counts(i, "f")) 28 | #' })} 29 | get_counts <- function(x, groups = NULL) { 30 | UseMethod("get_counts") 31 | } 32 | 33 | #' @rdname get_counts 34 | #' @export 35 | get_counts.incidence <- function(x, groups = NULL){ 36 | if (is.null(groups) || ncol(x$counts) == 1) { 37 | return(x$counts) 38 | } 39 | if (is.character(groups)) { 40 | correct_groups <- groups[groups %in% colnames(x$counts)] 41 | } 42 | if (is.numeric(groups)) { 43 | correct_groups <- groups[groups %in% seq(ncol(x$counts))] 44 | } 45 | if (!identical(correct_groups, groups)) { 46 | grps <- paste(setdiff(groups, correct_groups), collapse = ", ") 47 | msg <- sprintf("The following groups were not recognised: %s", grps) 48 | message(msg) 49 | } 50 | if (length(correct_groups) == 0) { 51 | grps <- paste(colnames(x$counts), collapse = ", ") 52 | stop(sprintf("No groups matched those present in the data: %s", grps)) 53 | } 54 | return(x$counts[, correct_groups, drop = FALSE]) 55 | } 56 | -------------------------------------------------------------------------------- /R/get_dates.R: -------------------------------------------------------------------------------- 1 | #' Retrieve dates from an incidence object 2 | #' 3 | #' @param x an [incidence] object 4 | #' @param ... Unused 5 | #' 6 | #' @return a vector of dates or numerics 7 | #' @export 8 | #' 9 | #' @examples 10 | #' 11 | #' set.seed(999) 12 | #' dat <- as.Date(Sys.Date()) + sample(-3:50, 100, replace = TRUE) 13 | #' x <- incidence(dat, interval = "month") 14 | #' get_dates(x) 15 | #' get_dates(x, position = "middle") 16 | get_dates <- function(x, ...) { 17 | UseMethod("get_dates") 18 | } 19 | 20 | #' @rdname get_dates 21 | #' @export 22 | #' @aliases get_dates.default 23 | get_dates.default <- function(x, ...) { 24 | stop(sprintf("Not implemented for class %s", 25 | paste(class(x), collapse = ", "))) 26 | } 27 | 28 | #' @param position One of "left", "center", "middle", or "right" specifying what 29 | #' side of the bin the date should be drawn from. 30 | #' @param count_days If `TRUE`, the result will be represented as the number of 31 | #' days from the first date. 32 | #' 33 | #' @rdname get_dates 34 | #' @keywords accessors 35 | #' @export 36 | #' 37 | #' @examples 38 | #' set.seed(999) 39 | #' dat <- as.Date(Sys.Date()) + sample(-3:50, 100, replace = TRUE) 40 | #' x <- incidence(dat, interval = "month") 41 | #' get_dates(x) 42 | #' get_dates(x, "center") 43 | #' get_dates(x, "right") 44 | #' 45 | #' # Return dates by number of days from the first date 46 | #' get_dates(x, count_days = TRUE) 47 | #' get_dates(incidence(-5:5), count_days = TRUE) 48 | get_dates.incidence <- function(x, position = "left", count_days = FALSE, ...) { 49 | POSITION <- match.arg(position, c("left", "center", "middle", "right")) 50 | if (!count_days && POSITION == "left") return(x$dates) 51 | # Default: left side of bins 52 | first_date <- min(x$dates) 53 | res <- x$dates - first_date 54 | if (POSITION %in% c("center", "middle", "right")) { 55 | divisor <- if (POSITION == "right") 1L else 2L 56 | res <- res + get_interval(x, integer = TRUE)/divisor 57 | } 58 | # This part is necessary to avoid the Date class rounding the result -_- 59 | res <- as.numeric(res) 60 | if (count_days) { 61 | return(res) 62 | } else { 63 | return(first_date + res) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /R/get_fit.R: -------------------------------------------------------------------------------- 1 | #' Accessors for `incidence_fit` objects 2 | #' 3 | #' @param x an `incidence_fit` or `incidence_fit_list` 4 | #' object. 5 | #' @return a list of `incidence_fit` objects. 6 | #' @export 7 | #' @examples 8 | #' 9 | #' if (require(outbreaks)) { withAutoprint({ 10 | #' 11 | #' dat <- ebola_sim$linelist$date_of_onset 12 | #' 13 | #' ## EXAMPLE WITH A SINGLE MODEL 14 | #' 15 | #' ## compute weekly incidence 16 | #' sex <- ebola_sim$linelist$gender 17 | #' i.sex <- incidence(dat, interval = 7, group = sex) 18 | #' 19 | #' ## Compute the optimal split for each group separately 20 | #' fits <- fit_optim_split(i.sex, separate_split = TRUE) 21 | #' 22 | #' ## `fits` contains an `incidence_fit_list` object 23 | #' fits$fit 24 | #' 25 | #' ## Grab the list of `incidence_fit` objects 26 | #' get_fit(fits$fit) 27 | #' 28 | #' ## Get the predictions for all groups 29 | #' get_info(fits$fit, "pred", groups = 1) 30 | #' 31 | #' ## Get the predictions, but set `groups` to "before" and "after" 32 | #' get_info(fits$fit, "pred", groups = 2) 33 | #' 34 | #' ## Get the reproduction number 35 | #' get_info(fits$fit, "r") 36 | #' 37 | #' ## Get the doubling confidence interval 38 | #' get_info(fits$fit, "doubling.conf") 39 | #' 40 | #' ## Get the halving confidence interval 41 | #' get_info(fits$fit, "halving.conf") 42 | #' })} 43 | get_fit <- function(x) { 44 | UseMethod("get_fit") 45 | } 46 | 47 | #' @rdname get_fit 48 | #' @export 49 | get_fit.incidence_fit <- function(x) { 50 | x 51 | } 52 | 53 | #' @rdname get_fit 54 | #' @export 55 | get_fit.incidence_fit_list <- function(x) { 56 | locations <- attr(x, "locations") 57 | res <- lapply(locations, function(i) x[[i]]) 58 | names(res) <- vapply(locations, paste, character(1), collapse = "_") 59 | res 60 | } 61 | -------------------------------------------------------------------------------- /R/get_info.R: -------------------------------------------------------------------------------- 1 | #' @rdname get_fit 2 | #' @param what the name of the item in the "info" element of the `incidence_fit` 3 | #' object. 4 | #' @param groups if `what = "pred"` and `x` is an `incidence_fit_list` object, 5 | #' then this indicates what part of the nesting hierarchy becomes the column 6 | #' named "groups". Defaults to `NULL`, indicating that no groups column will 7 | #' be added/modified. 8 | #' @param na.rm when `TRUE` (default), missing values will be excluded from the 9 | #' results. 10 | #' @param ... currently unused. 11 | #' @export 12 | get_info <- function(x, what = "r", ...) { 13 | UseMethod("get_info") 14 | } 15 | 16 | #' @rdname get_fit 17 | #' @export 18 | get_info.incidence_fit <- function(x, what = "r", ...) { 19 | x$info[[what]] 20 | } 21 | 22 | #' @rdname get_fit 23 | #' @export 24 | get_info.incidence_fit_list <- function(x, what = "r", groups = NULL, na.rm = TRUE, ...) { 25 | locations <- attr(x, "locations") 26 | n <- length(locations) 27 | if (what == "pred") { 28 | fits <- get_fit(x) 29 | for (i in names(fits)) { 30 | fits[[i]] <- fits[[i]]$info$pred 31 | fits[[i]]$location <- i 32 | if (!is.null(groups)) { 33 | tmp <- strsplit(i, "_")[[1]][[groups]] 34 | fits[[i]]$groups <- factor(tmp, tmp) 35 | } 36 | } 37 | res <- do.call("rbind", fits) 38 | return(res) 39 | } 40 | is_matrix <- grepl("conf", what) 41 | the_names <- vapply(locations, paste, character(1), collapse = "_") 42 | need_col_names <- TRUE 43 | if (is_matrix) { 44 | res <- matrix(0.0, nrow = n, ncol = 2L) 45 | } else { 46 | res <- numeric(n) 47 | } 48 | for (i in seq_len(n)) { 49 | tmp <- x[[locations[[i]]]]$info[[what]] 50 | tmp <- if (is.null(tmp)) NA_real_ else tmp 51 | if (is_matrix) { 52 | if (need_col_names && all(!is.na(tmp))) { 53 | colnames(res) <- colnames(tmp) 54 | need_col_names <- FALSE 55 | } 56 | res[i, ] <- tmp 57 | } else { 58 | res[[i]] <- tmp 59 | } 60 | } 61 | if (is_matrix) { 62 | rownames(res) <- the_names 63 | } else { 64 | names(res) <- the_names 65 | } 66 | if (na.rm) { 67 | nonas <- stats::complete.cases(res) 68 | res <- if (is_matrix) res[nonas, , drop = FALSE] else res[nonas] 69 | } 70 | res 71 | } 72 | -------------------------------------------------------------------------------- /R/get_interval.R: -------------------------------------------------------------------------------- 1 | #' Access various elements of an incidence object 2 | #' 3 | #' @param x an [incidence] object. 4 | #' @param ... Unused 5 | #' 6 | #' @return 7 | #' - `get_interval()` if `integer = TRUE`: an integer vector, otherwise: the 8 | #' value stored in `x$interval` 9 | #' @export 10 | #' @keywords accessors 11 | #' 12 | #' @rdname accessors 13 | #' @aliases get_interval 14 | #' @seealso 15 | #' - [get_counts()] to access the matrix of counts 16 | #' - [get_dates()] to access the dates on the right, left, and center of the 17 | #' interval. 18 | #' - [group_names()] to access and possibly re-name the groups 19 | #' @examples 20 | #' 21 | #' set.seed(999) 22 | #' dat <- as.Date(Sys.Date()) + sample(-3:50, 100, replace = TRUE) 23 | #' x <- incidence(dat, interval = "month") 24 | #' 25 | #' # the value stored in the interval element 26 | #' get_interval(x) 27 | #' 28 | #' # the numeric value of the interval in days 29 | #' get_interval(x, integer = FALSE) 30 | #' 31 | #' # the number of observations in the object 32 | #' get_n(x) 33 | #' 34 | #' # the length of time represented 35 | #' get_timespan(x) 36 | #' 37 | #' # the number of groups 38 | #' ncol(x) 39 | #' 40 | #' # the number of bins (intervals) 41 | #' nrow(x) 42 | get_interval <- function(x, ...) { 43 | UseMethod("get_interval") 44 | } 45 | 46 | #' @export 47 | #' @rdname accessors 48 | #' @aliases get_interval.default 49 | get_interval.default <- function(x, ...) { 50 | stop(sprintf("Not implemented for class %s", 51 | paste(class(x), collapse = ", "))) 52 | } 53 | 54 | #' @param integer When `TRUE` (default), the interval will be converted to an 55 | #' integer vector if it is stored as a character in the incidence object. 56 | #' @export 57 | #' @rdname accessors 58 | #' @aliases get_interval.incidence 59 | get_interval.incidence <- function(x, integer = TRUE, ...) { 60 | if (!integer || is.numeric(x$interval)) { 61 | return(x$interval) 62 | } 63 | if (is.character(x$interval)) { 64 | res <- get_interval_type(x$interval) 65 | n <- get_interval_number(x$interval) 66 | res <- switch(res, 67 | day = 1L * n, 68 | week = 7L * n, 69 | month = get_days_in_month(x$dates, n), 70 | quarter = get_days_in_quarter(x$dates, n), 71 | year = get_days_in_year(x$dates, n) 72 | ) 73 | return(res) 74 | } else { 75 | stop(sprintf("I don't know how to convert a %s to an integer", 76 | paste(class(x$interval), collapse = ", "))) 77 | } 78 | } 79 | 80 | get_interval_type <- function(x) { 81 | res <- NULL 82 | res <- if (grepl("day", x, ignore.case = TRUE)) "day" else res 83 | res <- if (grepl("week", x, ignore.case = TRUE)) "week" else res 84 | res <- if (grepl("month", x, ignore.case = TRUE)) "month" else res 85 | res <- if (grepl("quarter", x, ignore.case = TRUE)) "quarter" else res 86 | res <- if (grepl("year", x, ignore.case = TRUE)) "year" else res 87 | res 88 | } 89 | 90 | get_interval_number <- function(x) { 91 | 92 | if (!grepl("^\\d", x)) return(1L) 93 | as.integer(gsub("^(\\d*).+$", "\\1", x)) 94 | 95 | } 96 | 97 | 98 | get_days_in_month <- function(dates, m = 1L) { 99 | dates <- floor_month(dates) 100 | res <- vapply(strsplit(format(dates), "-"), 101 | add_months, 102 | character(1), 103 | months = m) 104 | as.integer(as.Date(res) - dates) 105 | } 106 | 107 | get_days_in_quarter <- function(dates, m = 1L) { 108 | dates <- floor_month(dates) 109 | res <- vapply(strsplit(format(dates), "-"), 110 | FUN = add_months, 111 | FUN.VALUE = character(1), 112 | months = 3L * m) 113 | as.integer(as.Date(res) - dates) 114 | } 115 | 116 | get_days_in_year <- function(dates, m = 1L) { 117 | dates <- floor_month(dates) 118 | res <- vapply(strsplit(format(dates), "-"), 119 | FUN = add_months, 120 | FUN.VALUE = character(1), 121 | months = 12L * m) 122 | as.integer(as.Date(res) - dates) 123 | } 124 | 125 | floor_month <- function(x) { 126 | x - as.integer(format(x, "%d")) + 1L 127 | } 128 | 129 | add_months <- function(x, months = 1L) { 130 | i <- as.integer(x[2]) + months 131 | if (i > 12L) { 132 | x[1] <- as.character(as.integer(x[1]) + 1L) 133 | i <- i - 12L 134 | } 135 | x[2] <- sprintf("%02d", i) 136 | paste(x, collapse = "-") 137 | } 138 | -------------------------------------------------------------------------------- /R/get_n.R: -------------------------------------------------------------------------------- 1 | #' @return 2 | #' - `get_n()` The total number of cases stored in the object 3 | #' @export 4 | #' @rdname accessors 5 | #' @aliases get_n 6 | get_n <- function(x) { 7 | UseMethod("get_n") 8 | } 9 | 10 | #' @export 11 | #' @rdname accessors 12 | #' @aliases get_n.default 13 | get_n.default <- function(x) { 14 | stop(sprintf("Not implemented for class %s", 15 | paste(class(x), collapse = ", "))) 16 | } 17 | 18 | #' @export 19 | #' @rdname accessors 20 | #' @aliases get_n.incidence 21 | get_n.incidence <- function(x) { 22 | x$n 23 | } 24 | -------------------------------------------------------------------------------- /R/get_timespan.R: -------------------------------------------------------------------------------- 1 | #' @return 2 | #' - `get_timespan()`: an `integer` denoting the timespan represented by the 3 | #' incidence object. 4 | #' @export 5 | #' @rdname accessors 6 | #' @aliases get_timespan 7 | get_timespan <- function(x) { 8 | UseMethod("get_timespan") 9 | } 10 | 11 | #' @export 12 | #' @rdname accessors 13 | #' @aliases get_timespan.default 14 | get_timespan.default <- function(x) { 15 | stop(sprintf("Not implemented for class %s", 16 | paste(class(x), collapse = ", "))) 17 | } 18 | 19 | #' @export 20 | #' @rdname accessors 21 | #' @aliases get_timespan.incidence 22 | get_timespan.incidence <- function(x) { 23 | x$timespan 24 | } 25 | -------------------------------------------------------------------------------- /R/get_week.R: -------------------------------------------------------------------------------- 1 | #' translate user input to the start date of the week 2 | #' 3 | #' @param a weekday specification: ISOweek, MMWRweek, EPIweek, Mon-week, Tue-week, etc. 4 | #' 5 | #' @return the corresponding weekday 6 | #' @keywords internal 7 | #' @noRd 8 | #' @examples 9 | #' get_week_start("ISOweek") 10 | #' get_week_start("MMWRweek") 11 | #' get_week_start("EPIweek") 12 | #' 13 | #' # weeks that start on saturday 14 | #' 15 | #' get_week_start("Sat-week") 16 | #' get_week_start("week: Saturday") 17 | #' get_week_start("2 weeks: Saturday") 18 | #' get_week_start("epiweek: Saturday") 19 | get_week_start <- function(weekday) { 20 | wkdy <- gsub("weeks?", "", tolower(weekday)) 21 | wkdy <- gsub('[[:punct:][:blank:][:digit:]]*', "", wkdy) 22 | wkdy <- if (wkdy == "") "monday" else wkdy # the input was "weeks" 23 | res <- switch(wkdy, 24 | "mmwr" = "sunday", # MMWR == CDC epiweek 25 | "epi" = "sunday", # CDC epiweek 26 | "iso" = "monday", # ISOweek == WHO epiweek 27 | wkdy # all others 28 | ) 29 | gsub("epi", "", res) # if they specify something like "epiweek:saturday" 30 | } 31 | 32 | #' Translate a custom interval to a valid interval 33 | #' 34 | #' @param the_interval an interval like 2 epiweeks or 1 ISOweek 35 | #' @return an interval compatible with `seq.Date()` 36 | #' @keywords internal 37 | #' @noRd 38 | #' @examples 39 | #' get_week_duration("2 weeks (wednesday)") # 2 weeks 40 | #' get_week_duration("2 epiweeks") # 2 weeks 41 | get_week_duration <- function(the_interval) { 42 | 43 | if (the_interval == 7) return(the_interval) 44 | res <- gsub('^(\\d*) ?.*(weeks?).*$', '\\1 \\2', tolower(the_interval), perl = TRUE) 45 | trimws(res) 46 | 47 | } 48 | 49 | get_type_of_week <- function(x) { 50 | 51 | switch(as.character(attr(x$weeks, "week_start")), 52 | "1" = "ISO", 53 | "7" = "MMWR", 54 | sprintf("(%s)", weekdays(x$dates[1])) 55 | ) 56 | } 57 | -------------------------------------------------------------------------------- /R/group_names.R: -------------------------------------------------------------------------------- 1 | #' extract and set group names 2 | #' @param x an [incidence()] object. 3 | #' @param value character vector used to rename groups 4 | #' @return an integer indicating the number of groups present in the incidence 5 | #' object. 6 | #' @details This accessor will return a 7 | #' @export 8 | #' @examples 9 | #' i <- incidence(dates = sample(10, 100, replace = TRUE), 10 | #' interval = 1L, 11 | #' groups = sample(letters[1:3], 100, replace = TRUE)) 12 | #' i 13 | #' group_names(i) 14 | #' 15 | #' # change the names of the groups 16 | #' group_names(i) <- c("Group 1", "Group 2", "Group 3") 17 | #' i 18 | #' 19 | #' # example if there are mistakes in the original data, e.g. 20 | #' # something is misspelled 21 | #' set.seed(50) 22 | #' grps <- sample(c("child", "adult", "adlut"), 100, replace = TRUE, prob = c(0.45, 0.45, 0.05)) 23 | #' i <- incidence(dates = sample(10, 100, replace = TRUE), 24 | #' interval = 1L, 25 | #' groups = grps) 26 | #' colSums(get_counts(i)) 27 | #' 28 | #' # If you change the name of the mis-spelled group, it will be merged with the 29 | #' # correctly-spelled group 30 | #' gname <- group_names(i) 31 | #' gname[gname == "adlut"] <- "adult" 32 | #' # without side-effects 33 | #' print(ii <- group_names(i, gname)) 34 | #' colSums(get_counts(i)) # original still has three groups 35 | #' colSums(get_counts(ii)) 36 | #' # with side-effects 37 | #' group_names(i) <- gname 38 | #' colSums(get_counts(i)) 39 | group_names <- function(x, value) { 40 | UseMethod("group_names", x) 41 | } 42 | 43 | #' @export 44 | #' @rdname group_names 45 | "group_names<-" <- function(x, value) { 46 | UseMethod("group_names<-", x) 47 | } 48 | 49 | #' @rdname group_names 50 | #' @export 51 | #' @aliases group_names.default 52 | group_names.default <- function(x, value) { 53 | stop(sprintf("Not implemented for class %s", 54 | paste(class(x), collapse = ", "))) 55 | } 56 | #' @rdname group_names 57 | #' @export 58 | #' @aliases `group_names<-`.default 59 | "group_names<-.default" <- function(x, value) { 60 | stop(sprintf("Not implemented for class %s", 61 | paste(class(x), collapse = ", "))) 62 | } 63 | 64 | #' @rdname group_names 65 | #' @export 66 | #' @keywords accessors 67 | group_names.incidence <- function(x, value = NULL){ 68 | if (is.null(value)) { 69 | colnames(x$counts) 70 | } else { 71 | `group_names<-`(x, value) 72 | } 73 | } 74 | 75 | #' @rdname group_names 76 | #' @export 77 | "group_names<-.incidence" <- function(x, value) { 78 | if (length(value) != ncol(x)) { 79 | stop("value must be the same length as the number of groups.") 80 | } 81 | if (anyNA(value <- as.character(value))) { 82 | stop("value must be able to be coerced to a character vector") 83 | } 84 | uval <- unique(value) 85 | if (identical(uval, value)) { 86 | colnames(x$counts) <- value 87 | } else { 88 | the_counts <- x$counts 89 | out <- matrix(integer(nrow(the_counts)*length(uval)), 90 | nrow = nrow(the_counts), 91 | ncol = length(uval) 92 | ) 93 | colnames(out) <- uval 94 | for (i in uval) { 95 | out[, i] <- rowSums(the_counts[, value == i, drop = FALSE]) 96 | } 97 | x$counts <- out 98 | } 99 | x 100 | } 101 | -------------------------------------------------------------------------------- /R/internals.R: -------------------------------------------------------------------------------- 1 | 2 | ## These functions are meant for internal use only, and are not 3 | ## exported. Functions which check content return it, after potential trivial 4 | ## conversions. 5 | 6 | #' Count dates within bins 7 | #' 8 | #' @param dates a vector of dates, integers, or numerics 9 | #' @param breaks an ordered vector of dates or integers 10 | #' 11 | #' @author Thibaut Jombart 12 | #' @return an integer vector of the number of incidences per date 13 | #' @noRd 14 | #' 15 | count.dates <- function(dates, breaks){ 16 | counts <- table(cut(as.integer(dates), breaks = c(breaks, Inf), right = FALSE)) 17 | as.integer(counts) 18 | } 19 | 20 | 21 | ## Implement isTRUE and isFALSE to avoid dep on R 3.5.0 22 | 23 | isFALSE <- function(x) { 24 | is.logical(x) && length(x) == 1L && !is.na(x) && !x 25 | } 26 | 27 | isTRUE <- function(x) { 28 | is.logical(x) && length(x) == 1L && !is.na(x) && x 29 | } 30 | 31 | ## A fix for the nonesensical behaviour of `sample` when first argument is of 32 | ## length 1. 33 | 34 | sample_ <- function(x, ...) { 35 | x[sample.int(length(x), ...)] 36 | } 37 | 38 | ## quantiles for Date objects 39 | 40 | quantile_Date <- function(x, ...) { 41 | if (!inherits(x, "Date")) { 42 | stop("'x' is not a 'Date' object") 43 | } 44 | 45 | first_date <- min(x, na.rm = TRUE) 46 | x_num <- as.numeric(x - min(x)) 47 | out <- stats::quantile(x_num, ...) 48 | first_date + out 49 | } 50 | -------------------------------------------------------------------------------- /R/make_breaks.R: -------------------------------------------------------------------------------- 1 | #' Make breaks with dates 2 | #' 3 | #' Because Date objects have a specific `seq` method, it's possible 4 | #' to make breaks with both integers and date objects. This function 5 | #' will check to make sure that the interval is valid. 6 | #' 7 | #' @param date an integer, numeric, or Date vector 8 | #' @param the_interval an integer or character 9 | #' @param last_date an integer, numeric, or Date 10 | #' @param first_date an integer, numeric, or Date 11 | #' @param dots a named list of options 12 | #' 13 | #' @author Zhian Kamvar 14 | #' @return a vector of integers or Dates 15 | #' @noRd 16 | #' @examples 17 | #' 18 | #' set.seed(999) 19 | #' d <- sample(10, replace = TRUE) 20 | #' make_breaks_easier(d, 2L) 21 | make_breaks_easier <- function(dates, the_interval, first_date = NULL, 22 | last_date = NULL, dots = 1L) { 23 | 24 | the_interval <- valid_interval_character(the_interval) 25 | date_interval <- is.character(the_interval) && is_date_interval(the_interval) 26 | is_month <- grepl("month", the_interval, ignore.case = TRUE) 27 | is_quarter <- grepl("quarter", the_interval, ignore.case = TRUE) 28 | is_year <- grepl("year", the_interval, ignore.case = TRUE) 29 | uneven_interval <- date_interval && (is_month || is_quarter || is_year) 30 | 31 | # getting information about the date 32 | fd <- as.character(first_date) 33 | the_day <- as.integer(substr(fd, 9, 10)) 34 | the_month <- as.integer(substr(fd, 6, 7)) 35 | 36 | if ("standard" %in% names(dots)) { 37 | if (isTRUE(dots$standard)) { 38 | is_a_week <- !uneven_interval && check_week(the_interval) 39 | if (is_a_week) { 40 | week_start <- get_week_start(the_interval) 41 | the_interval <- get_week_duration(the_interval) 42 | # This returns something like 2018-W29 43 | first_isoweek <- aweek::date2week(first_date, week_start, floor_day = TRUE) 44 | # here we convert it back to a date 45 | first_date <- aweek::week2date(first_isoweek) 46 | } 47 | if (uneven_interval) { 48 | # Replace the day with the first day of the month 49 | substr(fd, 9, 10) <- "01" 50 | if (is_quarter) { 51 | # Replace the month with the first month of the quarter 52 | m <- (as.integer(substr(fd, 6, 7)) - 1L) %/% 3L 53 | substr(fd, 6, 7) <- sprintf("%02d", (m * 3) + 1L) 54 | } 55 | if (is_year) { 56 | # Replace the month with the first month of the year 57 | substr(fd, 6, 7) <- "01" 58 | } 59 | # re-cast the date 60 | first_date <- as.Date(fd) 61 | } 62 | } else { 63 | if (uneven_interval && !is_year && the_day > 28) { 64 | # The first date represents a day that doesn't occur in all months 65 | msg <- paste("The first_date (%s) represents a day that does not", 66 | "occur in all months. Because of this, bins may not", 67 | "conform to monthly boundaries. To prevent this", 68 | "behavior, plese specify a different first_date that", 69 | "represents a day within [1, 28]." 70 | ) 71 | msg <- paste(strwrap(msg), collapse = "\n") 72 | warning(sprintf(msg, fd), call. = FALSE) 73 | } 74 | if (is_year && the_month == 2 && the_day == 29) { 75 | # The first date occurs on a leap day. 76 | msg <- paste("The first_date (%s) represents a day that does not", 77 | "occur in all years. Because of this, bins may not", 78 | "fall on the same day. To prevent this behavior, please", 79 | "specify a first_date that represents a different day." 80 | ) 81 | msg <- paste(strwrap(msg), collapse = "\n") 82 | warning(sprintf(msg, fd), call. = FALSE) 83 | } 84 | } 85 | } 86 | seq(first_date, last_date, by = the_interval) 87 | } 88 | -------------------------------------------------------------------------------- /R/make_incidence.R: -------------------------------------------------------------------------------- 1 | ##' Default internal constructor for incidence objects. 2 | ##' 3 | ##' 4 | ##' 5 | ##' @param dates A vector of dates, which can be provided as objects of the 6 | ##' class: integer, numeric, Date, POSIXct. Note that decimal numbers will be 7 | ##' floored with a warning. 8 | ##' 9 | ##' @param interval An integer indicating the (fixed) size of the time interval 10 | ##' used for computing the incidence; defaults to 1 day. 11 | ##' 12 | ##' @param groups An optional factor defining groups of observations for which 13 | ##' incidence should be computed separately. 14 | ##' 15 | ##' @param na_as_group A logical value indicating if missing group (NA) should be 16 | ##' treated as a separate group. 17 | ##' 18 | ##' @param last_date The last date to be included in the produced epicurve. If 19 | ##' `NULL` (default), the last date will be the most recent provided in 20 | ##' `dates`. 21 | ##' 22 | ##' @param ... Additional arguments passed to other methods (none are used). 23 | ##' 24 | ##' @author Zhian Kamvar 25 | ##' @return an incidence object 26 | ##' @noRd 27 | make_incidence <- function(dates, interval = 1L, groups = NULL, 28 | na_as_group = TRUE, first_date = NULL, 29 | last_date = NULL, ...) { 30 | dots <- list(...) 31 | 32 | ## make sure input can be used 33 | dates <- check_dates(dates) 34 | interval <- check_interval(interval, if (is.null(dots$standard)) TRUE else dots$standard) 35 | groups <- check_groups(groups, dates, na_as_group) 36 | 37 | ## Check the interval and arrange the breaks 38 | first_date <- check_boundaries(dates, first_date, "first") 39 | last_date <- check_boundaries(dates, last_date, "last") 40 | breaks <- make_breaks_easier(dates, 41 | the_interval = interval, 42 | first_date = first_date, 43 | last_date = last_date, 44 | dots = dots 45 | ) 46 | if (!is.numeric(interval) && grepl("week", interval)) { 47 | interval <- get_week_duration(interval) 48 | } 49 | 50 | ## Trim the dates and groups as necessary 51 | trimmed <- trim_observations(dates, first_date, last_date) 52 | dates <- dates[trimmed] 53 | groups <- groups[trimmed] 54 | 55 | ## compute counts within bins defined by the breaks 56 | if (!is.null(groups)) { 57 | counts <- tapply(dates, groups, count.dates, breaks) 58 | counts <- matrix(as.integer(unlist(counts, use.names = FALSE)), 59 | ncol = length(levels(groups))) 60 | colnames(counts) <- levels(groups) 61 | } else { 62 | counts <- count.dates(dates, breaks) 63 | counts <- matrix(as.integer(counts), ncol = 1L) 64 | } 65 | 66 | out <- list(dates = breaks, # left side of bins (incl left, excl right) 67 | counts = counts, # computed incidence, 1 col / group 68 | timespan = diff(range(breaks, na.rm = TRUE)) + 1, 69 | interval = interval, # fixed bin size 70 | n = sum(counts), # total number of cases 71 | cumulative = FALSE) # not cumulative at creation 72 | class(out) <- "incidence" 73 | out 74 | } 75 | -------------------------------------------------------------------------------- /R/palettes.R: -------------------------------------------------------------------------------- 1 | #' Color palettes used in incidence 2 | #' 3 | #' These functions are color palettes used in incidence. 4 | #' 5 | #' @author Thibaut Jombart \email{thibautjombart@@gmail.com} 6 | #' 7 | #' @param n a number of colors 8 | #' 9 | #' @rdname palettes 10 | #' @aliases palettes incidence_pal1 incidence_pal1_light incidence_pal1_dark 11 | #' 12 | #' @export 13 | #' @importFrom grDevices colorRampPalette 14 | #' 15 | #' @examples 16 | #' 17 | #' plot(1:4, cex=8, pch=20, col = incidence_pal1(4), 18 | #' main = "palette: incidence_pal1") 19 | #' plot(1:100, cex=8, pch=20, col = incidence_pal1(100), 20 | #' main ="palette: incidence_pal1") 21 | #' plot(1:100, cex=8, pch=20, col = incidence_pal1_light(100), 22 | #' main="palette: incidence_pal1_light") 23 | #' plot(1:100, cex=8, pch=20, col = incidence_pal1_dark(100), 24 | #' main="palette: incidence_pal1_dark") 25 | #' 26 | incidence_pal1 <- function(n){ 27 | if(!is.numeric(n)) stop("n is not a number") 28 | colors <- c("#aa3939", "#4a6a8a", "#d4aa6a","#499371") 29 | if (n < 4) return(colors[1:n]) 30 | return(colorRampPalette(colors)(n)) 31 | } 32 | 33 | 34 | 35 | 36 | 37 | #' @export 38 | #' @rdname palettes 39 | 40 | incidence_pal1_light <- function(n){ 41 | if(!is.numeric(n)) stop("n is not a number") 42 | colors <- c("#d46a6a", "#738ca6", "#ffddaa","#76b096") 43 | if (n < 4) return(colors[1:n]) 44 | return(colorRampPalette(colors)(n)) 45 | } 46 | 47 | 48 | 49 | 50 | 51 | 52 | #' @export 53 | #' @rdname palettes 54 | 55 | incidence_pal1_dark <- function(n){ 56 | if(!is.numeric(n)) stop("n is not a number") 57 | colors <- c("#801515", "#2b4c6f", "#aa7d39","#277552") 58 | if (n < 4) return(colors[1:n]) 59 | return(colorRampPalette(colors)(n)) 60 | } 61 | -------------------------------------------------------------------------------- /R/pool.R: -------------------------------------------------------------------------------- 1 | ##' Pool 'incidence' across groups 2 | ##' 3 | ##' This function pools incidence across all groups of an `incidence` 4 | ##' object. The resulting [incidence()] object will contains counts 5 | ##' summed over all groups present in the input. 6 | ##' 7 | ##' @author Thibaut Jombart \email{thibautjombart@@gmail.com} 8 | ##' 9 | ##' @seealso The [incidence()] function to generate the 'incidence' 10 | ##' objects. 11 | ##' 12 | ##' @inheritParams incidence 13 | ##' 14 | ##' @export 15 | ##' 16 | ##' @examples 17 | ##' dat <- as.integer(c(0,1,2,2,3,5,7)) 18 | ##' group <- factor(c(1, 2, 3, 3, 3, 3, 1)) 19 | ##' i <- incidence(dat, groups = group) 20 | ##' i 21 | ##' i$counts 22 | ##' 23 | ##' ## pool all groups 24 | ##' pool(i) 25 | ##' pool(i)$counts 26 | ##' 27 | ##' ## pool only groups 1 and 3 28 | ##' pool(i[,c(1,3)]) 29 | ##' pool(i[,c(1,3)])$counts 30 | ##' 31 | 32 | pool <- function(x){ 33 | if (!inherits(x, "incidence")) { 34 | stop(sprintf( 35 | "x should be an 'incidence' object (its class is: %s)", 36 | class(x))) 37 | } 38 | if (ncol(x$counts) == 1) return(x) 39 | x$counts <- matrix(apply(x$counts, 1 , sum), ncol = 1) 40 | x 41 | } 42 | -------------------------------------------------------------------------------- /R/print.R: -------------------------------------------------------------------------------- 1 | #' @export 2 | #' @rdname incidence 3 | #' @param x An 'incidence' object. 4 | print.incidence <- function(x, ...) { 5 | cat("\n") 6 | cat(sprintf("[%d cases from days %s to %s]\n", 7 | sum(x$n), min(x$dates), max(x$dates))) 8 | if ("weeks" %in% names(x)) { 9 | type_of_week <- get_type_of_week(x) 10 | cat(sprintf("[%d cases from %s weeks %s to %s]\n", 11 | sum(x$n), type_of_week, head(x$weeks, 1), tail(x$weeks, 1))) 12 | } 13 | if (!is.null(group_names(x))) { 14 | groups.txt <- paste(group_names(x), collapse = ", ") 15 | cat(sprintf("[%d groups: %s]\n", ncol(x), groups.txt)) 16 | } 17 | cat(sprintf("\n$counts: matrix with %d rows and %d columns\n", 18 | nrow(x$counts), ncol(x$counts))) 19 | cat(sprintf("$n: %d cases in total\n", x$n)) 20 | cat(sprintf("$dates: %d dates marking the left-side of bins\n", 21 | length(x$dates))) 22 | if (is.integer(x$interval)) { 23 | cat(sprintf("$interval: %d %s\n", 24 | x$interval, ifelse(x$interval < 2, "day", "days"))) 25 | } else if (grepl("\\d", x$interval)) { 26 | cat(sprintf("$interval: %s\n", x$interval)) 27 | } else { 28 | cat(sprintf("$interval: 1 %s\n", x$interval)) 29 | } 30 | cat(sprintf("$timespan: %d days\n", x$timespan)) 31 | if (!is.null(x$cumulative)) { 32 | cat(sprintf("$cumulative: %s\n", x$cumulative)) 33 | } 34 | cat("\n") 35 | invisible(x) 36 | } 37 | 38 | 39 | 40 | #' @export 41 | #' @rdname fit 42 | #' @param ... currently unused. 43 | print.incidence_fit <- function(x, ...) { 44 | 45 | cat("\n\n") 46 | cat("$model: regression of log-incidence over time\n\n") 47 | 48 | cat("$info: list containing the following items:\n") 49 | cat(" $r (daily growth rate):\n") 50 | print(x$info$r) 51 | cat("\n $r.conf (confidence interval):\n") 52 | print(x$info$r.conf) 53 | if (x$info$r[1] > 0) { 54 | cat("\n $doubling (doubling time in days):\n") 55 | print(x$info$doubling) 56 | cat("\n $doubling.conf (confidence interval):\n") 57 | print(x$info$doubling.conf) 58 | } else { 59 | cat("\n $halving (halving time in days):\n") 60 | print(x$info$halving) 61 | cat("\n $halving.conf (confidence interval):\n") 62 | print(x$info$halving.conf) 63 | } 64 | 65 | cat(sprintf( 66 | "\n $pred: data.frame of incidence predictions (%d rows, %d columns)\n", 67 | nrow(x$info$pred), ncol(x$info$pred))) 68 | invisible(x) 69 | } 70 | 71 | #' @export 72 | #' @rdname fit 73 | print.incidence_fit_list <- function(x, ...) { 74 | cat("\n\n") 75 | cat("attr(x, 'locations'): list of vectors with the locations of each incidence_fit object\n\n") 76 | locations <- attr(x, "locations") 77 | cat(sprintf("'%s'", vapply(locations, paste, character(1), collapse = "', '")), sep = "\n") 78 | cat("\n") 79 | cat("$model: regression of log-incidence over time\n\n") 80 | 81 | cat("$info: list containing the following items:\n") 82 | cat(" $r (daily growth rate):\n") 83 | print(get_info(x, "r")) 84 | cat("\n $r.conf (confidence interval):\n") 85 | print(get_info(x, "r.conf")) 86 | if (any(get_info(x, "r") > 0)) { 87 | cat("\n $doubling (doubling time in days):\n") 88 | print(get_info(x, "doubling", na.rm = TRUE)) 89 | cat("\n $doubling.conf (confidence interval):\n") 90 | print(get_info(x, "doubling.conf", na.rm = TRUE)) 91 | } 92 | if (any(get_info(x, "r") < 0)) { 93 | cat("\n $halving (halving time in days):\n") 94 | print(get_info(x, "halving", na.rm = TRUE)) 95 | cat("\n $halving.conf (confidence interval):\n") 96 | print(get_info(x, "halving.conf", na.rm = TRUE)) 97 | } 98 | preds <- get_info(x, "pred") 99 | cat(sprintf( 100 | "\n $pred: data.frame of incidence predictions (%d rows, %d columns)\n", 101 | nrow(preds), ncol(preds))) 102 | invisible(x) 103 | } 104 | 105 | -------------------------------------------------------------------------------- /R/scale_x_incidence.R: -------------------------------------------------------------------------------- 1 | #' @param ... arguments passed to [ggplot2::scale_x_date()], 2 | #' [ggplot2::scale_x_datetime()], or [ggplot2::scale_x_continuous()], depending 3 | #' on how the `$date` element is stored in the incidence object. 4 | #' @export 5 | #' @rdname plot.incidence 6 | scale_x_incidence <- function(x, n_breaks = 6, labels_week = TRUE, ...) { 7 | 8 | breaks <- make_breaks(x, n_breaks, labels_week) 9 | 10 | 11 | if (inherits(x$dates, "Date")) { 12 | 13 | out <- ggplot2::scale_x_date(breaks = breaks$breaks, 14 | labels = breaks$labels, 15 | ...) 16 | } else if (inherits(x$dates, "POSIXt")) { 17 | breaks$breaks <- as.POSIXct(as.POSIXlt(breaks$breaks)) 18 | out <- ggplot2::scale_x_datetime(breaks = breaks$breaks, 19 | labels = breaks$labels, 20 | timezone = "UTC", 21 | ... 22 | ) 23 | } else { 24 | out <- ggplot2::scale_x_continuous(breaks = breaks$breaks, ...) 25 | } 26 | out 27 | } 28 | 29 | #' @export 30 | #' @rdname plot.incidence 31 | make_breaks <- function(x, n_breaks = 6L, labels_week = TRUE) { 32 | stopifnot(inherits(x, "incidence"), is.logical(labels_week), is.numeric(n_breaks)) 33 | ## Defining breaks for the x axis -------------------------------------------- 34 | ## 35 | ## The x axis can either be integers, Dates, or POSIXt scales. Moreover, 36 | ## we need to make sure that the breaks align with the left-hand side of the 37 | ## bins (for now). This section first defines what the breaks should be 38 | ## and then treats them according to whether or not the interval was specified 39 | ## as a character. 40 | if (n_breaks == nrow(x)) { 41 | # The number of breaks are equal to the number of dates... don't worry about 42 | # adjusting 43 | breaks <- x$dates 44 | } else { 45 | # adjust breaks to force first date to beginning. 46 | breaks <- pretty(x$dates, n_breaks) 47 | breaks <- breaks + (x$dates[1] - breaks[1]) 48 | } 49 | ## Defining the x axis scale ------------------------------------------------- 50 | ## 51 | ## Choosing between scale_x_date, scale_x_datetime, and scale_x_continuous 52 | 53 | # labels should be dates or numbers 54 | if (is.character(x$interval)) { 55 | # The interval is a character like "2 weeks" and we have to figure out how 56 | # to split these manually 57 | has_number <- grepl("\\d", x$interval) 58 | tims <- ceiling(x$timespan/(n_breaks*mean(get_interval(x, integer = TRUE)))) 59 | if (has_number) { 60 | ni <- as.integer(strsplit(x$interval, " ", fixed = TRUE)[[1L]][1L]) 61 | # the replacement should be a multiple of the number 62 | replacement <- if (tims <= ni) ni else ceiling(tims/ni)*ni 63 | db <- gsub("\\d+", replacement, x$interval) 64 | } else if (x$interval == "quarter") { 65 | db <- paste(tims * 3, "months") 66 | } else { 67 | db <- sprintf("%d %s", tims, x$interval) 68 | } 69 | breaks <- seq(x$dates[1], x$dates[nrow(x)], by = db) 70 | } 71 | 72 | if (!is.null(x$weeks)) { 73 | # If the data are in weeks, we should make sure that the line up correctly 74 | w <- aweek::date2week(breaks, 75 | week_start = attr(x$weeks, "week_start"), 76 | floor_day = TRUE) 77 | breaks <- aweek::week2date(w) 78 | labels <- if (labels_week) w else ggplot2::waiver() 79 | } else { 80 | labels <- ggplot2::waiver() 81 | } 82 | list(breaks = breaks, labels = labels) 83 | } 84 | -------------------------------------------------------------------------------- /R/subset.R: -------------------------------------------------------------------------------- 1 | ##' Subsetting 'incidence' objects 2 | ##' 3 | ##' Two functions can be used to subset incidence objects. The function 4 | ##' `subset` permits to retain dates within a specified range and, 5 | ##' optionally, specific groups. The operator "[" can be used as for matrices, 6 | ##' using the syntax `x[i,j]` where 'i' is a subset of dates, and 'j' is a 7 | ##' subset of groups. 8 | ##' 9 | ##' @author Thibaut Jombart \email{thibautjombart@@gmail.com} 10 | ##' 11 | ##' @export 12 | ##' 13 | ##' @rdname subset 14 | ##' 15 | ##' @aliases "subset.incidence" "[.incidence" 16 | ##' 17 | ##' @seealso The [incidence()] function to generate the 'incidence' 18 | ##' objects. 19 | ##' 20 | ##' @param x An incidence object, generated by the function 21 | ##' [incidence()]. 22 | ##' 23 | ##' @param from The starting date; data strictly before this date are discarded. 24 | ##' 25 | ##' @param to The ending date; data strictly after this date are discarded. 26 | ##' 27 | ##' @param groups (optional) The groups to retained, indicated as subsets of the 28 | ##' columns of x$counts. 29 | ##' 30 | ##' @param ... Further arguments passed to other methods (not used). 31 | ##' 32 | ##' @examples 33 | ##' ## example using simulated dataset 34 | ##' if(require(outbreaks)) { withAutoprint({ 35 | ##' onset <- ebola_sim$linelist$date_of_onset 36 | ##' 37 | ##' ## weekly incidence 38 | ##' inc <- incidence(onset, interval = 7) 39 | ##' inc 40 | ##' inc[1:10] # first 10 weeks 41 | ##' plot(inc[1:10]) 42 | ##' inc[-c(11:15)] # remove weeks 11-15 43 | ##' plot(inc[-c(11:15)]) 44 | ##' })} 45 | ##' 46 | 47 | subset.incidence <- function(x, ..., from = min(x$dates), to = max(x$dates), 48 | groups = TRUE){ 49 | 50 | ## We need to make sure the comparison with dates is going to work. As for the 51 | ## [ operator, 'from' and 'to' are assumed to be expressed in the same way as 52 | ## the x$dates. 53 | 54 | is_date <- inherits(x$dates, "Date") 55 | numeric_from <- is.numeric(from) 56 | numeric_to <- is.numeric(to) 57 | 58 | if (is_date && (numeric_from || numeric_to)) { 59 | the_intervals <- get_interval(x, integer = TRUE) 60 | if (length(the_intervals) == 1L) { 61 | the_intervals <- rep(the_intervals, length(x$dates)) 62 | } 63 | the_intervals <- cumsum(c(0, the_intervals)) 64 | } 65 | if (is_date && numeric_from) { 66 | if (from <= 0) { 67 | from <- 0L 68 | } else if (from >= length(the_intervals) - 1L) { 69 | from <- the_intervals[length(the_intervals) - 1L] 70 | } else { 71 | from <- the_intervals[from] 72 | } 73 | from <- min(x$dates) + from 74 | } 75 | 76 | if (is_date && numeric_to) { 77 | if (to <= 0) { 78 | to <- 0L 79 | } else if (to >= length(the_intervals) - 1L) { 80 | to <- the_intervals[length(the_intervals) - 1L] 81 | } else { 82 | to <- the_intervals[to] 83 | } 84 | to <- min(x$dates) + to 85 | } 86 | 87 | to.keep <- x$dates >= from & x$dates <= to 88 | 89 | if (sum(to.keep) < 1) { 90 | stop("No data retained.") 91 | } 92 | x[to.keep, groups] 93 | } 94 | 95 | 96 | 97 | 98 | ##' @export 99 | ##' @rdname subset 100 | ##' @param i a subset of dates to retain 101 | ##' @param j a subset of groups to retain 102 | 103 | "[.incidence" <- function(x, i, j){ 104 | if (missing(i)) { 105 | i <- TRUE 106 | } 107 | 108 | if (missing(j)) { 109 | j <- TRUE 110 | } 111 | 112 | out <- x 113 | if (is.character(j) && !all(j %in% group_names(x))) { 114 | odd_names <- j[!j %in% group_names(x)] 115 | groups <- if (length(odd_names) > 1) "groups do" else "group does" 116 | odd_names <- paste(j[!j %in% group_names(x)], collapse = "', '") 117 | msg <- sprintf("The following %s not exist: '%s'", groups, odd_names) 118 | stop(msg) 119 | } 120 | out$counts <- out$counts[i, j, drop = FALSE] 121 | out$dates <- out$dates[i] 122 | if ("weeks" %in% names(x)) { 123 | out$weeks <- out$weeks[i] 124 | out$isoweeks <- out$isoweeks[i] 125 | } 126 | # Need to use 1L here to keep things type-stable: 127 | # double + integer = double 128 | # integer + integer = integer 129 | # Date + integer = Date 130 | out$timespan <- diff(range(out$dates, na.rm = TRUE)) + 1L 131 | out$n <- sum(out$counts) 132 | out 133 | } 134 | -------------------------------------------------------------------------------- /R/trim_observations.R: -------------------------------------------------------------------------------- 1 | #' Trim observations based on the first and last dates 2 | #' 3 | #' @param observations a vector of dates or integers 4 | #' @param first_date a single date or integer 5 | #' @param last_date a single date or integer 6 | #' 7 | #' @return the trimmed observations as a logical vector 8 | #' @noRd 9 | #' @keywords internal 10 | trim_observations <- function(dates, first_date = NULL, last_date = NULL) { 11 | # Remove the missing observations -------------------- 12 | res <- !is.na(dates) 13 | if (sum(res) < length(dates)) { 14 | message(sprintf("%d missing observations were removed.", 15 | length(dates) - sum(res) 16 | ) 17 | ) 18 | } 19 | dates <- dates[res] 20 | # Trim ends ------------------------------------------ 21 | res <- dates >= first_date & dates <= last_date 22 | if (sum(res) < length(dates)) { 23 | message(sprintf("%d observations outside of [%s, %s] were removed.", 24 | length(dates) - sum(res), 25 | format(first_date), 26 | format(last_date) 27 | ) 28 | ) 29 | } 30 | res 31 | } 32 | -------------------------------------------------------------------------------- /R/valid_interval.R: -------------------------------------------------------------------------------- 1 | #' Return TRUE if the interval is a valid date character 2 | #' 3 | #' @param the_interval an interval string 4 | #' 5 | #' @return a logical value 6 | #' @noRd 7 | #' @keywords internal 8 | is_date_interval <- function(the_interval) { 9 | valid_intervals <- "day|week|month|quarter|year" 10 | grepl(valid_intervals, the_interval, ignore.case = TRUE) 11 | } 12 | 13 | #' Validate potential character values for interval 14 | #' 15 | #' Characters are valid for intervals if they are of the 16 | #' form "day", "week", "month", etc. They can ALSO be 17 | #' valid if they are characters that convert to numbers. 18 | #' 19 | #' @param the_interval a character string of length one 20 | #' 21 | #' @author Zhian Kamvar 22 | #' @return the character string OR a numeric value. 23 | #' @noRd 24 | valid_interval_character <- function(the_interval, standard = TRUE) { 25 | if (is.character(the_interval)) { 26 | if (!is_date_interval(the_interval)) { 27 | suppressWarnings({ 28 | the_interval <- as.numeric(the_interval) 29 | }) 30 | if (is.na(the_interval)) { 31 | stop('The interval must be a number or one of the following: "day", "week", "month", "quarter" or "year"', 32 | call. = FALSE) 33 | } 34 | } else { 35 | valid_intervals <- "^\\d?\\s?(day|week|month|quarter|year)s?$" 36 | must_be_standard <- !grepl(valid_intervals, the_interval, ignore.case = TRUE) 37 | if (!standard && must_be_standard) { 38 | stop(sprintf("The interval '%s' implies a standard and cannot be used with `standard = FALSE`", the_interval)) 39 | } 40 | } 41 | } 42 | the_interval 43 | } 44 | 45 | #' Check to make sure an interval is valid for integer dates 46 | #' 47 | #' This will try to convert the interval if its a character, but complain if 48 | #' it doesn't pass check. 49 | #' 50 | #' @param interval either an integer or character 51 | #' 52 | #' @return interval or it will stop 53 | #' @noRd 54 | #' @keywords internal 55 | valid_interval_integer <- function(interval) { 56 | if (is.character(interval)) { 57 | res <- try(valid_interval_character(interval), silent = TRUE) 58 | if (inherits(res, "try-error")) { 59 | msg <- sprintf("The interval '%s' is not valid. Please supply an integer.", interval) 60 | stop(msg, call. = FALSE) 61 | } else if (is.character(res)) { 62 | msg <- sprintf("The interval '%s' can only be used for Dates, not integers or numerics.", 63 | interval) 64 | stop(msg, call. = FALSE) 65 | } 66 | } 67 | interval 68 | } 69 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | .onLoad <- function(...) { 2 | op <- options() 3 | op.incidence <- list(incidence.max.days = 18262, 4 | incidence.warn.first_date = TRUE) 5 | toset <- !names(op.incidence) %in% op 6 | if (any(toset)) options(op.incidence[toset]) 7 | } 8 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | navbar: 2 | left: 3 | - icon: fa-home fa-lg 4 | href: index.html 5 | - text: Reference 6 | href: reference/index.html 7 | - text: Articles 8 | menu: 9 | - text: "Using the incidence package" 10 | - text: "Overview" 11 | href: articles/overview.html 12 | - text: "Customising Epicurves (visualisation)" 13 | href: articles/customize_plot.html 14 | - text: "Exporting Incidence Data" 15 | href: articles/conversions.html 16 | - text: "------------------" 17 | - text: "Understanding the incidence package" 18 | - text: "The incidence class (data)" 19 | href: articles/incidence_class.html 20 | - text: "The incidence_fit class (models)" 21 | href: articles/incidence_fit_class.html 22 | - text: Changelog 23 | href: news/index.html 24 | right: 25 | - icon: fa-github fa-lg 26 | href: https://github.com/reconhub/incidence 27 | 28 | reference: 29 | - title: Data Conversion 30 | desc: > 31 | Functions for computing and converting incidence objects 32 | contents: 33 | - '`incidence`' 34 | - '`as.data.frame.incidence`' 35 | - title: Incidence Curve Visualisation 36 | desc: > 37 | Functions for plotting incidence curves and models 38 | contents: 39 | - '`plot.incidence`' 40 | - '`incidence_pal1`' 41 | - title: Accessors 42 | desc: Accessor functions for the incidence object 43 | contents: 44 | - '`get_counts`' 45 | - '`get_dates`' 46 | - '`get_fit`' 47 | - '`group_names`' 48 | - '`dim.incidence`' 49 | - title: Data Manipulation 50 | desc: > 51 | Functions for manipulating incidence objects by date or group 52 | contents: 53 | - '`subset.incidence`' 54 | - '`pool`' 55 | - '`cumulate`' 56 | - title: Parameter Estimation 57 | desc: > 58 | Functions for estimating parameters such as peak and doubling time 59 | contents: 60 | - '`bootstrap`' 61 | - '`estimate_peak`' 62 | - '`find_peak`' 63 | - '`fit`' 64 | 65 | 66 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE the "init" and "install" sections below 2 | 3 | # Download script file from GitHub 4 | init: 5 | ps: | 6 | $ErrorActionPreference = "Stop" 7 | Invoke-WebRequest https://raw.githubusercontent.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" 8 | Import-Module '..\appveyor-tool.ps1' 9 | 10 | install: 11 | ps: Bootstrap 12 | 13 | # Adapt as necessary starting from here 14 | 15 | build_script: 16 | - travis-tool.sh install_deps 17 | 18 | test_script: 19 | - travis-tool.sh run_tests 20 | 21 | on_failure: 22 | - 7z a failure.zip *.Rcheck\* 23 | - appveyor PushArtifact failure.zip 24 | 25 | artifacts: 26 | - path: '*.Rcheck\**\*.log' 27 | name: Logs 28 | 29 | - path: '*.Rcheck\**\*.out' 30 | name: Logs 31 | 32 | - path: '*.Rcheck\**\*.fail' 33 | name: Logs 34 | 35 | - path: '*.Rcheck\**\*.Rout' 36 | name: Logs 37 | 38 | - path: '\*_*.tar.gz' 39 | name: Bits 40 | 41 | - path: '\*_*.zip' 42 | name: Bits 43 | -------------------------------------------------------------------------------- /artwork/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/artwork/banner.png -------------------------------------------------------------------------------- /artwork/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/artwork/logo/logo.png -------------------------------------------------------------------------------- /artwork/workflow/workflow_script.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | library(incidence) 4 | library(outbreaks) 5 | 6 | dat <- ebola_sim_clean$linelist 7 | 8 | 9 | cat(paste(head(dat$date_of_onset), collapse = "\n")) 10 | 11 | -------------------------------------------------------------------------------- /bug_reports/issue_34.R: -------------------------------------------------------------------------------- 1 | 2 | ## Reproduce the error 3 | library(incidence) 4 | library(outbreaks) 5 | 6 | onset <- ebola_sim$linelist$date_of_onset 7 | i <- incidence(onset, interval = 7) 8 | plot(i) 9 | 10 | ## Clue: this is not happening if we don't use the iso_week definition 11 | i <- incidence(onset, 7, iso_week = FALSE) 12 | plot(i) 13 | 14 | 15 | ## Explanation: the code generating iso weeks hacked through the ggplot2 16 | ## structure. Instead we specify our own labels and pass them through 17 | ## ggplot2::scale_x_date(). 18 | 19 | ## This function takes a vector of Date objects, and an ideal number of breaks, 20 | ## and generates a list with two components: $breaks, and $labels. $breaks 21 | ## correspond to the first day of the matching iso week; $labels contains vector 22 | ## of labels of the corresponding iso weeks. 23 | 24 | make_iso_weeks_breaks <- function(dates, n = 5) { 25 | breaks_ini <- pretty(dates, n) 26 | iso_weeks <- ISOweek::date2ISOweek(breaks_ini) 27 | iso_weeks_day1 <- sub("-[1-7]+$", "-1", iso_weeks) 28 | list(breaks = ISOweek::ISOweek2date(iso_weeks_day1), 29 | labels = sub("-[1-7]+$", "", iso_weeks) 30 | ) 31 | } 32 | 33 | plot(i) + scale_x_date(breaks = breaks_day1, labels = labels) 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | Patch release tested on: 2 | - fedora 40, R Under development (unstable) (2024-05-29 r86640) 3 | 4 | ## R CMD check results 5 | Status: OK 6 | 7 | ## Reverse dependencies 8 | Status: No changes to worse 9 | -------------------------------------------------------------------------------- /demo/00Index: -------------------------------------------------------------------------------- 1 | incidence-demo Demonstration of the incidence package 2 | -------------------------------------------------------------------------------- /demo/incidence-demo.R: -------------------------------------------------------------------------------- 1 | #' Example 1 ------------------------------------------------------------------ 2 | #' 3 | #' **computing and manipulating stratified weekly incidence** 4 | #' 5 | #' 1) import data 6 | #' 7 | library('outbreaks') 8 | 9 | dat1 <- ebola_sim_clean$linelist 10 | str(dat1, strict.width = "cut", width = 76) 11 | 12 | #' 2) build an incidence object 13 | #' 14 | #+ incidence-curve, fig.width=9, fig.height=5 15 | library('incidence') 16 | library('ggplot2') 17 | 18 | # compute weekly stratified incidence 19 | i.7.group <- incidence(dat1$date_of_onset, interval = 7, groups = dat1$hospital) 20 | # print incidence object 21 | i.7.group 22 | 23 | # plot incidence object 24 | my_theme <- theme_bw(base_size = 12) + 25 | theme(panel.grid.minor = element_blank()) + 26 | theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5, color = "black")) 27 | 28 | plot(i.7.group, border = "white") + 29 | my_theme + 30 | theme(legend.position = c(0.8, 0.75)) 31 | 32 | #' 3) Manipulate incidence object 33 | #' 34 | #+ incidence-early-curve, fig.width=6, fig.height=6 35 | # plot the first 18 weeks, defined hospitals, and use different colors 36 | i.7.sub <- i.7.group[1:18, c(1:2, 4:5)] 37 | hosp_colors <- c("#899DA4", "#C93312", "#FAEFD1", "#DC863B") 38 | plot(i.7.sub, show_cases = TRUE, border = "black", color = hosp_colors) + 39 | my_theme + 40 | theme(legend.position = c(0.35, 0.8)) 41 | # exclude NA group by disabling treating NA as a separate group 42 | i.7.group0 <- incidence(dat1$date_of_onset, 43 | interval = 7, 44 | groups = dat1$hospital, 45 | na_as_group = FALSE) 46 | 47 | # exclude NA using [ operator 48 | i.7.group1 <- subset(i.7.group, groups = -ncol(i.7.group)) 49 | 50 | # exclude NA group using [ operator 51 | i.7.group2 <- i.7.group[, -ncol(i.7.group)] 52 | 53 | # check the resulting incidence objects are identical 54 | identical(i.7.group0$counts, i.7.group1$counts) 55 | identical(i.7.group1, i.7.group2) 56 | 57 | # check groups 58 | colnames(i.7.group1$counts) 59 | 60 | #' Example 2 ------------------------------------------------------------------ 61 | #' 62 | #' **importing pre-computed daily incidence and fitting log-linear model** 63 | #' 64 | #' 1) Import pre-computed daily incidence 65 | #' 66 | #+ incidence-curve2, fig.width=9, fig.height=6 67 | # preview datasets 68 | head(zika_girardot_2015, 3) 69 | head(zika_sanandres_2015, 3) 70 | 71 | # combine two datasets into one 72 | dat2 <- merge(zika_girardot_2015, zika_sanandres_2015, by = "date", all = TRUE) 73 | 74 | # rename variables 75 | names(dat2)[2:3] <- c("Girardot", "San Andres") 76 | 77 | # replace NA with 0 78 | dat2[is.na(dat2)] <- 0 79 | 80 | # convert pre-computed incidence in data.frame into incidence object 81 | # grouped by locations 82 | i.group <- as.incidence(x = dat2[, 2:3], dates = dat2$date) 83 | 84 | # pool incidence across two locations 85 | i.pooled <- pool(i.group) 86 | cowplot::plot_grid( 87 | plot(i.group, border = "white") + my_theme + theme(legend.position = c(0.9, 0.7)), 88 | plot(i.pooled, border = "white") + my_theme, 89 | ncol = 1, 90 | labels = c("(A)", "(B)"), 91 | label_size = 16, 92 | label_x = 0.06, 93 | label_y = 0.94 94 | ) 95 | 96 | #' 2) Fit log-linear regression model 97 | #' 98 | #+ incidence-fit, fig.width=9, fig.height=4 99 | library('magrittr') 100 | 101 | fos <- fit_optim_split(i.pooled) 102 | fos$split 103 | fos$fit 104 | plot(i.pooled, border = "white") %>% 105 | add_incidence_fit(fos$fit) + 106 | my_theme 107 | 108 | -------------------------------------------------------------------------------- /docs/articles/conversions_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/conversions_files/figure-html/example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/conversions_files/figure-html/example-1.png -------------------------------------------------------------------------------- /docs/articles/conversions_files/figure-html/iso-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/conversions_files/figure-html/iso-1.png -------------------------------------------------------------------------------- /docs/articles/conversions_files/figure-html/long-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/conversions_files/figure-html/long-1.png -------------------------------------------------------------------------------- /docs/articles/conversions_files/figure-html/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/conversions_files/figure-html/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /docs/articles/conversions_files/figure-html/unnamed-chunk-3-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/conversions_files/figure-html/unnamed-chunk-3-2.png -------------------------------------------------------------------------------- /docs/articles/conversions_files/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/conversions_files/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/EPIET1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/EPIET1-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/colors1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/colors1-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/colors2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/colors2-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/colors3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/colors3-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/default-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/default-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/default-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/default-2.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/default-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/default-3.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/grid1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/grid1-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/grid2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/grid2-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/incidence_pal1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/incidence_pal1-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/label-bins-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/label-bins-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/legend1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/legend1-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/pal2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/pal2-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/palettes-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/palettes-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/palettes-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/palettes-2.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/saturday-epiweek-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/saturday-epiweek-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/saturday-epiweek2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/saturday-epiweek2-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/saturday-epiweek3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/saturday-epiweek3-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/scales1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/scales1-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/scales2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/scales2-1.png -------------------------------------------------------------------------------- /docs/articles/customize_plot_files/figure-html/scales_breaks-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/customize_plot_files/figure-html/scales_breaks-1.png -------------------------------------------------------------------------------- /docs/articles/incidence_class_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/incidence_class_files/figure-html/i-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/incidence_class_files/figure-html/i-1.png -------------------------------------------------------------------------------- /docs/articles/incidence_class_files/figure-html/sex-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/incidence_class_files/figure-html/sex-1.png -------------------------------------------------------------------------------- /docs/articles/incidence_fit_class_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/incidence_fit_class_files/figure-html/combine-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/incidence_fit_class_files/figure-html/combine-1.png -------------------------------------------------------------------------------- /docs/articles/incidence_fit_class_files/figure-html/fit_dates-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/incidence_fit_class_files/figure-html/fit_dates-1.png -------------------------------------------------------------------------------- /docs/articles/incidence_fit_class_files/figure-html/fit_gender-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/incidence_fit_class_files/figure-html/fit_gender-1.png -------------------------------------------------------------------------------- /docs/articles/incidence_fit_class_files/figure-html/incidence_by_gender-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/incidence_fit_class_files/figure-html/incidence_by_gender-1.png -------------------------------------------------------------------------------- /docs/articles/incidence_fit_class_files/figure-html/incidence_fit_list-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/incidence_fit_class_files/figure-html/incidence_fit_list-1.png -------------------------------------------------------------------------------- /docs/articles/incidence_fit_class_files/figure-html/list_stuff-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/incidence_fit_class_files/figure-html/list_stuff-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/fit.both-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/fit.both-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/fit1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/fit1-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/gender-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/gender-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/groupsub-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/groupsub-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/hosp-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/hosp-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/i7outcome-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/i7outcome-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/incid1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/incid1-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/interv-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/interv-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/interv-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/interv-2.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/interv-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/interv-3.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/middle-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/middle-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/optim-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/optim-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/optim-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/optim-2.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/optim2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/optim2-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/optim2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/optim2-2.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/stripes-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/stripes-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/tail-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/tail-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/unnamed-chunk-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/unnamed-chunk-2-1.png -------------------------------------------------------------------------------- /docs/articles/overview_files/figure-html/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/articles/overview_files/figure-html/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/figs/fit-plot-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/fit-plot-1-1.png -------------------------------------------------------------------------------- /docs/figs/fit-plot-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/fit-plot-2-1.png -------------------------------------------------------------------------------- /docs/figs/fit1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/fit1-1.png -------------------------------------------------------------------------------- /docs/figs/gender-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/gender-1.png -------------------------------------------------------------------------------- /docs/figs/i7outcome-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/i7outcome-1.png -------------------------------------------------------------------------------- /docs/figs/i7outcome_cum-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/i7outcome_cum-1.png -------------------------------------------------------------------------------- /docs/figs/incid1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/incid1-1.png -------------------------------------------------------------------------------- /docs/figs/optim-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/optim-1.png -------------------------------------------------------------------------------- /docs/figs/optim-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/optim-2.png -------------------------------------------------------------------------------- /docs/figs/pipe-fit-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/pipe-fit-1.png -------------------------------------------------------------------------------- /docs/figs/start-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/start-1.png -------------------------------------------------------------------------------- /docs/figs/tail-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/figs/tail-1.png -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $(".examples, div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent; 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 2.7.3 2 | pkgdown: 1.5.1 3 | pkgdown_sha: ~ 4 | articles: 5 | conversions: conversions.html 6 | customize_plot: customize_plot.html 7 | incidence_class: incidence_class.html 8 | incidence_fit_class: incidence_fit_class.html 9 | overview: overview.html 10 | last_built: 2020-07-24T03:00Z 11 | 12 | -------------------------------------------------------------------------------- /docs/reference/bootstrap-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/bootstrap-1.png -------------------------------------------------------------------------------- /docs/reference/bootstrap-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/bootstrap-2.png -------------------------------------------------------------------------------- /docs/reference/conversions-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/conversions-1.png -------------------------------------------------------------------------------- /docs/reference/cumulate-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/cumulate-1.png -------------------------------------------------------------------------------- /docs/reference/cumulate-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/cumulate-2.png -------------------------------------------------------------------------------- /docs/reference/estimate_peak-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/estimate_peak-1.png -------------------------------------------------------------------------------- /docs/reference/estimate_peak-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/estimate_peak-2.png -------------------------------------------------------------------------------- /docs/reference/estimate_peak-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/estimate_peak-3.png -------------------------------------------------------------------------------- /docs/reference/estimate_peak-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/estimate_peak-4.png -------------------------------------------------------------------------------- /docs/reference/find_peak-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/find_peak-1.png -------------------------------------------------------------------------------- /docs/reference/find_peak-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/find_peak-2.png -------------------------------------------------------------------------------- /docs/reference/find_peak-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/find_peak-3.png -------------------------------------------------------------------------------- /docs/reference/fit-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/fit-1.png -------------------------------------------------------------------------------- /docs/reference/fit-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/fit-2.png -------------------------------------------------------------------------------- /docs/reference/fit-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/fit-3.png -------------------------------------------------------------------------------- /docs/reference/fit-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/fit-4.png -------------------------------------------------------------------------------- /docs/reference/fit-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/fit-5.png -------------------------------------------------------------------------------- /docs/reference/fit-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/fit-6.png -------------------------------------------------------------------------------- /docs/reference/fit-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/fit-7.png -------------------------------------------------------------------------------- /docs/reference/fit-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/fit-8.png -------------------------------------------------------------------------------- /docs/reference/fit-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/fit-9.png -------------------------------------------------------------------------------- /docs/reference/incidence-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/incidence-1.png -------------------------------------------------------------------------------- /docs/reference/incidence-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/incidence-2.png -------------------------------------------------------------------------------- /docs/reference/incidence-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/incidence-3.png -------------------------------------------------------------------------------- /docs/reference/incidence-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/incidence-4.png -------------------------------------------------------------------------------- /docs/reference/incidence-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/incidence-5.png -------------------------------------------------------------------------------- /docs/reference/palettes-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/palettes-1.png -------------------------------------------------------------------------------- /docs/reference/palettes-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/palettes-2.png -------------------------------------------------------------------------------- /docs/reference/palettes-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/palettes-3.png -------------------------------------------------------------------------------- /docs/reference/palettes-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/palettes-4.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-1.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-10.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-11.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-2.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-3.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-4.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-5.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-6.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-7.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-8.png -------------------------------------------------------------------------------- /docs/reference/plot.incidence-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/plot.incidence-9.png -------------------------------------------------------------------------------- /docs/reference/subset-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/subset-1.png -------------------------------------------------------------------------------- /docs/reference/subset-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/docs/reference/subset-2.png -------------------------------------------------------------------------------- /figs/fit-plot-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/fit-plot-1-1.png -------------------------------------------------------------------------------- /figs/fit-plot-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/fit-plot-2-1.png -------------------------------------------------------------------------------- /figs/fit1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/fit1-1.png -------------------------------------------------------------------------------- /figs/gender-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/gender-1.png -------------------------------------------------------------------------------- /figs/i7outcome-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/i7outcome-1.png -------------------------------------------------------------------------------- /figs/i7outcome_cum-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/i7outcome_cum-1.png -------------------------------------------------------------------------------- /figs/incid1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/incid1-1.png -------------------------------------------------------------------------------- /figs/optim-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/optim-1.png -------------------------------------------------------------------------------- /figs/optim-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/optim-2.png -------------------------------------------------------------------------------- /figs/pipe-fit-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/pipe-fit-1.png -------------------------------------------------------------------------------- /figs/start-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/start-1.png -------------------------------------------------------------------------------- /figs/tail-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/figs/tail-1.png -------------------------------------------------------------------------------- /incidence.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 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite the incidence package in publications use:") 2 | 3 | bibentry(bibtype = "Article", 4 | title = "Epidemic curves made easy using the R package incidence [version 1; referees: awaiting peer review]", 5 | author = c(as.person("Zhian N. Kamvar"), 6 | as.person("Jun Cai"), 7 | as.person("Juliet R.C. Pulliam"), 8 | as.person("Jakob Schumacher"), 9 | as.person("Thibaut Jombart")), 10 | journal = "F1000Research", 11 | year = "2019", 12 | volume = "8", 13 | number = "139", 14 | url = "https://doi.org/10.12688/f1000research.18002.1", 15 | 16 | textVersion = 17 | paste("Kamvar ZN, Cai J, Pulliam JRC, Schumacher J, Jombart T.", 18 | "Epidemic curves made easy using the R package incidence [version 1; referees: awaiting peer review].", 19 | "F1000Research 2019, 8:139.", 20 | "URL https://doi.org/10.12688/f1000research.18002.1.") 21 | ) 22 | 23 | 24 | year = sub('.*(2[[:digit:]]{3})-.*', '\\1', meta$Date, perl = TRUE) 25 | vers = paste('R package version', meta$Version) 26 | 27 | bibentry( 28 | bibtype = 'Manual', 29 | title = paste('incidence:', meta$Title), 30 | author = c(as.person("Thibaut Jombart"), 31 | as.person("Zhian N. Kamvar"), 32 | as.person("Rich FitzJohn"), 33 | as.person("Jun Cai"), 34 | as.person("Sangeeta Bhatia"), 35 | as.person("Jakob Schumacher"), 36 | as.person("Juliet R.C. Pulliam")), 37 | year = year, 38 | note = vers, 39 | url = "https://doi.org/10.5281/zenodo.2584018", 40 | textVersion = paste('Thibaut Jombart, Zhian N. Kamvar, Rich FitzJohn, Jun Cai, ', 41 | 'Sangeeta Bhatia, Jakob Schumacher and Juliet R.C. Pulliam (', 42 | year, '). incidence: ', meta$Title, '. ', vers, '. URL https://doi.org/10.5281/zenodo.2584018', sep = ''), 43 | header = "To cite the specific version of incidence package in publications use:" 44 | ) 45 | -------------------------------------------------------------------------------- /inst/WORDLIST: -------------------------------------------------------------------------------- 1 | analyse 2 | behaviour 3 | colours 4 | conf 5 | csv 6 | customisation 7 | customisations 8 | Customise 9 | devtools 10 | epi 11 | epicurve 12 | epicurves 13 | EPIET 14 | EVD 15 | Fitzjohn 16 | ggplot 17 | github 18 | grey 19 | Höhle 20 | http 21 | iso 22 | ISOweek 23 | isoweeks 24 | Jombart 25 | Kamvar 26 | knitr 27 | modelled 28 | modelling 29 | Modelling 30 | POSIXct 31 | pre 32 | pred 33 | Programme 34 | randomised 35 | repidemicsconsortium 36 | rmarkdown 37 | Thibaut 38 | timespan 39 | toc 40 | VignetteEncoding 41 | VignetteEngine 42 | VignetteIndexEntry 43 | visualise 44 | www 45 | Www 46 | yyyy 47 | Zhian 48 | -------------------------------------------------------------------------------- /man/accessors.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dim.R, R/get_interval.R, R/get_n.R, 3 | % R/get_timespan.R 4 | \name{dim.incidence} 5 | \alias{dim.incidence} 6 | \alias{get_interval} 7 | \alias{get_interval.default} 8 | \alias{get_interval.incidence} 9 | \alias{get_n} 10 | \alias{get_n.default} 11 | \alias{get_n.incidence} 12 | \alias{get_timespan} 13 | \alias{get_timespan.default} 14 | \alias{get_timespan.incidence} 15 | \title{Access various elements of an incidence object} 16 | \usage{ 17 | \method{dim}{incidence}(x) 18 | 19 | get_interval(x, ...) 20 | 21 | \method{get_interval}{default}(x, ...) 22 | 23 | \method{get_interval}{incidence}(x, integer = TRUE, ...) 24 | 25 | get_n(x) 26 | 27 | \method{get_n}{default}(x) 28 | 29 | \method{get_n}{incidence}(x) 30 | 31 | get_timespan(x) 32 | 33 | \method{get_timespan}{default}(x) 34 | 35 | \method{get_timespan}{incidence}(x) 36 | } 37 | \arguments{ 38 | \item{x}{an \link{incidence} object.} 39 | 40 | \item{...}{Unused} 41 | 42 | \item{integer}{When \code{TRUE} (default), the interval will be converted to an 43 | integer vector if it is stored as a character in the incidence object.} 44 | } 45 | \value{ 46 | \itemize{ 47 | \item \code{dim()} the dimensions in the number of bins and number of groups 48 | } 49 | 50 | \itemize{ 51 | \item \code{get_interval()} if \code{integer = TRUE}: an integer vector, otherwise: the 52 | value stored in \code{x$interval} 53 | } 54 | 55 | \itemize{ 56 | \item \code{get_n()} The total number of cases stored in the object 57 | } 58 | 59 | \itemize{ 60 | \item \code{get_timespan()}: an \code{integer} denoting the timespan represented by the 61 | incidence object. 62 | } 63 | } 64 | \description{ 65 | Access various elements of an incidence object 66 | } 67 | \examples{ 68 | 69 | set.seed(999) 70 | dat <- as.Date(Sys.Date()) + sample(-3:50, 100, replace = TRUE) 71 | x <- incidence(dat, interval = "month") 72 | 73 | # the value stored in the interval element 74 | get_interval(x) 75 | 76 | # the numeric value of the interval in days 77 | get_interval(x, integer = FALSE) 78 | 79 | # the number of observations in the object 80 | get_n(x) 81 | 82 | # the length of time represented 83 | get_timespan(x) 84 | 85 | # the number of groups 86 | ncol(x) 87 | 88 | # the number of bins (intervals) 89 | nrow(x) 90 | } 91 | \seealso{ 92 | \itemize{ 93 | \item \code{\link[=get_counts]{get_counts()}} to access the matrix of counts 94 | \item \code{\link[=get_dates]{get_dates()}} to access the dates on the right, left, and center of the 95 | interval. 96 | \item \code{\link[=group_names]{group_names()}} to access and possibly re-name the groups 97 | } 98 | } 99 | \keyword{accessors} 100 | -------------------------------------------------------------------------------- /man/bootstrap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bootstrap.R 3 | \name{bootstrap} 4 | \alias{bootstrap} 5 | \title{Bootstrap incidence time series} 6 | \usage{ 7 | bootstrap(x, randomise_groups = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{incidence} object.} 11 | 12 | \item{randomise_groups}{A \code{logical} indicating whether groups should be 13 | randomised as well in the resampling procedure; respective group sizes will 14 | be preserved, but this can be used to remove any group-specific temporal 15 | dynamics. If \code{FALSE} (default), data are resampled within groups.} 16 | } 17 | \value{ 18 | An \code{incidence} object. 19 | } 20 | \description{ 21 | This function can be used to bootstrap \code{incidence} objects. Bootstrapping is 22 | done by sampling with replacement the original input dates. See \code{details} for 23 | more information on how this is implemented. 24 | } 25 | \details{ 26 | As original data are not stored in \code{incidence} objects, the 27 | bootstrapping is achieved by multinomial sampling of date bins weighted by 28 | their relative incidence. 29 | } 30 | \examples{ 31 | 32 | if (require(outbreaks) && require(ggplot2)) { withAutoprint({ 33 | i <- incidence(fluH7N9_china_2013$date_of_onset) 34 | i 35 | plot(i) 36 | 37 | ## one simple bootstrap 38 | x <- bootstrap(i) 39 | x 40 | plot(x) 41 | 42 | })} 43 | 44 | } 45 | \seealso{ 46 | \link{find_peak} to use estimate peak date using bootstrap 47 | } 48 | \author{ 49 | Thibaut Jombart \email{thibautjombart@gmail.com} 50 | } 51 | -------------------------------------------------------------------------------- /man/conversions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/conversion.R 3 | \name{as.data.frame.incidence} 4 | \alias{as.data.frame.incidence} 5 | \alias{as.incidence} 6 | \alias{as.incidence.matrix} 7 | \alias{as.incidence.data.frame} 8 | \alias{as.incidence.numeric} 9 | \title{Conversion of incidence objects} 10 | \usage{ 11 | \method{as.data.frame}{incidence}(x, ..., long = FALSE) 12 | 13 | as.incidence(x, ...) 14 | 15 | \method{as.incidence}{matrix}( 16 | x, 17 | dates = NULL, 18 | interval = NULL, 19 | standard = TRUE, 20 | isoweeks = standard, 21 | ... 22 | ) 23 | 24 | \method{as.incidence}{data.frame}(x, dates = NULL, interval = NULL, isoweeks = TRUE, ...) 25 | 26 | \method{as.incidence}{numeric}(x, dates = NULL, interval = NULL, isoweeks = TRUE, ...) 27 | } 28 | \arguments{ 29 | \item{x}{An \code{incidence} object, or an object to be converted as 30 | \code{incidence} (see details).} 31 | 32 | \item{...}{Further arguments passed to other functions (no used).} 33 | 34 | \item{long}{A logical indicating if the output data.frame should be 'long', i.e. where a single 35 | column containing 'groups' is added in case of data computed on several groups.} 36 | 37 | \item{dates}{A vector of dates, each corresponding to the (inclusive) lower 38 | limit of the bins.} 39 | 40 | \item{interval}{An integer indicating the time interval used in the 41 | computation of the incidence. If NULL, it will be determined from the first 42 | time interval between provided dates. If only one date is provided, it will 43 | trigger an error.} 44 | 45 | \item{standard}{A logical indicating whether standardised dates should be 46 | used. Defaults to \code{TRUE}.} 47 | 48 | \item{isoweeks}{Deprecated. Use standard.} 49 | } 50 | \description{ 51 | These functions convert \code{incidence} objects into other classes. 52 | } 53 | \details{ 54 | Conversion to \code{incidence} objects should only be done when the 55 | original dates are not available. In such case, the argument \code{x} 56 | should be a matrix corresponding to the \verb{$counts} element of an 57 | \code{incidence} object, i.e. giving counts with time intervals in rows and 58 | named groups in columns. In the absence of groups, a single unnamed columns 59 | should be given. \code{data.frame} and vectors will be coerced to a matrix. 60 | } 61 | \examples{ 62 | ## create fake data 63 | data <- c(0,1,1,2,1,3,4,5,5,5,5,4,4,26,6,7,9) 64 | sex <- sample(c("m","f"), length(data), replace=TRUE) 65 | 66 | ## get incidence per group (sex) 67 | i <- incidence(data, groups = sex) 68 | i 69 | plot(i) 70 | 71 | ## convert to data.frame 72 | as.data.frame(i) 73 | 74 | ## same, 'long format' 75 | as.data.frame(i, long = TRUE) 76 | 77 | 78 | 79 | ## conversion from a matrix of counts to an incidence object 80 | i$counts 81 | new_i <- as.incidence(i$counts, i$dates) 82 | new_i 83 | all.equal(i, new_i) 84 | 85 | } 86 | \seealso{ 87 | the \code{\link[=incidence]{incidence()}} function to generate the 'incidence' objects. 88 | } 89 | \author{ 90 | Thibaut Jombart \email{thibautjombart@gmail.com}, Rich Fitzjohn 91 | } 92 | -------------------------------------------------------------------------------- /man/cumulate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cumulate.R 3 | \name{cumulate} 4 | \alias{cumulate} 5 | \alias{cumulate.default} 6 | \alias{cumulate.incidence} 7 | \title{Compute cumulative 'incidence'} 8 | \usage{ 9 | cumulate(x) 10 | 11 | \method{cumulate}{default}(x) 12 | 13 | \method{cumulate}{incidence}(x) 14 | } 15 | \arguments{ 16 | \item{x}{An incidence object.} 17 | } 18 | \description{ 19 | \code{cumulate} is an S3 generic to compute cumulative numbers, with methods 20 | for different types of objects: 21 | } 22 | \details{ 23 | \itemize{ 24 | 25 | \item default method is a wrapper for \code{cumsum} 26 | 27 | \item \code{incidence} objects: computes cumulative incidence over time 28 | 29 | \item \code{projections} objects: same, for \code{projections} objects, 30 | implemented in the similarly named package; see \code{?cumulate.projections} 31 | for more information, after loading the package 32 | 33 | } 34 | } 35 | \examples{ 36 | dat <- as.integer(c(0,1,2,2,3,5,7)) 37 | group <- factor(c(1, 2, 3, 3, 3, 3, 1)) 38 | i <- incidence(dat, groups = group) 39 | i 40 | plot(i) 41 | 42 | i_cum <- cumulate(i) 43 | i_cum 44 | plot(i_cum) 45 | 46 | } 47 | \seealso{ 48 | The \code{\link[=incidence]{incidence()}} function to generate the 'incidence' 49 | objects. 50 | } 51 | \author{ 52 | Thibaut Jombart \email{thibautjombart@gmail.com} 53 | } 54 | -------------------------------------------------------------------------------- /man/estimate_peak.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/estimate_peak.R 3 | \name{estimate_peak} 4 | \alias{estimate_peak} 5 | \title{Estimate the peak date of an incidence curve using bootstrap} 6 | \usage{ 7 | estimate_peak(x, n = 100, alpha = 0.05) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{incidence} object.} 11 | 12 | \item{n}{The number of bootstrap datasets to be generated; defaults to 100.} 13 | 14 | \item{alpha}{The type 1 error chosen for the confidence interval; defaults to 15 | 0.05.} 16 | } 17 | \value{ 18 | A list containing the following items: 19 | \itemize{ 20 | \item \code{observed}: the peak incidence of the original dataset 21 | \item \code{estimated}: the mean peak time of the bootstrap datasets 22 | \item \code{ci}: the confidence interval based on bootstrap datasets 23 | \item \code{peaks}: the peak times of the bootstrap datasets 24 | } 25 | } 26 | \description{ 27 | This function can be used to estimate the peak of an epidemic curve stored as 28 | \code{incidence}, using bootstrap. See \link{bootstrap} for more information 29 | on the resampling. 30 | } 31 | \details{ 32 | Input dates are resampled with replacement to form bootstrapped 33 | datasets; the peak is reported for each, resulting in a distribution of 34 | peak times. When there are ties for peak incidence, only the first date is 35 | reported. 36 | 37 | Note that the bootstrapping approach used for estimating the peak time makes 38 | the following assumptions: 39 | \itemize{ 40 | \item the total number of event is known (no uncertainty on total incidence) 41 | \item dates with no events (zero incidence) will never be in bootstrapped datasets 42 | \item the reporting is assumed to be constant over time, i.e. every case is 43 | equally likely to be reported 44 | } 45 | } 46 | \examples{ 47 | 48 | if (require(outbreaks) && require(ggplot2)) { withAutoprint({ 49 | i <- incidence(fluH7N9_china_2013$date_of_onset) 50 | i 51 | plot(i) 52 | 53 | ## one simple bootstrap 54 | x <- bootstrap(i) 55 | x 56 | plot(x) 57 | 58 | ## find 95\% CI for peak time using bootstrap 59 | peak_data <- estimate_peak(i) 60 | peak_data 61 | summary(peak_data$peaks) 62 | 63 | ## show confidence interval 64 | plot(i) + geom_vline(xintercept = peak_data$ci, col = "red", lty = 2) 65 | 66 | ## show the distribution of bootstrapped peaks 67 | df <- data.frame(peak = peak_data$peaks) 68 | plot(i) + geom_density(data = df, 69 | aes(x = peak, y = 10 * ..scaled..), 70 | alpha = .2, fill = "red", color = "red") 71 | 72 | })} 73 | 74 | } 75 | \seealso{ 76 | \link{bootstrap} for the bootstrapping underlying this 77 | approach and \link{find_peak} to find the peak in a single 78 | \code{incidence} object. 79 | } 80 | \author{ 81 | Thibaut Jombart \email{thibautjombart@gmail.com}, with inputs on 82 | caveats from Michael Höhle. 83 | } 84 | -------------------------------------------------------------------------------- /man/find_peak.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/find_peak.R 3 | \name{find_peak} 4 | \alias{find_peak} 5 | \title{Find the peak date of an incidence curve} 6 | \usage{ 7 | find_peak(x, pool = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{incidence} object.} 11 | 12 | \item{pool}{If \code{TRUE} (default), any groups will be pooled before finding 13 | a peak. If \code{FALSE}, separate peaks will be found for each group.} 14 | } 15 | \value{ 16 | The date of the (first) highest incidence in the data. 17 | } 18 | \description{ 19 | This function can be used to find the peak of an epidemic curve stored as an 20 | \code{incidence} object. 21 | } 22 | \examples{ 23 | 24 | if (require(outbreaks) && require(ggplot2)) { withAutoprint({ 25 | i <- incidence(fluH7N9_china_2013$date_of_onset) 26 | i 27 | plot(i) 28 | 29 | ## one simple bootstrap 30 | x <- bootstrap(i) 31 | x 32 | plot(x) 33 | 34 | ## find 95\% CI for peak time using bootstrap 35 | find_peak(i) 36 | 37 | 38 | ## show confidence interval 39 | plot(i) + geom_vline(xintercept = find_peak(i), col = "red", lty = 2) 40 | 41 | })} 42 | 43 | } 44 | \seealso{ 45 | \code{\link[=estimate_peak]{estimate_peak()}} for bootstrap estimates of the peak time 46 | } 47 | \author{ 48 | Thibaut Jombart \email{thibautjombart@gmail.com}, Zhian N. Kamvar 49 | \email{zkamvar@gmail.com} 50 | } 51 | -------------------------------------------------------------------------------- /man/get_counts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_counts.R 3 | \name{get_counts} 4 | \alias{get_counts} 5 | \alias{get_counts.incidence} 6 | \title{Get counts from an incidence object} 7 | \usage{ 8 | get_counts(x, groups = NULL) 9 | 10 | \method{get_counts}{incidence}(x, groups = NULL) 11 | } 12 | \arguments{ 13 | \item{x}{an \code{incidence} object.} 14 | 15 | \item{groups}{if there are groups, use this to specify a group or groups to 16 | subset. Defaults to \code{NULL} indicating that all groups are returned.} 17 | } 18 | \value{ 19 | a matrix of counts where each row represents a date bin 20 | } 21 | \description{ 22 | Get counts from an incidence object 23 | } 24 | \examples{ 25 | if (require(outbreaks)) { withAutoprint({ 26 | dat <- ebola_sim$linelist$date_of_onset 27 | gend <- ebola_sim$linelist$gender 28 | i <- incidence(dat, interval = "week", groups = gend) 29 | 30 | ## Use with an object and no arguments gives the counts matrix 31 | head(get_counts(i)) 32 | 33 | ## Specifying a position or group name will return a matrix subset to that 34 | ## group 35 | head(get_counts(i, 1L)) 36 | head(get_counts(i, "f")) 37 | 38 | ## Specifying multiple groups allows you to rearrange columns 39 | head(get_counts(i, c("m", "f"))) 40 | 41 | ## If you want a vector, you can use drop 42 | drop(get_counts(i, "f")) 43 | })} 44 | } 45 | -------------------------------------------------------------------------------- /man/get_dates.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_dates.R 3 | \name{get_dates} 4 | \alias{get_dates} 5 | \alias{get_dates.default} 6 | \alias{get_dates.incidence} 7 | \title{Retrieve dates from an incidence object} 8 | \usage{ 9 | get_dates(x, ...) 10 | 11 | \method{get_dates}{default}(x, ...) 12 | 13 | \method{get_dates}{incidence}(x, position = "left", count_days = FALSE, ...) 14 | } 15 | \arguments{ 16 | \item{x}{an \link{incidence} object} 17 | 18 | \item{...}{Unused} 19 | 20 | \item{position}{One of "left", "center", "middle", or "right" specifying what 21 | side of the bin the date should be drawn from.} 22 | 23 | \item{count_days}{If \code{TRUE}, the result will be represented as the number of 24 | days from the first date.} 25 | } 26 | \value{ 27 | a vector of dates or numerics 28 | } 29 | \description{ 30 | Retrieve dates from an incidence object 31 | } 32 | \examples{ 33 | 34 | set.seed(999) 35 | dat <- as.Date(Sys.Date()) + sample(-3:50, 100, replace = TRUE) 36 | x <- incidence(dat, interval = "month") 37 | get_dates(x) 38 | get_dates(x, position = "middle") 39 | set.seed(999) 40 | dat <- as.Date(Sys.Date()) + sample(-3:50, 100, replace = TRUE) 41 | x <- incidence(dat, interval = "month") 42 | get_dates(x) 43 | get_dates(x, "center") 44 | get_dates(x, "right") 45 | 46 | # Return dates by number of days from the first date 47 | get_dates(x, count_days = TRUE) 48 | get_dates(incidence(-5:5), count_days = TRUE) 49 | } 50 | \keyword{accessors} 51 | -------------------------------------------------------------------------------- /man/get_fit.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_fit.R, R/get_info.R 3 | \name{get_fit} 4 | \alias{get_fit} 5 | \alias{get_fit.incidence_fit} 6 | \alias{get_fit.incidence_fit_list} 7 | \alias{get_info} 8 | \alias{get_info.incidence_fit} 9 | \alias{get_info.incidence_fit_list} 10 | \title{Accessors for \code{incidence_fit} objects} 11 | \usage{ 12 | get_fit(x) 13 | 14 | \method{get_fit}{incidence_fit}(x) 15 | 16 | \method{get_fit}{incidence_fit_list}(x) 17 | 18 | get_info(x, what = "r", ...) 19 | 20 | \method{get_info}{incidence_fit}(x, what = "r", ...) 21 | 22 | \method{get_info}{incidence_fit_list}(x, what = "r", groups = NULL, na.rm = TRUE, ...) 23 | } 24 | \arguments{ 25 | \item{x}{an \code{incidence_fit} or \code{incidence_fit_list} 26 | object.} 27 | 28 | \item{what}{the name of the item in the "info" element of the \code{incidence_fit} 29 | object.} 30 | 31 | \item{...}{currently unused.} 32 | 33 | \item{groups}{if \code{what = "pred"} and \code{x} is an \code{incidence_fit_list} object, 34 | then this indicates what part of the nesting hierarchy becomes the column 35 | named "groups". Defaults to \code{NULL}, indicating that no groups column will 36 | be added/modified.} 37 | 38 | \item{na.rm}{when \code{TRUE} (default), missing values will be excluded from the 39 | results.} 40 | } 41 | \value{ 42 | a list of \code{incidence_fit} objects. 43 | } 44 | \description{ 45 | Accessors for \code{incidence_fit} objects 46 | } 47 | \examples{ 48 | 49 | if (require(outbreaks)) { withAutoprint({ 50 | 51 | dat <- ebola_sim$linelist$date_of_onset 52 | 53 | ## EXAMPLE WITH A SINGLE MODEL 54 | 55 | ## compute weekly incidence 56 | sex <- ebola_sim$linelist$gender 57 | i.sex <- incidence(dat, interval = 7, group = sex) 58 | 59 | ## Compute the optimal split for each group separately 60 | fits <- fit_optim_split(i.sex, separate_split = TRUE) 61 | 62 | ## `fits` contains an `incidence_fit_list` object 63 | fits$fit 64 | 65 | ## Grab the list of `incidence_fit` objects 66 | get_fit(fits$fit) 67 | 68 | ## Get the predictions for all groups 69 | get_info(fits$fit, "pred", groups = 1) 70 | 71 | ## Get the predictions, but set `groups` to "before" and "after" 72 | get_info(fits$fit, "pred", groups = 2) 73 | 74 | ## Get the reproduction number 75 | get_info(fits$fit, "r") 76 | 77 | ## Get the doubling confidence interval 78 | get_info(fits$fit, "doubling.conf") 79 | 80 | ## Get the halving confidence interval 81 | get_info(fits$fit, "halving.conf") 82 | })} 83 | } 84 | -------------------------------------------------------------------------------- /man/group_names.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/group_names.R 3 | \name{group_names} 4 | \alias{group_names} 5 | \alias{group_names<-} 6 | \alias{group_names.default} 7 | \alias{group_names<-.default} 8 | \alias{`group_names<-`.default} 9 | \alias{group_names.incidence} 10 | \alias{group_names<-.incidence} 11 | \title{extract and set group names} 12 | \usage{ 13 | group_names(x, value) 14 | 15 | group_names(x) <- value 16 | 17 | \method{group_names}{default}(x, value) 18 | 19 | \method{group_names}{default}(x) <- value 20 | 21 | \method{group_names}{incidence}(x, value = NULL) 22 | 23 | \method{group_names}{incidence}(x) <- value 24 | } 25 | \arguments{ 26 | \item{x}{an \code{\link[=incidence]{incidence()}} object.} 27 | 28 | \item{value}{character vector used to rename groups} 29 | } 30 | \value{ 31 | an integer indicating the number of groups present in the incidence 32 | object. 33 | } 34 | \description{ 35 | extract and set group names 36 | } 37 | \details{ 38 | This accessor will return a 39 | } 40 | \examples{ 41 | i <- incidence(dates = sample(10, 100, replace = TRUE), 42 | interval = 1L, 43 | groups = sample(letters[1:3], 100, replace = TRUE)) 44 | i 45 | group_names(i) 46 | 47 | # change the names of the groups 48 | group_names(i) <- c("Group 1", "Group 2", "Group 3") 49 | i 50 | 51 | # example if there are mistakes in the original data, e.g. 52 | # something is misspelled 53 | set.seed(50) 54 | grps <- sample(c("child", "adult", "adlut"), 100, replace = TRUE, prob = c(0.45, 0.45, 0.05)) 55 | i <- incidence(dates = sample(10, 100, replace = TRUE), 56 | interval = 1L, 57 | groups = grps) 58 | colSums(get_counts(i)) 59 | 60 | # If you change the name of the mis-spelled group, it will be merged with the 61 | # correctly-spelled group 62 | gname <- group_names(i) 63 | gname[gname == "adlut"] <- "adult" 64 | # without side-effects 65 | print(ii <- group_names(i, gname)) 66 | colSums(get_counts(i)) # original still has three groups 67 | colSums(get_counts(ii)) 68 | # with side-effects 69 | group_names(i) <- gname 70 | colSums(get_counts(i)) 71 | } 72 | \keyword{accessors} 73 | -------------------------------------------------------------------------------- /man/palettes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/palettes.R 3 | \name{incidence_pal1} 4 | \alias{incidence_pal1} 5 | \alias{palettes} 6 | \alias{incidence_pal1_light} 7 | \alias{incidence_pal1_dark} 8 | \title{Color palettes used in incidence} 9 | \usage{ 10 | incidence_pal1(n) 11 | 12 | incidence_pal1_light(n) 13 | 14 | incidence_pal1_dark(n) 15 | } 16 | \arguments{ 17 | \item{n}{a number of colors} 18 | } 19 | \description{ 20 | These functions are color palettes used in incidence. 21 | } 22 | \examples{ 23 | 24 | plot(1:4, cex=8, pch=20, col = incidence_pal1(4), 25 | main = "palette: incidence_pal1") 26 | plot(1:100, cex=8, pch=20, col = incidence_pal1(100), 27 | main ="palette: incidence_pal1") 28 | plot(1:100, cex=8, pch=20, col = incidence_pal1_light(100), 29 | main="palette: incidence_pal1_light") 30 | plot(1:100, cex=8, pch=20, col = incidence_pal1_dark(100), 31 | main="palette: incidence_pal1_dark") 32 | 33 | } 34 | \author{ 35 | Thibaut Jombart \email{thibautjombart@gmail.com} 36 | } 37 | -------------------------------------------------------------------------------- /man/pool.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pool.R 3 | \name{pool} 4 | \alias{pool} 5 | \title{Pool 'incidence' across groups} 6 | \usage{ 7 | pool(x) 8 | } 9 | \arguments{ 10 | \item{x}{An 'incidence' object.} 11 | } 12 | \description{ 13 | This function pools incidence across all groups of an \code{incidence} 14 | object. The resulting \code{\link[=incidence]{incidence()}} object will contains counts 15 | summed over all groups present in the input. 16 | } 17 | \examples{ 18 | dat <- as.integer(c(0,1,2,2,3,5,7)) 19 | group <- factor(c(1, 2, 3, 3, 3, 3, 1)) 20 | i <- incidence(dat, groups = group) 21 | i 22 | i$counts 23 | 24 | ## pool all groups 25 | pool(i) 26 | pool(i)$counts 27 | 28 | ## pool only groups 1 and 3 29 | pool(i[,c(1,3)]) 30 | pool(i[,c(1,3)])$counts 31 | 32 | } 33 | \seealso{ 34 | The \code{\link[=incidence]{incidence()}} function to generate the 'incidence' 35 | objects. 36 | } 37 | \author{ 38 | Thibaut Jombart \email{thibautjombart@gmail.com} 39 | } 40 | -------------------------------------------------------------------------------- /man/subset.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/subset.R 3 | \name{subset.incidence} 4 | \alias{subset.incidence} 5 | \alias{"subset.incidence"} 6 | \alias{"[.incidence"} 7 | \alias{[.incidence} 8 | \title{Subsetting 'incidence' objects} 9 | \usage{ 10 | \method{subset}{incidence}(x, ..., from = min(x$dates), to = max(x$dates), groups = TRUE) 11 | 12 | \method{[}{incidence}(x, i, j) 13 | } 14 | \arguments{ 15 | \item{x}{An incidence object, generated by the function 16 | \code{\link[=incidence]{incidence()}}.} 17 | 18 | \item{...}{Further arguments passed to other methods (not used).} 19 | 20 | \item{from}{The starting date; data strictly before this date are discarded.} 21 | 22 | \item{to}{The ending date; data strictly after this date are discarded.} 23 | 24 | \item{groups}{(optional) The groups to retained, indicated as subsets of the 25 | columns of x$counts.} 26 | 27 | \item{i}{a subset of dates to retain} 28 | 29 | \item{j}{a subset of groups to retain} 30 | } 31 | \description{ 32 | Two functions can be used to subset incidence objects. The function 33 | \code{subset} permits to retain dates within a specified range and, 34 | optionally, specific groups. The operator "[" can be used as for matrices, 35 | using the syntax \code{x[i,j]} where 'i' is a subset of dates, and 'j' is a 36 | subset of groups. 37 | } 38 | \examples{ 39 | ## example using simulated dataset 40 | if(require(outbreaks)) { withAutoprint({ 41 | onset <- ebola_sim$linelist$date_of_onset 42 | 43 | ## weekly incidence 44 | inc <- incidence(onset, interval = 7) 45 | inc 46 | inc[1:10] # first 10 weeks 47 | plot(inc[1:10]) 48 | inc[-c(11:15)] # remove weeks 11-15 49 | plot(inc[-c(11:15)]) 50 | })} 51 | 52 | } 53 | \seealso{ 54 | The \code{\link[=incidence]{incidence()}} function to generate the 'incidence' 55 | objects. 56 | } 57 | \author{ 58 | Thibaut Jombart \email{thibautjombart@gmail.com} 59 | } 60 | -------------------------------------------------------------------------------- /misc/plotly-expl.R: -------------------------------------------------------------------------------- 1 | 2 | ## load libraries 3 | ## if not installed, use install.packages("name of the package") 4 | ## e.g. install.packages("incidence") 5 | 6 | library(outbreaks) 7 | library(incidence) 8 | library(ggplot2) 9 | library(plotly) 10 | 11 | 12 | ## generate incidence object 13 | dat <- ebola.sim$linelist$date.of.onset 14 | i.7.sex <- incidence(dat, interval = 7, 15 | groups = ebola.sim$linelist$gender) 16 | 17 | ## generate best fit 18 | fit <- fit_optim_split(i.7.sex)$fit 19 | 20 | ## generate ggplot object 21 | p <- plot(i.7.sex, fit = fit) 22 | 23 | 24 | ## generate plotly object (used for JS rendering) 25 | p_ly <- ggplotly(p) 26 | 27 | ## to display the plot: print(p_ly) 28 | ## (implicitely called when typing p_ly and return 29 | 30 | ## to display the content: unclass(p_ly) 31 | 32 | ## Wishlist for improving the graph: 33 | 34 | ## - adjust x labels to zoom 35 | ## - modify the text when hovering 36 | ## - modify the legend, e.g. "(f,1)" -> "f" 37 | -------------------------------------------------------------------------------- /tests/figs/deps.txt: -------------------------------------------------------------------------------- 1 | - vdiffr-svg-engine: 1.0 2 | - vdiffr: 0.3.2.2 3 | - freetypeharfbuzz: 0.2.5 4 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(incidence) 3 | 4 | test_check("incidence") 5 | -------------------------------------------------------------------------------- /tests/testthat/data_cache/mfcat.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/data_cache/mfcat.rds -------------------------------------------------------------------------------- /tests/testthat/data_cache/mfdat.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/data_cache/mfdat.rds -------------------------------------------------------------------------------- /tests/testthat/rds/df.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/df.rds -------------------------------------------------------------------------------- /tests/testthat/rds/df2.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/df2.rds -------------------------------------------------------------------------------- /tests/testthat/rds/df3.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/df3.rds -------------------------------------------------------------------------------- /tests/testthat/rds/df5.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/df5.rds -------------------------------------------------------------------------------- /tests/testthat/rds/df6.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/df6.rds -------------------------------------------------------------------------------- /tests/testthat/rds/dfl.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/dfl.rds -------------------------------------------------------------------------------- /tests/testthat/rds/fit.i.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/fit.i.rds -------------------------------------------------------------------------------- /tests/testthat/rds/fit.i.sex.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/fit.i.sex.rds -------------------------------------------------------------------------------- /tests/testthat/rds/incidence.res1.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/incidence.res1.rds -------------------------------------------------------------------------------- /tests/testthat/rds/incidence.res2.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/incidence.res2.rds -------------------------------------------------------------------------------- /tests/testthat/rds/incidence.res3.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/incidence.res3.rds -------------------------------------------------------------------------------- /tests/testthat/rds/incidence.res4.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/incidence.res4.rds -------------------------------------------------------------------------------- /tests/testthat/rds/incidence.res5.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/incidence.res5.rds -------------------------------------------------------------------------------- /tests/testthat/rds/incidence.res6.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/incidence.res6.rds -------------------------------------------------------------------------------- /tests/testthat/rds/incidence.res7.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/incidence.res7.rds -------------------------------------------------------------------------------- /tests/testthat/rds/incidence.res8.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/incidence.res8.rds -------------------------------------------------------------------------------- /tests/testthat/rds/o.fit.i.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/o.fit.i.rds -------------------------------------------------------------------------------- /tests/testthat/rds/o.fit.i.sex.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/o.fit.i.sex.rds -------------------------------------------------------------------------------- /tests/testthat/rds/print.fit.i.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/print.fit.i.rds -------------------------------------------------------------------------------- /tests/testthat/rds/print.fit.sex.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/print.fit.sex.rds -------------------------------------------------------------------------------- /tests/testthat/rds/print1.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/print1.rds -------------------------------------------------------------------------------- /tests/testthat/rds/print2.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/print2.rds -------------------------------------------------------------------------------- /tests/testthat/rds/print3.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/print3.rds -------------------------------------------------------------------------------- /tests/testthat/rds/res.g.1.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/res.g.1.rds -------------------------------------------------------------------------------- /tests/testthat/rds/res.g.2.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/res.g.2.rds -------------------------------------------------------------------------------- /tests/testthat/rds/res.g.3.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/res.g.3.rds -------------------------------------------------------------------------------- /tests/testthat/rds/x.sub1.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/x.sub1.rds -------------------------------------------------------------------------------- /tests/testthat/rds/x.sub2.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/x.sub2.rds -------------------------------------------------------------------------------- /tests/testthat/rds/x.sub3.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/x.sub3.rds -------------------------------------------------------------------------------- /tests/testthat/rds/x.sub4.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/x.sub4.rds -------------------------------------------------------------------------------- /tests/testthat/rds/x.sub5.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/x.sub5.rds -------------------------------------------------------------------------------- /tests/testthat/rds/y.sub1.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/tests/testthat/rds/y.sub1.rds -------------------------------------------------------------------------------- /tests/testthat/test-bootstrap.R: -------------------------------------------------------------------------------- 1 | context("Bootstrapping incidence") 2 | 3 | set.seed(1) 4 | dates <- as.integer(sample(-3:100, 50, replace = TRUE)) 5 | DATES <- as.Date("2016-09-20") + dates 6 | groups <- sample(c("toto", "tata"), 50, replace = TRUE) 7 | 8 | 9 | test_that("Bootstrap needs an incidence object", { 10 | expect_error(bootstrap(DATES), "x is not an incidence object") 11 | }) 12 | 13 | test_that("estimate_peak needs an incidence object", { 14 | expect_error(estimate_peak(DATES), "x is not an incidence object") 15 | }) 16 | 17 | test_that("Bootstrap incidence with groups", { 18 | skip_on_cran() 19 | 20 | x <- incidence(DATES, 3, groups = groups) 21 | y <- bootstrap(x) 22 | z <- bootstrap(x, TRUE) 23 | expect_identical(colSums(x$counts), colSums(y$counts)) 24 | expect_identical(colSums(x$counts), colSums(z$counts)) 25 | expect_identical(colnames(x$counts), colnames(y$counts)) 26 | expect_identical(colnames(x$counts), colnames(z$counts)) 27 | expect_identical(x$interval, y$interval) 28 | expect_identical(x$interval, z$interval) 29 | 30 | }) 31 | 32 | 33 | context("Mountain Climbing") 34 | 35 | test_that("find_peak can find the peak", { 36 | skip_on_cran() 37 | 38 | 39 | x <- incidence(DATES, 3, groups = groups) 40 | 41 | expect_error(find_peak(1:10), "x is not an incidence object") 42 | expect_message(p1 <- find_peak(x), "'x' is stratified by groups\npooling groups before finding peaks") 43 | expect_length(p1, 1L) 44 | expect_named(find_peak(x, pool = FALSE), c("tata", "toto")) 45 | }) 46 | 47 | 48 | test_that("estimate_peak can roughly estimate it", { 49 | x <- incidence(DATES, 3, groups = groups) 50 | y <- incidence(dates, 3) 51 | expect_message(e1 <- estimate_peak(x), "'x' is stratified by groups\npooling groups before finding peaks") 52 | e2 <- estimate_peak(y) 53 | expect_named(e1, c("observed", "estimated", "ci", "peaks")) 54 | expect_named(e2, c("observed", "estimated", "ci", "peaks")) 55 | ## The observed is identical to find_peak 56 | expect_identical(e1$observed, find_peak(pool(x))) 57 | expect_identical(e2$observed, find_peak(pool(y))) 58 | ## The number of peaks defaults to 100 59 | expect_length(e1$peaks, 100) 60 | expect_length(e2$peaks, 100) 61 | ## The observed falls within the confidence interval 62 | expect_gt(as.integer(e1$observed), as.integer(e1$ci[1])) 63 | expect_lt(as.integer(e1$observed), as.integer(e1$ci[2])) 64 | expect_gt(as.integer(e2$observed), as.integer(e2$ci[1])) 65 | expect_lt(as.integer(e2$observed), as.integer(e2$ci[2])) 66 | }) 67 | -------------------------------------------------------------------------------- /tests/testthat/test-cumulate.R: -------------------------------------------------------------------------------- 1 | context("Test cumulate") 2 | 3 | test_that("Results as expected", { 4 | skip_on_cran() 5 | 6 | dat <- as.Date("2016-01-02") + as.integer(c(7,7,7,0,1,2,2,2,3,3,5,7)) 7 | i <- incidence(dat) 8 | 9 | out <- cumulate(i) 10 | expect_identical(cumsum(i$counts), as.vector(out$counts)) 11 | expect_true(out$cumulative) 12 | expect_identical(cumulate(-3:10), cumsum(-3:10)) 13 | expect_error(cumulate(out), "x is already a cumulative incidence") 14 | 15 | }) 16 | -------------------------------------------------------------------------------- /tests/testthat/test-fit.R: -------------------------------------------------------------------------------- 1 | context("Test fit functions") 2 | 3 | test_that("fit", { 4 | skip_on_cran() 5 | 6 | dat <- readRDS("data_cache/mfdat.rds") 7 | sex <- readRDS("data_cache/mfcat.rds") 8 | 9 | i <- incidence(dat, 5L) 10 | i.sex <- incidence(dat, 5L, groups = sex) 11 | fit.i <- fit(i) 12 | expect_warning(fit.i.sex <- fit(i.sex), 13 | "3 dates with incidence of 0 ignored for fitting") 14 | 15 | expect_equal_to_reference(fit.i, file = "rds/fit.i.rds") 16 | expect_equal_to_reference(fit.i.sex, file = "rds/fit.i.sex.rds") 17 | expect_equal_to_reference(capture.output(fit.i), file = "rds/print.fit.i.rds") 18 | expect_equal_to_reference(capture.output(fit.i.sex), file = "rds/print.fit.sex.rds") 19 | 20 | ## errors 21 | x <- incidence(c(1, 0, 0, 0), interval = 7) 22 | expect_error(fit(x), "Only 1 date with non-zero incidence. Cannot fit model to 1 data point.") 23 | }) 24 | 25 | test_that("fit_optim_split", { 26 | skip_on_cran() 27 | 28 | dat <- readRDS("data_cache/mfdat.rds") 29 | sex <- readRDS("data_cache/mfcat.rds") 30 | 31 | i <- incidence(dat, 5L) 32 | i.sex <- incidence(dat, 5L, groups = sex) 33 | i.fit <- fit_optim_split(i, plot = FALSE) 34 | i.fit.sex <- fit_optim_split(i.sex, plot = FALSE) 35 | expect_equal_to_reference(i.fit, 36 | file = "rds/o.fit.i.rds") 37 | expect_equal_to_reference(i.fit.sex, 38 | file = "rds/o.fit.i.sex.rds") 39 | 40 | expect_is(i.fit$df, "data.frame") 41 | expect_is(i.fit$fit, "incidence_fit_list") 42 | 43 | expect_is(i.fit.sex$df, "data.frame") 44 | expect_is(i.fit.sex$fit, "incidence_fit_list") 45 | 46 | expect_output(print(i.fit.sex$fit), "") 47 | expect_output(print(i.fit.sex$fit), "[^N][^A]") 48 | expect_true(any(is.na(get_info(i.fit.sex$fit, "halving", na.rm = FALSE)))) 49 | 50 | ## errors 51 | expect_error(fit_optim_split(i, window = -1), 52 | "No date left to try after defining splits to try.") 53 | }) 54 | 55 | test_that("internals for fitting", { 56 | skip_on_cran() 57 | 58 | expect_null(extract_info(NULL)) 59 | }) 60 | 61 | test_that("fitting results are the same for incidence fits on Dates and POSIXct", { 62 | days <- 1:14 63 | dat_cases <- round(exp(.2*(days))) 64 | dat_dates_Date <- rep(as.Date(Sys.Date() + days), dat_cases) 65 | dat_dates_POSIXct <- as.POSIXct(dat_dates_Date) 66 | 67 | iD <- incidence(dat_dates_Date) 68 | iP <- incidence(dat_dates_POSIXct) 69 | 70 | expect_equal(fit(iP), fit(iD)) 71 | }) 72 | -------------------------------------------------------------------------------- /tests/testthat/test-non-exported.R: -------------------------------------------------------------------------------- 1 | context("Non-exported functions") 2 | 3 | test_that("check_dates works", { 4 | msg <- "NA detected in the dates" 5 | expect_error(check_dates(c(1,2,NA), TRUE), msg) 6 | 7 | msg <- paste0("Flooring from non-integer date caused approximations:\n", 8 | "Mean relative difference: 0.1") 9 | expect_warning(check_dates(1.1), msg) 10 | 11 | msg <- paste0("Input could not be converted to date. Accepted formats are:\n", 12 | "Date, POSIXct, integer, numeric") 13 | expect_error(check_dates(factor("2001-01-01")), msg) 14 | 15 | x <- list(1L, 16 | as.POSIXct("2001-01-01"), 17 | as.Date("2001-01-01") + 1:10, 18 | 1.0, 19 | 100:1) 20 | for (e in x) { 21 | expect_equal(e, check_dates(e)) 22 | } 23 | }) 24 | 25 | test_that("check_interval", { 26 | skip_on_cran() 27 | 28 | expect_error(check_interval(), 29 | "Interval is missing or NULL") 30 | expect_error(check_interval(NULL), 31 | "Interval is missing or NULL") 32 | expect_error(check_interval(1:2), 33 | "Exactly one value should be provided as interval \\(2 provided\\)") 34 | expect_error(check_interval(integer(0)), 35 | "Exactly one value should be provided as interval \\(0 provided\\)") 36 | expect_error(check_interval(NA), 37 | "Interval is not finite") 38 | expect_error(check_interval(-Inf), 39 | "Interval is not finite") 40 | expect_error(check_interval(.1), 41 | "Interval must be at least 1 \\(input: 0.100; after rounding: 0\\)") 42 | expect_equal(check_interval(1), 1) 43 | expect_equal(check_interval(2.4), 2) 44 | expect_equal(check_interval(2.7), 3) 45 | }) 46 | 47 | test_that("check_groups", { 48 | skip_on_cran() 49 | 50 | expect_is(check_groups(1, 1, FALSE), "factor") 51 | expect_error(check_groups(1, 1:2, FALSE), 52 | "'x' does not have the same length as dates \\(1 vs 2\\)") 53 | expect_equal(check_groups(NULL, NULL, FALSE), NULL) 54 | expect_equal(check_groups(c(1, 1, 2, NA, 2), 1:5, na_as_group = FALSE), 55 | factor(c(1, 1, 2, NA, 2))) 56 | expect_equal(check_groups(c(1,1,2,NA,2), 1:5, na_as_group = TRUE), 57 | factor(c(1, 1, 2, "NA", 2))) 58 | }) 59 | 60 | 61 | -------------------------------------------------------------------------------- /tests/testthat/test-palettes.R: -------------------------------------------------------------------------------- 1 | context("Color palettes") 2 | 3 | test_that("incidence_pal1", { 4 | skip_on_cran() 5 | 6 | expect_error(incidence_pal1(NULL), "n is not a number") 7 | for (n in 1:30) { 8 | expect_length(incidence_pal1(n), n) 9 | } 10 | }) 11 | 12 | test_that("incidence_pal1_light", { 13 | skip_on_cran() 14 | 15 | expect_error(incidence_pal1_light(NULL), "n is not a number") 16 | for (n in 1:30) { 17 | expect_length(incidence_pal1_light(n), n) 18 | } 19 | }) 20 | 21 | 22 | 23 | test_that("incidence_pal1_dark", { 24 | skip_on_cran() 25 | 26 | expect_error(incidence_pal1_dark(NULL), "n is not a number") 27 | for (n in 1:30) { 28 | expect_length(incidence_pal1_dark(n), n) 29 | } 30 | }) 31 | -------------------------------------------------------------------------------- /tests/testthat/test-pool.R: -------------------------------------------------------------------------------- 1 | context("Pool") 2 | 3 | test_that("Pool works", { 4 | skip_on_cran() 5 | 6 | expect_error(pool(1), 7 | "x should be an 'incidence' object \\(its class is: numeric\\)") 8 | expect_identical(incidence(1L), pool(incidence(1L))) 9 | 10 | dat <- as.integer(c(0, 1, 2, 2, 3, 5, 7)) 11 | fac <- factor(c(1, 2, 3, 3, 3, 3, 1)) 12 | expect_identical(pool(incidence(dat, groups = fac)), incidence(dat)) 13 | }) 14 | -------------------------------------------------------------------------------- /tests/testthat/test-standards.R: -------------------------------------------------------------------------------- 1 | context("standardisation tests") 2 | 3 | 4 | d <- c('2019-04-18', '2019-04-14', '2019-03-31', '2019-04-03', '2019-03-30', 5 | '2019-04-05', '2019-03-12', '2019-04-07', '2019-04-02', '2019-03-09', 6 | '2019-04-20', '2019-04-23', '2019-03-07', '2019-03-25', '2019-03-27', 7 | '2019-04-13', '2019-04-15', '2019-04-04', '2019-03-30', '2019-03-19') 8 | 9 | test_that("standard will override first_date", { 10 | 11 | expect_output(print(incidence(d, interval = "week", standard = TRUE)), "2019-03-04") 12 | expect_output(print(incidence(d, interval = "week", standard = TRUE)), "2019-W10") 13 | expect_output(print(incidence(d, interval = "isoweek", standard = TRUE)), "2019-W10") 14 | expect_output(print(incidence(d, interval = "1 isoweek", standard = TRUE)), "2019-W10") 15 | expect_output(print(incidence(d, interval = "monday week", standard = TRUE)), "2019-W10") 16 | expect_output(print(incidence(d, interval = "week", standard = FALSE)), "2019-03-07") 17 | expect_error(incidence(d, interval = "isoweek", standard = FALSE), 18 | "The interval 'isoweek' implies a standard and cannot be used with `standard = FALSE`") 19 | 20 | expect_error(incidence(d, interval = "monday week", standard = FALSE), 21 | "The interval 'monday week' implies a standard and cannot be used with `standard = FALSE`") 22 | expect_output(print(incidence(d, interval = "month", standard = TRUE)), "2019-03-01") 23 | expect_output(print(incidence(d, interval = "month", standard = FALSE)), "2019-03-07") 24 | 25 | expect_output(print(incidence(d, interval = "year", standard = TRUE)), "2019-01-01") 26 | expect_output(print(incidence(d, interval = "year", standard = FALSE)), "2019-03-07") 27 | 28 | }) 29 | -------------------------------------------------------------------------------- /tests/testthat/test-subset.R: -------------------------------------------------------------------------------- 1 | context("Subset of incidence objects") 2 | 3 | test_that("[ operator for incidence objects", { 4 | skip_on_cran() 5 | 6 | dat <- c(1L, 8L, 2L, 9L, 10L, -3L, 4L, 9L, 4L, 3L, 10L, 3L, 6L, 5L, -2L, 9L, 7 | 0L, -3L, 1L, 10L, 9L, 6L, 5L, 10L, 6L, 6L, 4L, 5L, 1L, -1L, 10L, 9L, 8 | 6L, 8L, -3L, 3L, 7L, 0L, 1L, 0L, -2L, 2L, 2L, 2L, -1L, -2L, 0L, 3L, 9 | 0L, 9L) 10 | # set.seed(123) 11 | # dat <- as.integer(sample(-3:10, 50, replace = TRUE)) 12 | x <- incidence(dat) 13 | y <- incidence(dat + as.Date("2016-01-12"), 7L) 14 | 15 | z <- incidence(dat + as.Date("2016-01-12"), "epiweek") 16 | s <- incidence(dat + as.Date("2016-01-12"), "sunday week") 17 | m <- incidence(dat + as.Date("2016-01-12"), "MMWR week") 18 | 19 | # epiweeks and MMWR weeks start on Sunday 20 | expect_identical(z[1:2], s[1:2]) 21 | expect_identical(z[], m[]) 22 | 23 | x.sub1 <- x[c(3,5,7,8)] 24 | expect_equal_to_reference(x.sub1, file = "rds/x.sub1.rds") 25 | 26 | x.sub2 <- x[-c(5,1,2)] 27 | expect_equal_to_reference(x.sub2, file = "rds/x.sub2.rds") 28 | 29 | expect_equal(y[1:2]$weeks, y$weeks[1:2]) 30 | expect_equal(z[1:2]$weeks, z$weeks[1:2]) 31 | 32 | y.sub1 <- y[1:2] 33 | expect_equal_to_reference(y.sub1, file = "rds/y.sub1.rds") 34 | }) 35 | 36 | 37 | 38 | 39 | test_that("subset for incidence objects", { 40 | skip_on_cran() 41 | 42 | dat <- c(1L, 8L, 2L, 9L, 10L, -3L, 4L, 9L, 4L, 3L, 10L, 3L, 6L, 5L, -2L, 9L, 43 | 0L, -3L, 1L, 10L, 9L, 6L, 5L, 10L, 6L, 6L, 4L, 5L, 1L, -1L, 10L, 9L, 44 | 6L, 8L, -3L, 3L, 7L, 0L, 1L, 0L, -2L, 2L, 2L, 2L, -1L, -2L, 0L, 3L, 45 | 0L, 9L) 46 | # set.seed(123) 47 | # dat <- as.integer(sample(-3:10, 50, replace = TRUE)) 48 | x <- incidence(dat) 49 | 50 | x.sub3 <- subset(x, from = 0) 51 | expect_equal_to_reference(x.sub3, file = "rds/x.sub3.rds") 52 | 53 | x.sub4 <- subset(x, to = 5) 54 | expect_equal_to_reference(x.sub4, file = "rds/x.sub4.rds") 55 | 56 | x.sub5 <- subset(x, from = 1, to = 4) 57 | expect_equal_to_reference(x.sub5, file = "rds/x.sub5.rds") 58 | 59 | ## round trip 60 | expect_identical(x, x[]) 61 | 62 | ## corner cases 63 | expect_error(subset(x, from = 19), "No data retained.") 64 | expect_error(subset(x, to = -2319), "No data retained.") 65 | expect_error(subset(x, from = Inf, to = -2319), "No data retained.") 66 | }) 67 | 68 | test_that("numeric subset works with dates ", { 69 | skip_on_cran() 70 | 71 | x <- incidence(as.Date("2001-01-01") + 1:10, 2L) 72 | 73 | expect_equal(subset(x, from = 1, to = 2)$dates, 74 | x$dates[1:2]) 75 | 76 | expect_equal(subset(x, from = -10, to = 2)$dates, 77 | x$dates[1:2]) 78 | 79 | expect_equal(as.data.frame(subset(x, from = 0, to = 1e3)), 80 | as.data.frame(x)) 81 | expect_identical(x, x[]) 82 | }) 83 | 84 | 85 | test_that("numeric subset works with dates and character strings", { 86 | x <- incidence(as.Date("2001-01-01") + 1:100, "month") 87 | 88 | expect_equal(subset(x, from = 1, to = -1)$dates, 89 | x$dates[1]) 90 | 91 | expect_equal(subset(x, from = 1, to = 2)$dates, 92 | x$dates[1:2]) 93 | 94 | expect_equal(subset(x, from = -10, to = 2)$dates, 95 | x$dates[1:2]) 96 | 97 | 98 | expect_equal(subset(x, from = 5, to = 5)$dates, 99 | x$dates[4]) 100 | 101 | expect_equal(as.data.frame(subset(x, from = 0, to = 1e3)), 102 | as.data.frame(x)) 103 | expect_identical(x, x[]) 104 | }) 105 | 106 | test_that("an erroneous group will give a sensible error", { 107 | i <- incidence(sample(1:10, 100, replace = TRUE), groups = rep(c("a", "b"), length.out = 100)) 108 | expect_error(i[, "c"], "The following group does not exist: 'c'") 109 | expect_error(i[, c("grind", "core")], "The following groups do not exist: 'grind', 'core'") 110 | }) 111 | -------------------------------------------------------------------------------- /vignettes/conversions.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Conversions to and from the incidence class" 3 | author: "Thibaut Jombart, Zhian N. Kamvar" 4 | date: "`r Sys.Date()`" 5 | output: 6 | rmarkdown::html_vignette: 7 | toc: true 8 | toc_depth: 2 9 | vignette: > 10 | %\VignetteIndexEntry{Conversions} 11 | %\VignetteEngine{knitr::rmarkdown} 12 | %\VignetteEncoding{UTF-8} 13 | --- 14 | 15 | 16 | 17 | ```{r, echo = FALSE} 18 | knitr::opts_chunk$set( 19 | collapse = TRUE, 20 | comment = "#>", 21 | fig.width=7, 22 | fig.height=5 23 | ) 24 | ``` 25 | 26 | 27 | This vignette documents to types of conversion which can be made using the *incidence* class: 28 | 29 | - *'exports'*: conversion from an *incidence* object to another type of object; 30 | this can be useful for processing incidence data in another software, or for 31 | reporting results. 32 | 33 | - *'imports'*conversion from already computed incidence into an *incidence* 34 | object; this can be useful for using features of the *incidence* package for 35 | data handling and plotting with incidence data computed elsewhere. 36 | 37 | 38 | 39 |
    40 | 41 | # Exporting results 42 | 43 | To export results, we first compute semi-weekly incidence (with weeks starting 44 | on Sunday, the beginning of the CDC epiweek) by gender from the simulated Ebola 45 | data used in the [overview 46 | vignette](https://www.repidemicsconsortium.org/incidence/articles/overview.html): 47 | 48 | ```{r example} 49 | library(outbreaks) 50 | library(incidence) 51 | dat <- ebola_sim$linelist$date_of_onset 52 | i_14 <- incidence(dat, interval = "2 epiweeks", groups = ebola_sim$linelist$gender) 53 | i_14 54 | plot(i_14, border = "white") 55 | ``` 56 | 57 | To export the data to a `data.frame`, one simply needs: 58 | 59 | ```{r} 60 | as.data.frame(i_14) 61 | ``` 62 | 63 | The first column contains the dates marking the (inclusive) left side of the 64 | time intervals used for computing incidence, and the other columns give counts 65 | for the different groups. This function also has an option for exporting data as 66 | a 'long' format, i.e. with a column for 'groups' and a column for counts. This 67 | format can be useful especially when working with *ggplot2*, which expect data 68 | in this shape: 69 | 70 | ```{r, long} 71 | df <- as.data.frame(i_14, long = TRUE) 72 | head(df) 73 | tail(df) 74 | 75 | ## example of custom plot using steps: 76 | library(ggplot2) 77 | ggplot(df, aes(x = dates, y = counts)) + geom_step(aes(color = groups)) 78 | ``` 79 | 80 | 81 | Finally, note that when ISO weeks are used, these are also reported in the output: 82 | 83 | ```{r, iso} 84 | i_7 <- incidence(dat, interval = "week") 85 | i_7 86 | plot(i_7, border = "white") 87 | head(as.data.frame(i_7)) 88 | tail(as.data.frame(i_7)) 89 | 90 | ``` 91 | 92 | 93 | 94 | 95 |
    96 | 97 | # Importing pre-computed incidence 98 | 99 | The function `as.incidence` facilitates the conversion of pre-computed 100 | incidences to an *incidence* object. Typically, the input will be imported into 101 | R from a *.csv* file or other spreadsheet formats. 102 | 103 | 104 | `as.incidence` is a generic with methods for several types of objects (see 105 | `?as.incidence`). The main method is `matrix`, as other types are coerced to 106 | `matrix` first and then passed to `as.incidence.matrix`: 107 | 108 | ```{r, conversions} 109 | args(incidence:::as.incidence.matrix) 110 | ``` 111 | 112 | The only mandatory argument `x` is a table of counts, with time intervals in 113 | rows and groups in columns; if there are no groups, then the column doesn't need 114 | a name; but if there are several groups, then columns should be named to 115 | indicate group labels. Optionally, `dates` can be provided to indicate the 116 | (inclusive) lower bounds of the time intervals, corresponding to the rows of 117 | `x`; most sensible date formats will do; if indicated as a character string, 118 | make sure the format is `YYYY-mm-dd`, e.g. `2017-04-01` for the 1st April 2017. 119 | 120 | 121 | Let us illustrate the conversion using a simple vector of incidence: 122 | ```{r} 123 | vec <- c(1,2,3,0,3,2,4,1,2,1) 124 | 125 | i <- as.incidence(vec) 126 | i 127 | 128 | plot(vec, type = "s") 129 | plot(i, border = "white") 130 | 131 | ``` 132 | 133 | Assuming the above incidences are computed weekly, we would then use: 134 | ```{r} 135 | i <- as.incidence(vec, interval = 7) 136 | i 137 | plot(i, border = "white") 138 | 139 | ``` 140 | 141 | Note that in this case, incidences have been treated as per week, and 142 | corresponding dates in days have been computed during the conversion (the first 143 | day is always '1'), so that the first days of weeks 1, 2, 3... are: 144 | ```{r} 145 | i$dates 146 | ``` 147 | 148 | In practice, it is best to provide the actual dates marking the lower bounds of 149 | the time intervals. We can illustrate this by a round trip using the example of 150 | the previous section: 151 | 152 | ```{r, round_trip} 153 | ## convertion: incidence --> data.frame: 154 | i_14 155 | df <- as.data.frame(i_14) 156 | head(df) 157 | tail(df) 158 | 159 | ## conversion: data.frame --> incidence 160 | new_i <- as.incidence(df[group_names(i_14)], df$dates, interval = "2 epiweeks") 161 | new_i 162 | 163 | ## check round trip 164 | identical(new_i, i_14) 165 | 166 | ``` 167 | 168 | 169 | -------------------------------------------------------------------------------- /vignettes/figs-class/i-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-class/i-1.png -------------------------------------------------------------------------------- /vignettes/figs-class/sex-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-class/sex-1.png -------------------------------------------------------------------------------- /vignettes/figs-conversion/example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-conversion/example-1.png -------------------------------------------------------------------------------- /vignettes/figs-conversion/iso-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-conversion/iso-1.png -------------------------------------------------------------------------------- /vignettes/figs-conversion/long-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-conversion/long-1.png -------------------------------------------------------------------------------- /vignettes/figs-conversion/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-conversion/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /vignettes/figs-conversion/unnamed-chunk-3-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-conversion/unnamed-chunk-3-2.png -------------------------------------------------------------------------------- /vignettes/figs-conversion/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-conversion/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/colors1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/colors1-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/colors2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/colors2-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/colors3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/colors3-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/default-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/default-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/default-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/default-2.png -------------------------------------------------------------------------------- /vignettes/figs-custom/default-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/default-3.png -------------------------------------------------------------------------------- /vignettes/figs-custom/grid1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/grid1-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/grid2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/grid2-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/incidence_pal1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/incidence_pal1-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/legend1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/legend1-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/pal1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/pal1-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/pal2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/pal2-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/palettes-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/palettes-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/palettes-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/palettes-2.png -------------------------------------------------------------------------------- /vignettes/figs-custom/scales1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/scales1-1.png -------------------------------------------------------------------------------- /vignettes/figs-custom/scales2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-custom/scales2-1.png -------------------------------------------------------------------------------- /vignettes/figs-fit/combine-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-fit/combine-1.png -------------------------------------------------------------------------------- /vignettes/figs-fit/fit_dates-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-fit/fit_dates-1.png -------------------------------------------------------------------------------- /vignettes/figs-fit/fit_gender-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-fit/fit_gender-1.png -------------------------------------------------------------------------------- /vignettes/figs-fit/incidence_by_gender-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-fit/incidence_by_gender-1.png -------------------------------------------------------------------------------- /vignettes/figs-fit/incidence_fit_list-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-fit/incidence_fit_list-1.png -------------------------------------------------------------------------------- /vignettes/figs-fit/list_stuff-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-fit/list_stuff-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/fit.both-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/fit.both-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/fit1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/fit1-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/gender-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/gender-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/groupsub-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/groupsub-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/hosp-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/hosp-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/i7outcome-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/i7outcome-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/incid1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/incid1-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/interv-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/interv-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/interv-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/interv-2.png -------------------------------------------------------------------------------- /vignettes/figs-overview/interv-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/interv-3.png -------------------------------------------------------------------------------- /vignettes/figs-overview/middle-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/middle-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/optim-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/optim-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/optim-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/optim-2.png -------------------------------------------------------------------------------- /vignettes/figs-overview/optim2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/optim2-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/optim2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/optim2-2.png -------------------------------------------------------------------------------- /vignettes/figs-overview/stripes-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/stripes-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/tail-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/tail-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/unnamed-chunk-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/unnamed-chunk-2-1.png -------------------------------------------------------------------------------- /vignettes/figs-overview/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reconhub/incidence/42212a2ce0a63ada19d1d4d471bd93055d1a8876/vignettes/figs-overview/unnamed-chunk-3-1.png --------------------------------------------------------------------------------