├── .Rbuildignore ├── docs ├── logo.png ├── favicon.ico ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── extra.css ├── reference │ ├── Rplot001.png │ ├── Rplot002.png │ ├── Rplot003.png │ ├── figures │ │ ├── logo.png │ │ ├── daily_cases-1.png │ │ ├── variant_tracker-1.png │ │ ├── location_tracker-1.png │ │ ├── resources_by_date-1.png │ │ └── lineage_comparison-1.png │ ├── plotCovid-1.png │ ├── plotEpiData-1.png │ ├── plotPrevalenceOverTime-1.png │ ├── plotPrevalenceOverTime-2.png │ ├── plotPrevalenceOverTime-3.png │ ├── plotAllLineagesByLocation-1.png │ ├── plotPrevalenceByLocation-1.png │ └── plotPrevalenceByLocation-2.png ├── apple-touch-icon-60x60.png ├── apple-touch-icon-76x76.png ├── apple-touch-icon-120x120.png ├── apple-touch-icon-152x152.png ├── apple-touch-icon-180x180.png ├── articles │ ├── outbreakinfo_files │ │ ├── figure-html │ │ │ ├── epi-1.png │ │ │ ├── prev-time-1.png │ │ │ ├── unnamed-chunk-1-1.png │ │ │ ├── unnamed-chunk-1-2.png │ │ │ └── characteristic_mutations-1.png │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ └── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ ├── varianttracker_files │ │ ├── figure-html │ │ │ ├── p1-1.png │ │ │ ├── p1_comparison-1.png │ │ │ ├── p1_comparison-2.png │ │ │ ├── mutation_queries-1.png │ │ │ ├── unnamed-chunk-1-1.png │ │ │ ├── unnamed-chunk-2-1.png │ │ │ ├── world_choropleth-1.png │ │ │ ├── all_gamma_mutations-1.png │ │ │ └── characteristic_mutations-1.png │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ └── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ ├── locationtracker_files │ │ ├── figure-html │ │ │ ├── pressure-1.png │ │ │ ├── custom_variants-1.png │ │ │ ├── variant_overlay-1.png │ │ │ ├── variant_overlay-2.png │ │ │ ├── cum_prev_by_state-1.png │ │ │ ├── cum_prev_by_state-2.png │ │ │ ├── location_overlay-1.png │ │ │ ├── mutation_heatmap-1.png │ │ │ ├── all_lineages_streamgraph-1.png │ │ │ └── all_lineages_streamgraph_overload-1.png │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ └── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ ├── epivignette_files │ │ ├── figure-html │ │ │ └── unnamed-chunk-25-1.png │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ └── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ ├── researchlibrary_files │ │ ├── figure-html │ │ │ ├── unnamed-chunk-1-1.png │ │ │ ├── unnamed-chunk-1-2.png │ │ │ ├── resources_by_date-1.png │ │ │ └── resources_by_type_source-1.png │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ └── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ └── index.html ├── pkgdown.yml ├── link.svg ├── lineagevignette.Rmd ├── bootstrap-toc.css ├── docsearch.js ├── locationvignette.Rmd ├── pkgdown.js ├── bootstrap-toc.js ├── LICENSE-text.html └── 404.html ├── tests ├── testthat.R └── testthat │ ├── test-plotCovid.R │ ├── test-getISO3.R │ └── test-searchLocations.R ├── man ├── daily_cases-1.png ├── figures │ ├── logo.png │ ├── daily_cases-1.png │ ├── location_tracker-1.png │ ├── variant_tracker-1.png │ ├── lineage_comparison-1.png │ └── resources_by_date-1.png ├── getGenomicsResponse.Rd ├── getAdmn0.Rd ├── authenticateUser.Rd ├── epidemiologyDataDictionary.Rd ├── getMutationDetails.Rd ├── getMetroByCountry.Rd ├── genomicsDataDictionary.Rd ├── getLag.Rd ├── getAdmn2ByCountry.Rd ├── getAdmn2ByState.Rd ├── getLocationData.Rd ├── getAdmn1ByCountry.Rd ├── getLocationIdGenomic.Rd ├── getCountryByRegion.Rd ├── getISO3.Rd ├── plotEpiData.Rd ├── getByAdmnLevel.Rd ├── getMutationAcrossLineage.Rd ├── getCuratedLineages.Rd ├── getMutationsByLineage.Rd ├── getGlobalPrevalence.Rd ├── getCollectionDateByLocation.Rd ├── getGenomicData.Rd ├── searchLocations.Rd ├── getSubmissionDateByLocation.Rd ├── plotMutationHeatmap.Rd ├── plotChoropleth.Rd ├── getSeqCounts.Rd ├── plotPrevalenceDotPlot.Rd ├── getCumulativeBySubadmin.Rd ├── getEpiData.Rd ├── lookupSublineages.Rd ├── getAllLineagesByLocation.Rd ├── plotAllLineagesByLocation.Rd ├── plotPrevalenceOverTime.Rd ├── getResourcesResponse.Rd ├── getPrevalence.Rd └── getResourcesData.Rd ├── pkgdown ├── extra.css └── favicon │ ├── favicon.ico │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── apple-touch-icon.png │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ └── apple-touch-icon-76x76.png ├── .gitignore ├── R ├── getAdmn0.R ├── getMutationDetails.R ├── zzz.R ├── getMetroByCountry.R ├── getAdmn2ByCountry.R ├── getLocationData.R ├── setAuthToken.R ├── getByAdmnLevel.R ├── getAdmn2ByState.R ├── getAuthToken.R ├── getAdmn1ByCountry.R ├── getCountryByRegion.R ├── getMutationAcrossLineage.R ├── getLag.R ├── getCollectionDateByLocation.R ├── getGlobalPrevalence.R ├── getSubmissionDateByLocation.R ├── getSeqCounts.R ├── getCumulativeBySubadmin.R ├── getMutationsByLineage.R ├── getCuratedLineages.R ├── getAllLineagesByLocation.R ├── genomicsDataDictionary.R ├── plotChoropleth.R ├── plotPrevalenceDotPlot.R ├── getResourcesData.R ├── plotPrevalenceOverTime.R ├── plotMutationHeatmap.R ├── lookupSublineages.R ├── plotAllLineagesByLocation.R ├── getPrevalence.R ├── getGenomicData.R ├── epidemiologyDataDictionary.R ├── getLocationIdGenomic.R ├── plotEpiData.R ├── authenticateUser.R ├── getGenomicsResponse.R ├── getEpiData.R ├── searchLocations.R ├── getISO3.R └── getResourcesResponse.R ├── pkgdown_build.R ├── LICENSE.md ├── .github └── workflows │ ├── pkgdown.yml │ └── testing-r-versions.yml ├── DESCRIPTION ├── NAMESPACE ├── _pkgdown.yml └── outbreakinfo └── R └── getGenomicsResponse.R~ /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^LICENSE\.md$ 4 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/logo.png -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(outbreakinfo) 3 | 4 | test_check("outbreakinfo") 5 | -------------------------------------------------------------------------------- /man/daily_cases-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/man/daily_cases-1.png -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/man/figures/logo.png -------------------------------------------------------------------------------- /docs/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/favicon-16x16.png -------------------------------------------------------------------------------- /docs/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/favicon-32x32.png -------------------------------------------------------------------------------- /docs/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/extra.css: -------------------------------------------------------------------------------- 1 | .contents h2 { 2 | margin-top: 0; 3 | } 4 | 5 | .contents h3 { 6 | color: #126B93 !important; 7 | } -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/Rplot002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/Rplot002.png -------------------------------------------------------------------------------- /docs/reference/Rplot003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/Rplot003.png -------------------------------------------------------------------------------- /man/figures/daily_cases-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/man/figures/daily_cases-1.png -------------------------------------------------------------------------------- /pkgdown/extra.css: -------------------------------------------------------------------------------- 1 | .contents h2 { 2 | margin-top: 0; 3 | } 4 | 5 | .contents h3 { 6 | color: #126B93 !important; 7 | } -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /docs/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /docs/reference/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/figures/logo.png -------------------------------------------------------------------------------- /docs/reference/plotCovid-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/plotCovid-1.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /docs/reference/plotEpiData-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/plotEpiData-1.png -------------------------------------------------------------------------------- /man/figures/location_tracker-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/man/figures/location_tracker-1.png -------------------------------------------------------------------------------- /man/figures/variant_tracker-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/man/figures/variant_tracker-1.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /man/figures/lineage_comparison-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/man/figures/lineage_comparison-1.png -------------------------------------------------------------------------------- /man/figures/resources_by_date-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/man/figures/resources_by_date-1.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/reference/figures/daily_cases-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/figures/daily_cases-1.png -------------------------------------------------------------------------------- /docs/reference/figures/variant_tracker-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/figures/variant_tracker-1.png -------------------------------------------------------------------------------- /docs/reference/plotPrevalenceOverTime-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/plotPrevalenceOverTime-1.png -------------------------------------------------------------------------------- /docs/reference/plotPrevalenceOverTime-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/plotPrevalenceOverTime-2.png -------------------------------------------------------------------------------- /docs/reference/plotPrevalenceOverTime-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/plotPrevalenceOverTime-3.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /docs/reference/figures/location_tracker-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/figures/location_tracker-1.png -------------------------------------------------------------------------------- /docs/reference/figures/resources_by_date-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/figures/resources_by_date-1.png -------------------------------------------------------------------------------- /docs/reference/plotAllLineagesByLocation-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/plotAllLineagesByLocation-1.png -------------------------------------------------------------------------------- /docs/reference/plotPrevalenceByLocation-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/plotPrevalenceByLocation-1.png -------------------------------------------------------------------------------- /docs/reference/plotPrevalenceByLocation-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/plotPrevalenceByLocation-2.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.RData 2 | **/.Rhistory 3 | **/.Rproj.user 4 | **/*.Rproj 5 | .DS_Store 6 | .Rproj.user 7 | data/* 8 | *~ 9 | .R_outbreak-info-token 10 | -------------------------------------------------------------------------------- /docs/reference/figures/lineage_comparison-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/reference/figures/lineage_comparison-1.png -------------------------------------------------------------------------------- /docs/articles/outbreakinfo_files/figure-html/epi-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/outbreakinfo_files/figure-html/epi-1.png -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/figure-html/p1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/varianttracker_files/figure-html/p1-1.png -------------------------------------------------------------------------------- /docs/articles/outbreakinfo_files/figure-html/prev-time-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/outbreakinfo_files/figure-html/prev-time-1.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/pressure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/pressure-1.png -------------------------------------------------------------------------------- /docs/articles/epivignette_files/figure-html/unnamed-chunk-25-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/epivignette_files/figure-html/unnamed-chunk-25-1.png -------------------------------------------------------------------------------- /docs/articles/outbreakinfo_files/figure-html/unnamed-chunk-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/outbreakinfo_files/figure-html/unnamed-chunk-1-1.png -------------------------------------------------------------------------------- /docs/articles/outbreakinfo_files/figure-html/unnamed-chunk-1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/outbreakinfo_files/figure-html/unnamed-chunk-1-2.png -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/figure-html/p1_comparison-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/varianttracker_files/figure-html/p1_comparison-1.png -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/figure-html/p1_comparison-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/varianttracker_files/figure-html/p1_comparison-2.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/custom_variants-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/custom_variants-1.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/variant_overlay-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/variant_overlay-1.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/variant_overlay-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/variant_overlay-2.png -------------------------------------------------------------------------------- /docs/articles/researchlibrary_files/figure-html/unnamed-chunk-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/researchlibrary_files/figure-html/unnamed-chunk-1-1.png -------------------------------------------------------------------------------- /docs/articles/researchlibrary_files/figure-html/unnamed-chunk-1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/researchlibrary_files/figure-html/unnamed-chunk-1-2.png -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/figure-html/mutation_queries-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/varianttracker_files/figure-html/mutation_queries-1.png -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/figure-html/unnamed-chunk-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/varianttracker_files/figure-html/unnamed-chunk-1-1.png -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/figure-html/unnamed-chunk-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/varianttracker_files/figure-html/unnamed-chunk-2-1.png -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/figure-html/world_choropleth-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/varianttracker_files/figure-html/world_choropleth-1.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/cum_prev_by_state-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/cum_prev_by_state-1.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/cum_prev_by_state-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/cum_prev_by_state-2.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/location_overlay-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/location_overlay-1.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/mutation_heatmap-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/mutation_heatmap-1.png -------------------------------------------------------------------------------- /docs/articles/researchlibrary_files/figure-html/resources_by_date-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/researchlibrary_files/figure-html/resources_by_date-1.png -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/figure-html/all_gamma_mutations-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/varianttracker_files/figure-html/all_gamma_mutations-1.png -------------------------------------------------------------------------------- /docs/articles/outbreakinfo_files/figure-html/characteristic_mutations-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/outbreakinfo_files/figure-html/characteristic_mutations-1.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/all_lineages_streamgraph-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/all_lineages_streamgraph-1.png -------------------------------------------------------------------------------- /docs/articles/researchlibrary_files/figure-html/resources_by_type_source-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/researchlibrary_files/figure-html/resources_by_type_source-1.png -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/figure-html/characteristic_mutations-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/varianttracker_files/figure-html/characteristic_mutations-1.png -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/figure-html/all_lineages_streamgraph_overload-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outbreak-info/R-outbreak-info/HEAD/docs/articles/locationtracker_files/figure-html/all_lineages_streamgraph_overload-1.png -------------------------------------------------------------------------------- /docs/articles/epivignette_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/outbreakinfo_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/researchlibrary_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 2.17.1.1 2 | pkgdown: 2.0.5 3 | pkgdown_sha: ~ 4 | articles: 5 | epivignette: epivignette.html 6 | locationtracker: locationtracker.html 7 | outbreakinfo: outbreakinfo.html 8 | researchlibrary: researchlibrary.html 9 | varianttracker: varianttracker.html 10 | last_built: 2022-06-24T16:19Z 11 | 12 | -------------------------------------------------------------------------------- /R/getAdmn0.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve COVID-19 data for all countries 2 | #' 3 | #' @description Retrieve up-to-date COVID-19 data from outbreak.info for all countries 4 | #' 5 | #' @return dataframe 6 | #' 7 | #' @examples 8 | #' \dontrun{ 9 | #' getAdmn0() 10 | #' } 11 | #' @export 12 | 13 | getAdmn0 <- function(...){ 14 | data <- getEpiData(admin_level = 0, ...) 15 | return(data) 16 | } 17 | -------------------------------------------------------------------------------- /tests/testthat/test-plotCovid.R: -------------------------------------------------------------------------------- 1 | test_that("plot produced", { 2 | expect_is(plotEpiData("San Diego County", "confirmed"), "ggplot") 3 | }) 4 | 5 | test_that("invalid API field returns error", { 6 | expect_null(plotEpiData("San Diego County", "comfirmed")) 7 | }) 8 | 9 | test_that("no API field returns error", { 10 | expect_error(plotEpiData("San Diego County"), "Variable to plot not specified") 11 | }) 12 | -------------------------------------------------------------------------------- /man/getGenomicsResponse.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getGenomicsResponse.R 3 | \name{getGenomicsResponse} 4 | \alias{getGenomicsResponse} 5 | \title{Get response from genomics endpoint} 6 | \usage{ 7 | getGenomicsResponse(dataurl, logInfo = T, logWarning = T, logError = T) 8 | } 9 | \description{ 10 | A function that does blabla, blabla. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/getAdmn0.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getAdmn0.R 3 | \name{getAdmn0} 4 | \alias{getAdmn0} 5 | \title{Retrieve COVID-19 data for all countries} 6 | \usage{ 7 | getAdmn0(...) 8 | } 9 | \value{ 10 | dataframe 11 | } 12 | \description{ 13 | Retrieve up-to-date COVID-19 data from outbreak.info for all countries 14 | } 15 | \examples{ 16 | \dontrun{ 17 | getAdmn0() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /man/authenticateUser.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/authenticateUser.R 3 | \name{authenticateUser} 4 | \alias{authenticateUser} 5 | \title{Authenticate API} 6 | \usage{ 7 | authenticateUser() 8 | } 9 | \value{ 10 | url 11 | } 12 | \description{ 13 | Authenticate API to get access to genomics data 14 | } 15 | \examples{ 16 | # Authenticate with GISAID credentials 17 | # authenticateUser() 18 | } 19 | -------------------------------------------------------------------------------- /R/getMutationDetails.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve mutation details 2 | #' 3 | #' @description Retrieve details of specified mutation(s) 4 | #' 5 | #'@param mutations a `vector` of mutation(s) 6 | #' 7 | #'@return dataframe 8 | #' 9 | #'@examples 10 | #'getMutationDetails(mutations=c("S:E484K", "S:N501Y")) 11 | #' 12 | #' @export 13 | 14 | getMutationDetails <- function(mutations){ 15 | df <- getGenomicData(query_url="mutation-details", mutations = mutations) 16 | return(df) 17 | } 18 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | .onLoad <- function(libname, pkgname){ 2 | api.url <- "https://api.outbreak.info/covid19/" 3 | assign("api.url", api.url, envir = parent.env(environment())) 4 | assign("COLORPALETTE", c("#bab0ab", "#4E79A7", "#f28e2b", "#59a14f","#e15759", "#499894","#B6992D", "#D37295", "#B07AA1","#9D7660", "#bcbd22", 5 | "#aecBe8", "#FFBE7D", "#8CD17D", "#FF9D9A", "#86BCB6", "#F1CE63","#FABFD2", "#D4A6C8", "#D7B5A6", "#79706E"), envir = parent.env(environment())) 6 | } 7 | -------------------------------------------------------------------------------- /R/getMetroByCountry.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve COVID-19 data for all metropolitan areas in the US. 2 | #' 3 | #' @description Retrieve up-to-date COVID-19 data from outbreak.info for all metropolitan areas in the United States of America. 4 | #' 5 | #' @return dataframe 6 | #' 7 | #' @examples 8 | #' \dontrun{ 9 | #' getMetroByCountry() 10 | #' } 11 | 12 | getMetroByCountry <- function(...){ 13 | data <- getEpiData(country_name = "United States of America", admin_level = 1.5, ...) 14 | return(data) 15 | } 16 | -------------------------------------------------------------------------------- /R/getAdmn2ByCountry.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve COVID-19 data for all counties in the US. 2 | #' 3 | #' @description Retrieve up-to-date COVID-19 data from outbreak.info for all counties in the United States of America. 4 | #' 5 | #' @return dataframe 6 | #' 7 | #' @examples 8 | #' # Takes a long time to run! 9 | #' \dontrun{ 10 | #' getAdmn2ByCountry() 11 | #' } 12 | #' 13 | 14 | getAdmn2ByCountry <- function(...){ 15 | data <- getEpiData(country_name = "United States of America", admin_level = 2, ...) 16 | return(data) 17 | } 18 | -------------------------------------------------------------------------------- /man/epidemiologyDataDictionary.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epidemiologyDataDictionary.R 3 | \name{epidemiologyDataDictionary} 4 | \alias{epidemiologyDataDictionary} 5 | \title{Documentation of Epidemiology API fields} 6 | \usage{ 7 | epidemiologyDataDictionary() 8 | } 9 | \value{ 10 | dataframe 11 | } 12 | \description{ 13 | Documents fields included when extracting data from outbreak.info 14 | } 15 | \examples{ 16 | df = epidemiologyDataDictionary() 17 | knitr::kable(df) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /man/getMutationDetails.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getMutationDetails.R 3 | \name{getMutationDetails} 4 | \alias{getMutationDetails} 5 | \title{Retrieve mutation details} 6 | \usage{ 7 | getMutationDetails(mutations) 8 | } 9 | \arguments{ 10 | \item{mutations}{a `vector` of mutation(s)} 11 | } 12 | \value{ 13 | dataframe 14 | } 15 | \description{ 16 | Retrieve details of specified mutation(s) 17 | } 18 | \examples{ 19 | getMutationDetails(mutations=c("S:E484K", "S:N501Y")) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/getMetroByCountry.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getMetroByCountry.R 3 | \name{getMetroByCountry} 4 | \alias{getMetroByCountry} 5 | \title{Retrieve COVID-19 data for all metropolitan areas in the US.} 6 | \usage{ 7 | getMetroByCountry(...) 8 | } 9 | \value{ 10 | dataframe 11 | } 12 | \description{ 13 | Retrieve up-to-date COVID-19 data from outbreak.info for all metropolitan areas in the United States of America. 14 | } 15 | \examples{ 16 | \dontrun{ 17 | getMetroByCountry() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /man/genomicsDataDictionary.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/genomicsDataDictionary.R 3 | \name{genomicsDataDictionary} 4 | \alias{genomicsDataDictionary} 5 | \title{Documentation of genomics (SARS-CoV-2 variant prevalence) API fields} 6 | \usage{ 7 | genomicsDataDictionary() 8 | } 9 | \value{ 10 | dataframe 11 | } 12 | \description{ 13 | Returns a dataframe describing the fields included when making calls to the genomics API. 14 | } 15 | \examples{ 16 | knitr::kable(genomicsDataDictionary()) 17 | } 18 | -------------------------------------------------------------------------------- /man/getLag.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getLag.R 3 | \name{getLag} 4 | \alias{getLag} 5 | \title{Retrieve lag between collection and submission} 6 | \usage{ 7 | getLag(location = NULL) 8 | } 9 | \arguments{ 10 | \item{location}{(optional) a location name (if not specified, daily lag globally returned)} 11 | } 12 | \value{ 13 | dataframe 14 | } 15 | \description{ 16 | Retrieve daily lag between collection and submission by location 17 | } 18 | \examples{ 19 | getLag(location="California") 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/getAdmn2ByCountry.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getAdmn2ByCountry.R 3 | \name{getAdmn2ByCountry} 4 | \alias{getAdmn2ByCountry} 5 | \title{Retrieve COVID-19 data for all counties in the US.} 6 | \usage{ 7 | getAdmn2ByCountry(...) 8 | } 9 | \value{ 10 | dataframe 11 | } 12 | \description{ 13 | Retrieve up-to-date COVID-19 data from outbreak.info for all counties in the United States of America. 14 | } 15 | \examples{ 16 | # Takes a long time to run! 17 | \dontrun{ 18 | getAdmn2ByCountry() 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /R/getLocationData.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve COVID-19 data for given locations 2 | #' 3 | #' @description Retrieve up-to-date COVID-19 data from outbreak.info for specified location(s) 4 | #' 5 | #' @param location_names vector or list of location name(s) 6 | #' 7 | #' @return dataframe 8 | #' 9 | #' @examples 10 | #' getLocationData(c("California", "India")) 11 | #' 12 | #' @export 13 | 14 | 15 | getLocationData <- function(location_names, ...){ 16 | location_codes <- getISO3(location_names) 17 | data <- getEpiData(location_id=location_codes, ...) 18 | return(data) 19 | } 20 | -------------------------------------------------------------------------------- /man/getAdmn2ByState.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getAdmn2ByState.R 3 | \name{getAdmn2ByState} 4 | \alias{getAdmn2ByState} 5 | \title{Retrieve COVID-19 data for counties in a state(s)} 6 | \usage{ 7 | getAdmn2ByState(states, ...) 8 | } 9 | \arguments{ 10 | \item{states}{vector or list of state name(s)} 11 | } 12 | \value{ 13 | dataframe 14 | } 15 | \description{ 16 | Retrieve up-to-date COVID-19 data from outbreak.info for all counties in one or more states/provinces. 17 | } 18 | \examples{ 19 | getAdmn2ByState("California") 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/getLocationData.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getLocationData.R 3 | \name{getLocationData} 4 | \alias{getLocationData} 5 | \title{Retrieve COVID-19 data for given locations} 6 | \usage{ 7 | getLocationData(location_names, ...) 8 | } 9 | \arguments{ 10 | \item{location_names}{vector or list of location name(s)} 11 | } 12 | \value{ 13 | dataframe 14 | } 15 | \description{ 16 | Retrieve up-to-date COVID-19 data from outbreak.info for specified location(s) 17 | } 18 | \examples{ 19 | getLocationData(c("California", "India")) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /R/setAuthToken.R: -------------------------------------------------------------------------------- 1 | #' Set authentication token 2 | #' 3 | #' Writes authentication token to file 4 | #' 5 | #' @param token A String representing the token to be stored 6 | #' 7 | #' @noRd 8 | 9 | setAuthToken <- function(token){ 10 | wd <- getwd() 11 | tryCatch({ 12 | fileConn<-file(paste0(wd, "/.R_outbreak-info-token")) 13 | writeLines(c(token), fileConn) 14 | close(fileConn) 15 | }, error = function(e){ 16 | stop("Unable to write authentication token to disk. Please make sure your disk has space and the permissions are set correctly.") 17 | }) 18 | } -------------------------------------------------------------------------------- /man/getAdmn1ByCountry.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getAdmn1ByCountry.R 3 | \name{getAdmn1ByCountry} 4 | \alias{getAdmn1ByCountry} 5 | \title{Retrieve COVID-19 data for states/provinces in a country or countries} 6 | \usage{ 7 | getAdmn1ByCountry(countries, ...) 8 | } 9 | \arguments{ 10 | \item{countries}{vector or list of country name(s)} 11 | } 12 | \value{ 13 | dataframe 14 | } 15 | \description{ 16 | Retrieve up-to-date COVID-19 data from outbreak.info for all states/provinces in one or more countries. 17 | } 18 | \examples{ 19 | getAdmn1ByCountry("India") 20 | 21 | } 22 | -------------------------------------------------------------------------------- /tests/testthat/test-getISO3.R: -------------------------------------------------------------------------------- 1 | test_that("returns region ISO3", { 2 | expect_match(getISO3("East Asia & Pacific"), "East_Asia___Pacific", fixed=T) 3 | }) 4 | 5 | test_that("returns country ISO3", { 6 | expect_match(getISO3("Iraq"), "IRQ", fixed=T) 7 | }) 8 | 9 | test_that("returns state ISO3", { 10 | expect_match(getISO3("New Hampshire"), "USA_US-NH", fixed=T) 11 | }) 12 | 13 | test_that("returns county ISO3", { 14 | expect_match(getISO3("Los Angeles County"), "USA_US-CA_06037", fixed=T) 15 | }) 16 | 17 | test_that("returns metro ISO3", { 18 | expect_match(getISO3("Kansas City"), "CITY_US-MO_KC", fixed=T) 19 | }) 20 | -------------------------------------------------------------------------------- /man/getLocationIdGenomic.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getLocationIdGenomic.R 3 | \name{getLocationIdGenomic} 4 | \alias{getLocationIdGenomic} 5 | \title{Get location id codes from genomic API} 6 | \usage{ 7 | getLocationIdGenomic(locations_to_search) 8 | } 9 | \arguments{ 10 | \item{locations_to_search}{a location name} 11 | } 12 | \value{ 13 | a location ID code (ISO3, FIPS) 14 | } 15 | \description{ 16 | Get location ID code for countries, states/provinces, metropolitan areas, and/or counties from genomic API 17 | } 18 | \examples{ 19 | getLocationIdGenomic("San Diego") 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/getCountryByRegion.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getCountryByRegion.R 3 | \name{getCountryByRegion} 4 | \alias{getCountryByRegion} 5 | \title{Retrieve COVID-19 data for countries in a World Bank region(s)} 6 | \usage{ 7 | getCountryByRegion(wb_regions, ...) 8 | } 9 | \arguments{ 10 | \item{wb_regions}{vector or list of World Bank region(s)} 11 | } 12 | \value{ 13 | dataframe 14 | } 15 | \description{ 16 | Retrieve up-to-date COVID-19 data from outbreak.info for all countries in one or more World Bank region(s). 17 | } 18 | \examples{ 19 | getCountryByRegion("North America") 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/getISO3.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getISO3.R 3 | \name{getISO3} 4 | \alias{getISO3} 5 | \title{Get ISO3 codes} 6 | \usage{ 7 | getISO3(locations_to_search) 8 | } 9 | \arguments{ 10 | \item{locations_to_search}{vector or list of location (World Bank region, country, state/province, metropolitan area, county) name(s)} 11 | } 12 | \value{ 13 | a vector or list of ISO3 codes 14 | } 15 | \description{ 16 | Get ISO3 codes for World Bank regions, countries, states/provinces, metropolitan areas, and/or counties. 17 | } 18 | \examples{ 19 | getISO3(c("San Diego", "Virginia", "India")) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /R/getByAdmnLevel.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve COVID-19 data for all locations at an administrative level. 2 | #' 3 | #' @description Retrieve up-to-date COVID-19 data from outbreak.info for all locations at a given administrative level. 4 | #' 5 | #' @param admin_level an integer representing an administrative level (World Bank regions = -1, countries = 0, states/provinces = 1, metropolitan areas = 1.5, counties = 2) 6 | #' 7 | #' @return dataframe 8 | #' 9 | #' @examples 10 | #' getByAdmnLevel(-1) 11 | #' 12 | #' @export 13 | 14 | getByAdmnLevel <- function(admin_level, ...){ 15 | data <- getEpiData(admin_level = admin_level, ...) 16 | return(data) 17 | } 18 | -------------------------------------------------------------------------------- /R/getAdmn2ByState.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve COVID-19 data for counties in a state(s) 2 | #' 3 | #' @description Retrieve up-to-date COVID-19 data from outbreak.info for all counties in one or more states/provinces. 4 | #' 5 | #' @param states vector or list of state name(s) 6 | #' 7 | #' @return dataframe 8 | #' 9 | #' @examples 10 | #' getAdmn2ByState("California") 11 | #' 12 | #' @export 13 | 14 | getAdmn2ByState <- function(states, ...){ 15 | locations <- searchLocations(states, admin_level = 1) 16 | if (is.null(locations)){ 17 | stop("No states selected") 18 | } 19 | data <- getEpiData(state_name = locations, admin_level = 2, ...) 20 | return(data) 21 | } 22 | -------------------------------------------------------------------------------- /R/getAuthToken.R: -------------------------------------------------------------------------------- 1 | #' Get authentication token 2 | #' 3 | #' Get authentication token from file 4 | #' 5 | #' @noRd 6 | 7 | getAuthToken <- function(token){ 8 | wd <- getwd() 9 | token_file <- paste0(wd, "/.R_outbreak-info-token") 10 | if(file.exists(token_file)){ 11 | con <- file(token_file, "r") 12 | token <- readLines(token_file) 13 | close(con) 14 | if(length(token) != 1){ 15 | return(NULL); 16 | } 17 | return(token) 18 | } else { 19 | if(Sys.getenv("OUTBREAK_INFO_TOKEN") != ""){ 20 | return(Sys.getenv("OUTBREAK_INFO_TOKEN")) 21 | } 22 | } 23 | return(NULL) 24 | } -------------------------------------------------------------------------------- /R/getAdmn1ByCountry.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve COVID-19 data for states/provinces in a country or countries 2 | #' 3 | #' @description Retrieve up-to-date COVID-19 data from outbreak.info for all states/provinces in one or more countries. 4 | #' 5 | #' 6 | #' @param countries vector or list of country name(s) 7 | #' 8 | #' @return dataframe 9 | #' 10 | #' @examples 11 | #' getAdmn1ByCountry("India") 12 | #' 13 | #' @export 14 | 15 | getAdmn1ByCountry <- function(countries, ...){ 16 | locations <- searchLocations(countries, admin_level = 0) 17 | if (is.null(locations)){ 18 | stop("No countries selected") 19 | } 20 | data <- getEpiData(country_name = locations, admin_level = 1, ...) 21 | return(data) 22 | } 23 | -------------------------------------------------------------------------------- /R/getCountryByRegion.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve COVID-19 data for countries in a World Bank region(s) 2 | #' 3 | #' @description Retrieve up-to-date COVID-19 data from outbreak.info for all countries in one or more World Bank region(s). 4 | #' 5 | #' @param wb_regions vector or list of World Bank region(s) 6 | #' 7 | #' @return dataframe 8 | #' 9 | #' @examples 10 | #' getCountryByRegion("North America") 11 | #' 12 | #' @export 13 | 14 | getCountryByRegion <- function(wb_regions, ...){ 15 | locations <- searchLocations(wb_regions, admin_level = -1) 16 | if (is.null(locations)){ 17 | stop("No regions selected") 18 | } 19 | data <- getEpiData(wb_region = locations, admin_level = 0, ...) 20 | return(data) 21 | } 22 | -------------------------------------------------------------------------------- /R/getMutationAcrossLineage.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve prevalence of mutation across lineages by location 2 | #' 3 | #' @description Retrieve prevalence of a specified mutation across all lineages by location 4 | #' 5 | #'@param mutations a `vector` of mutation(s) 6 | #'@param location (optional) a location name (if not specified, prevalence globally returned) 7 | #' 8 | #'@return dataframe 9 | #' 10 | #'@examples 11 | #'getMutationAcrossLineage(mutations="S:N501Y", location="United States") 12 | #' 13 | #' @export 14 | 15 | 16 | getMutationAcrossLineage <- function(mutations, location=NULL){ 17 | df <- getGenomicData(query_url="mutations-by-lineage", mutations = mutations, location = location) 18 | return(df) 19 | } 20 | -------------------------------------------------------------------------------- /man/plotEpiData.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotEpiData.R 3 | \name{plotEpiData} 4 | \alias{plotEpiData} 5 | \title{Plot COVID-19 data of interest} 6 | \usage{ 7 | plotEpiData(locations, variable) 8 | } 9 | \arguments{ 10 | \item{locations}{a vector or list of location names} 11 | 12 | \item{variable}{metric to plot} 13 | } 14 | \value{ 15 | ggplot2 object 16 | } 17 | \description{ 18 | Plot a metric of interest using up-to-date COVID-19 data from outbreak.info for location(s) of interest (World Bank region, country, state/province, metropolitan area, county). 19 | } 20 | \examples{ 21 | p = plotEpiData("Florida", "confirmed_per_100k") 22 | show(p) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /man/getByAdmnLevel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getByAdmnLevel.R 3 | \name{getByAdmnLevel} 4 | \alias{getByAdmnLevel} 5 | \title{Retrieve COVID-19 data for all locations at an administrative level.} 6 | \usage{ 7 | getByAdmnLevel(admin_level, ...) 8 | } 9 | \arguments{ 10 | \item{admin_level}{an integer representing an administrative level (World Bank regions = -1, countries = 0, states/provinces = 1, metropolitan areas = 1.5, counties = 2)} 11 | } 12 | \value{ 13 | dataframe 14 | } 15 | \description{ 16 | Retrieve up-to-date COVID-19 data from outbreak.info for all locations at a given administrative level. 17 | } 18 | \examples{ 19 | getByAdmnLevel(-1) 20 | 21 | } 22 | -------------------------------------------------------------------------------- /R/getLag.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve lag between collection and submission 2 | #' 3 | #' @description Retrieve daily lag between collection and submission by location 4 | #' 5 | #'@param location (optional) a location name (if not specified, daily lag globally returned) 6 | #' 7 | #'@return dataframe 8 | #' 9 | #'@examples 10 | #'getLag(location="California") 11 | #' 12 | #' @export 13 | 14 | getLag <- function(location=NULL){ 15 | df <- getGenomicData(query_url="collection-submission", location = location) 16 | if(!is.null(df) && nrow(df) > 0) { 17 | df$date_collected <- as.Date(df$date_collected, "%Y-%m-%d") 18 | df$date_submitted <- as.Date(df$date_submitted, "%Y-%m-%d") 19 | df$lag <- df$date_submitted - df$date_collected 20 | } 21 | return(df) 22 | } 23 | -------------------------------------------------------------------------------- /man/getMutationAcrossLineage.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getMutationAcrossLineage.R 3 | \name{getMutationAcrossLineage} 4 | \alias{getMutationAcrossLineage} 5 | \title{Retrieve prevalence of mutation across lineages by location} 6 | \usage{ 7 | getMutationAcrossLineage(mutations, location = NULL) 8 | } 9 | \arguments{ 10 | \item{mutations}{a `vector` of mutation(s)} 11 | 12 | \item{location}{(optional) a location name (if not specified, prevalence globally returned)} 13 | } 14 | \value{ 15 | dataframe 16 | } 17 | \description{ 18 | Retrieve prevalence of a specified mutation across all lineages by location 19 | } 20 | \examples{ 21 | getMutationAcrossLineage(mutations="S:N501Y", location="United States") 22 | 23 | } 24 | -------------------------------------------------------------------------------- /docs/articles/epivignette_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/locationtracker_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/outbreakinfo_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/researchlibrary_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/varianttracker_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 | -------------------------------------------------------------------------------- /R/getCollectionDateByLocation.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve most recent collection date 2 | #' 3 | #' @description Retrieve most recent collection date by location 4 | #' 5 | #'@param pangolin_lineage PANGO lineage name 6 | #'@param location (optional) a location name (if not specified, collection date at the global level returned) 7 | #'@param mutations (optional) a `vector` of mutation(s) 8 | #' 9 | #'@return dataframe 10 | #' 11 | #'@examples 12 | #'getCollectionDateByLocation(pangolin_lineage="B.1.1.7", location="California") 13 | #' 14 | #' @export 15 | 16 | getCollectionDateByLocation <- function(pangolin_lineage, location=NULL, mutations=NULL){ 17 | df <- getGenomicData(query_url="most-recent-collection-date-by-location", pangolin_lineage = pangolin_lineage, location = location, mutations = mutations) 18 | return(df) 19 | } 20 | -------------------------------------------------------------------------------- /pkgdown_build.R: -------------------------------------------------------------------------------- 1 | # Steps to update the package down build 2 | 3 | # Semi-manual process! 4 | # NOTE: you'll need to supervise this process, because every example that 5 | # contains a call to a genomics function will require GISAID authentication. 6 | 7 | update_package_website = function(auth_token, commit_message = "update R outbreakinfo package website"){ 8 | # Set the authentication token 9 | Sys.setenv(OUTBREAK_INFO_TOKEN = auth_token) 10 | 11 | # 1. Knit the README.Rmd file 12 | # Creates README.md 13 | knitr::knit("README.Rmd") 14 | 15 | # 2. Build the site 16 | # Note: some of the functions in the examples take a fair bit of time to run. 17 | pkgdown::build_site() 18 | 19 | # 3. Push to GitHub; will automatically update GitHub pages. 20 | gert::git_commit_all(commit_message) 21 | gert::git_push() 22 | } 23 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /man/getCuratedLineages.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getCuratedLineages.R 3 | \name{getCuratedLineages} 4 | \alias{getCuratedLineages} 5 | \title{Lookup curated lineages from outbreak.info} 6 | \usage{ 7 | getCuratedLineages() 8 | } 9 | \value{ 10 | dataframe containing VOCs, VOIs, VUMs, and associated metadata. 11 | } 12 | \description{ 13 | Retrieve a curated list of Variants of Concern, Variants of Interest, 14 | Variants Under Monitoring, and de-escalated variants maintained by the [outbreak.info team](https://outbreak.info/situation-reports) 15 | } 16 | \examples{ 17 | curated = getCuratedLineages() 18 | # Pull out the curated lineages which are WHO-desginated 19 | curated[!is.na(curated$who_name),] 20 | # Pull out the Variants of Concern 21 | curated[curated$variantType == "Variant of Concern",] 22 | } 23 | -------------------------------------------------------------------------------- /R/getGlobalPrevalence.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve global daily prevalence of a lineage 2 | #' 3 | #' @description Retrieves the global daily prevalence of a PANGO lineage 4 | #' 5 | #'@param pangolin_lineage PANGO lineage name 6 | #'@param mutations (optional) a `vector` of mutation(s) 7 | #'@param cumulative (optional) `Boolean` (T/F), T returns cumulative global prevalence since first day of detection 8 | #' 9 | #'@return dataframe 10 | #' 11 | #'@examples 12 | #' # B.1.1.7 lineage 13 | #'b117 = getGlobalPrevalence(pangolin_lineage = "B.1.1.7", mutations = "S:E484K") 14 | #'head(b117) 15 | #' 16 | #' @export 17 | 18 | 19 | getGlobalPrevalence <- function(pangolin_lineage, mutations=NULL, cumulative=NULL){ 20 | df <- getGenomicData(query_url="global-prevalence", pangolin_lineage = pangolin_lineage, mutations = mutations, cumulative = cumulative) 21 | return(df) 22 | } 23 | -------------------------------------------------------------------------------- /man/getMutationsByLineage.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getMutationsByLineage.R 3 | \name{getMutationsByLineage} 4 | \alias{getMutationsByLineage} 5 | \title{Retrieve mutations by lineage} 6 | \usage{ 7 | getMutationsByLineage(pangolin_lineage, frequency = 0.75, logInfo = TRUE) 8 | } 9 | \arguments{ 10 | \item{pangolin_lineage}{PANGO lineage name or vector} 11 | 12 | \item{frequency}{a number between 0 and 1 specifying the frequency threshold above which to return mutations (default=0.8)} 13 | 14 | \item{logInfo}{(optional) `Boolean` (T/F), T logs helper messages during API calls.} 15 | } 16 | \value{ 17 | dataframe 18 | } 19 | \description{ 20 | Retrieve all mutations in a specified lineage above a threshold 21 | } 22 | \examples{ 23 | p1 = getMutationsByLineage(pangolin_lineage="P.1", frequency=0.5) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/getGlobalPrevalence.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getGlobalPrevalence.R 3 | \name{getGlobalPrevalence} 4 | \alias{getGlobalPrevalence} 5 | \title{Retrieve global daily prevalence of a lineage} 6 | \usage{ 7 | getGlobalPrevalence(pangolin_lineage, mutations = NULL, cumulative = NULL) 8 | } 9 | \arguments{ 10 | \item{pangolin_lineage}{PANGO lineage name} 11 | 12 | \item{mutations}{(optional) a `vector` of mutation(s)} 13 | 14 | \item{cumulative}{(optional) `Boolean` (T/F), T returns cumulative global prevalence since first day of detection} 15 | } 16 | \value{ 17 | dataframe 18 | } 19 | \description{ 20 | Retrieves the global daily prevalence of a PANGO lineage 21 | } 22 | \examples{ 23 | # B.1.1.7 lineage 24 | b117 = getGlobalPrevalence(pangolin_lineage = "B.1.1.7", mutations = "S:E484K") 25 | head(b117) 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/getCollectionDateByLocation.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getCollectionDateByLocation.R 3 | \name{getCollectionDateByLocation} 4 | \alias{getCollectionDateByLocation} 5 | \title{Retrieve most recent collection date} 6 | \usage{ 7 | getCollectionDateByLocation( 8 | pangolin_lineage, 9 | location = NULL, 10 | mutations = NULL 11 | ) 12 | } 13 | \arguments{ 14 | \item{pangolin_lineage}{PANGO lineage name} 15 | 16 | \item{location}{(optional) a location name (if not specified, collection date at the global level returned)} 17 | 18 | \item{mutations}{(optional) a `vector` of mutation(s)} 19 | } 20 | \value{ 21 | dataframe 22 | } 23 | \description{ 24 | Retrieve most recent collection date by location 25 | } 26 | \examples{ 27 | getCollectionDateByLocation(pangolin_lineage="B.1.1.7", location="California") 28 | 29 | } 30 | -------------------------------------------------------------------------------- /man/getGenomicData.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getGenomicData.R 3 | \name{getGenomicData} 4 | \alias{getGenomicData} 5 | \title{Retrieve data from api.outbreak.info/genomics} 6 | \usage{ 7 | getGenomicData( 8 | query_url, 9 | location = NULL, 10 | cumulative = NULL, 11 | pangolin_lineage = NULL, 12 | mutations = NULL, 13 | ndays = NULL, 14 | frequency = NULL, 15 | subadmin = NULL, 16 | other_threshold = NULL, 17 | nday_threshold = NULL, 18 | other_exclude = NULL, 19 | logInfo = TRUE 20 | ) 21 | } 22 | \value{ 23 | dataframe 24 | } 25 | \description{ 26 | Retrieves up-to-date COVID-19 genomic data from outbreak.info according to user specifications. 27 | } 28 | \examples{ 29 | uk_b117 = getGenomicData(query_url="prevalence-by-location", location="United Kingdom", pangolin_lineage = "B.1.1.7") 30 | head(uk_b117) 31 | } 32 | -------------------------------------------------------------------------------- /man/searchLocations.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/searchLocations.R 3 | \name{searchLocations} 4 | \alias{searchLocations} 5 | \title{Get exact location names} 6 | \usage{ 7 | searchLocations(locations_to_search, admin_level) 8 | } 9 | \arguments{ 10 | \item{locations_to_search}{vector or list of location (World Bank region, country, state/province, metropolitan area, county) name(s) at the same administrative level} 11 | 12 | \item{admin_level}{an integer representing an administrative level (World Bank regions = -1, countries = 0, states/provinces = 1, metropolitan areas = 1.5, counties = 2)} 13 | } 14 | \value{ 15 | a vector or list of location names 16 | } 17 | \description{ 18 | Get exact spelling of locations at the same administrative level. 19 | } 20 | \examples{ 21 | searchLocations(c("California", "Florida", "Texas"), admin_level=1) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /R/getSubmissionDateByLocation.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve most recent submission date 2 | #' 3 | #' @description Retrieves number of sequences by location, by date of sequence submission. 4 | #' See \link[outbreakinfo]{getSeqCounts} to view similar information by date of sample collection. 5 | #' 6 | #'@param pangolin_lineage PANGO lineage name 7 | #'@param location (optional) a location name (if not specified, submission date at the global level returned) 8 | #'@param mutations (optional) a `vector` of mutation(s) 9 | #' 10 | #'@return dataframe 11 | #' 12 | #'@examples 13 | #'getSubmissionDateByLocation(pangolin_lineage="B.1.1.7", location="California") 14 | #' 15 | #' @export 16 | 17 | getSubmissionDateByLocation <- function(pangolin_lineage, location=NULL, mutations=NULL){ 18 | df <- getGenomicData(query_url="most-recent-submission-date-by-location", pangolin_lineage = pangolin_lineage, location = location, mutations = mutations) 19 | return(df) 20 | } 21 | -------------------------------------------------------------------------------- /tests/testthat/test-searchLocations.R: -------------------------------------------------------------------------------- 1 | test_that("returns region name", { 2 | expect_match(searchLocations("East Asia & Pacific", -1), "East Asia & Pacific", fixed=T) 3 | }) 4 | 5 | test_that("returns country name", { 6 | expect_match(searchLocations("Iraq", 0), "Iraq", fixed=T) 7 | }) 8 | 9 | test_that("returns state name", { 10 | expect_match(searchLocations("New Hampshire", 1), "New Hampshire", fixed=T) 11 | }) 12 | 13 | test_that("returns county name", { 14 | expect_match(searchLocations("Los Angeles County", 2), "Los Angeles County", fixed=T) 15 | }) 16 | 17 | test_that("returns metro name", { 18 | expect_match(searchLocations("Kansas City, MO-KS", 1.5), "Kansas City, MO-KS", fixed=T) 19 | }) 20 | 21 | test_that("no admin returns error", { 22 | expect_error(searchLocations("San Diego County"), "Administrative level not specified") 23 | }) 24 | 25 | test_that("misspelling returns error", { 26 | expect_null(searchLocations("San Deigo", 2)) 27 | }) 28 | 29 | 30 | -------------------------------------------------------------------------------- /man/getSubmissionDateByLocation.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getSubmissionDateByLocation.R 3 | \name{getSubmissionDateByLocation} 4 | \alias{getSubmissionDateByLocation} 5 | \title{Retrieve most recent submission date} 6 | \usage{ 7 | getSubmissionDateByLocation( 8 | pangolin_lineage, 9 | location = NULL, 10 | mutations = NULL 11 | ) 12 | } 13 | \arguments{ 14 | \item{pangolin_lineage}{PANGO lineage name} 15 | 16 | \item{location}{(optional) a location name (if not specified, submission date at the global level returned)} 17 | 18 | \item{mutations}{(optional) a `vector` of mutation(s)} 19 | } 20 | \value{ 21 | dataframe 22 | } 23 | \description{ 24 | Retrieves number of sequences by location, by date of sequence submission. 25 | See \link[outbreakinfo]{getSeqCounts} to view similar information by date of sample collection. 26 | } 27 | \examples{ 28 | getSubmissionDateByLocation(pangolin_lineage="B.1.1.7", location="California") 29 | 30 | } 31 | -------------------------------------------------------------------------------- /man/plotMutationHeatmap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotMutationHeatmap.R 3 | \name{plotMutationHeatmap} 4 | \alias{plotMutationHeatmap} 5 | \title{Title Compare mutation prevalences between lineages} 6 | \usage{ 7 | plotMutationHeatmap(df, gene2Plot = "S", title = NULL, lightBorders = TRUE) 8 | } 9 | \arguments{ 10 | \item{df}{Resulting dataframe from calling \link[outbreakinfo]{getMutationsByLineage}} 11 | 12 | \item{gene2Plot}{(optional) string containing which genes to include, e.g. "Orf1a" By default, will limit the mutations to those in the S-gene.} 13 | 14 | \item{title}{(optional) title to add to the plot} 15 | 16 | \item{lightBorders}{(optional) boolean; whether the borders between grid items should be separated with a light or dark border.} 17 | } 18 | \value{ 19 | 20 | } 21 | \description{ 22 | Plots a heatamp of mutation prevalence across particular lineages. 23 | } 24 | \examples{ 25 | p1 = getMutationsByLineage(pangolin_lineage = "P.1", frequency = 0.5) 26 | plotMutationHeatmap(p1, gene2Plot = "ORF1a") 27 | 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2021 outbreakinfo authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/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 ] 6 | tags: ['*'] 7 | 8 | name: pkgdown 9 | 10 | jobs: 11 | pkgdown: 12 | runs-on: ubuntu-latest 13 | env: 14 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 15 | steps: 16 | - uses: actions/checkout@v2 17 | 18 | - uses: r-lib/actions/setup-pandoc@v1 19 | 20 | - uses: r-lib/actions/setup-r@v1 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v1 25 | with: 26 | extra-packages: pkgdown 27 | needs: website 28 | 29 | - name: Authorize app & deploy package 30 | run: | 31 | git config --local user.name "$GITHUB_ACTOR" 32 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 33 | Rscript -e 'Sys.setenv(OUTBREAK_INFO_TOKEN = ${{secrets.OUTBREAK_INFO_TOKEN}}, GADM_FILE = ${{secrets.GADM_FILE}}); pkgdown::deploy_to_branch(new_process = FALSE)' 34 | -------------------------------------------------------------------------------- /man/plotChoropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotChoropleth.R 3 | \name{plotChoropleth} 4 | \alias{plotChoropleth} 5 | \title{Basic plotting function to create a choropleth (map with areas shaded by prevalence)} 6 | \usage{ 7 | plotChoropleth( 8 | df, 9 | fillVar = "proportion", 10 | title = NULL, 11 | subtitle = NULL, 12 | proj4 = "+proj=wag7 +lon_0=11 +datum=WGS84 +units=m +no_defs" 13 | ) 14 | } 15 | \arguments{ 16 | \item{df}{Dataframe resulting from calling \link[outbreakinfo]{getCumulativeBySubadmin}} 17 | 18 | \item{fillVar}{(optional) Which variable within `df` that should be used to fill the location areas. (`proportion` by default)} 19 | 20 | \item{title}{(optional) Title to include on plot} 21 | 22 | \item{subtitle}{(optional) Subtitle to include on plot} 23 | 24 | \item{proj4}{(optional) PROJ4 projection string used to project geographic coordinates. \href{Wagner VII}{https://proj.org/operations/projections/wag7.html}, appropriate for World maps, is used by default} 25 | } 26 | \value{ 27 | 28 | } 29 | \description{ 30 | Basic plotting function to create a choropleth (map with areas shaded by prevalence) 31 | } 32 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: outbreakinfo 2 | Type: Package 3 | Title: outbreak.info R Client 4 | Version: 0.2.0 5 | Authors@R: c(person("Manar", "Alkuzweny", email = "manaralkuzweny@gmail.com", 6 | role = c("aut", "cre")), 7 | person("Karthik", "Gangavarapu", email = "gkarthik@ucla.edu", 8 | role = c("aut")), 9 | person("Laura", "Hughes", email = "lhughes@scripps.edu", 10 | role = c("aut")) 11 | ) 12 | Description: This package retrieves up-to-date COVID-19 epidemiological and genomic data from outbreak.info. 13 | License: MIT + file LICENSE 14 | Encoding: UTF-8 15 | LazyData: FALSE 16 | Imports: 17 | jsonlite, 18 | RcppSimdJson, 19 | ggplot2, 20 | readr, 21 | progress, 22 | dplyr, 23 | plyr, 24 | purrr, 25 | stringr, 26 | tidyr, 27 | httr, 28 | yaml, 29 | crayon, 30 | sf 31 | RoxygenNote: 7.2.0 32 | Suggests: 33 | testthat, 34 | knitr, 35 | lubridate 36 | URL: https://outbreak-info.github.io/R-outbreak-info/ 37 | BugReports: https://github.com/outbreak-info/R-outbreak-info/issues 38 | -------------------------------------------------------------------------------- /R/getSeqCounts.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve sequence count data 2 | #' 3 | #' @description Retrieves number of sequences by location, by date of sample collection. 4 | #' See \link[outbreakinfo]{getSubmissionDateByLocation} to view similar information by date of sequence submission. 5 | #' 6 | #'@param location (optional) a location name (if not specified, global total counts returned) 7 | #'@param cumulative (optional) Boolean (T/F), T returns cumulative number of sequences to date 8 | #'@param subadmin (optional) Boolean (T/F), subadmin=T and cumulative=T returns cumulative number of sequences for next administrative level 9 | #' 10 | #'@return dataframe 11 | #' 12 | #'@examples 13 | #' # Retrieves the number of samples sequenced in the U.S. each day, by date of sample collection 14 | #'getSeqCounts(location="United States") 15 | #' 16 | #' # Returns the total number of global sequences in the outbreak.info API. 17 | #'getSeqCounts(cumulative=TRUE) 18 | #' 19 | #' @export 20 | 21 | 22 | getSeqCounts <- function(location=NULL, cumulative=NULL, subadmin=NULL){ 23 | df <- getGenomicData(query_url="sequence-count", location = location, cumulative = cumulative, subadmin = subadmin) 24 | return(df) 25 | } 26 | -------------------------------------------------------------------------------- /man/getSeqCounts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getSeqCounts.R 3 | \name{getSeqCounts} 4 | \alias{getSeqCounts} 5 | \title{Retrieve sequence count data} 6 | \usage{ 7 | getSeqCounts(location = NULL, cumulative = NULL, subadmin = NULL) 8 | } 9 | \arguments{ 10 | \item{location}{(optional) a location name (if not specified, global total counts returned)} 11 | 12 | \item{cumulative}{(optional) Boolean (T/F), T returns cumulative number of sequences to date} 13 | 14 | \item{subadmin}{(optional) Boolean (T/F), subadmin=T and cumulative=T returns cumulative number of sequences for next administrative level} 15 | } 16 | \value{ 17 | dataframe 18 | } 19 | \description{ 20 | Retrieves number of sequences by location, by date of sample collection. 21 | See \link[outbreakinfo]{getSubmissionDateByLocation} to view similar information by date of sequence submission. 22 | } 23 | \examples{ 24 | # Retrieves the number of samples sequenced in the U.S. each day, by date of sample collection 25 | getSeqCounts(location="United States") 26 | 27 | # Returns the total number of global sequences in the outbreak.info API. 28 | getSeqCounts(cumulative=TRUE) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /docs/articles/epivignette_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /docs/articles/outbreakinfo_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /docs/articles/varianttracker_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /docs/articles/locationtracker_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /docs/articles/researchlibrary_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /man/plotPrevalenceDotPlot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotPrevalenceDotPlot.R 3 | \name{plotPrevalenceDotPlot} 4 | \alias{plotPrevalenceDotPlot} 5 | \title{Plots a dot plot of prevalences of a variant in a specific location} 6 | \usage{ 7 | plotPrevalenceDotPlot(df, title = NULL, subtitle = NULL, dot_size = 3) 8 | } 9 | \arguments{ 10 | \item{df}{Dataframe resulting from calling \link[outbreakinfo]{getCumulativeBySubadmin}} 11 | 12 | \item{title}{(optional) Title to include on the plot} 13 | 14 | \item{subtitle}{(optional) Subtitle to include on the plot} 15 | 16 | \item{dot_size}{(optional) Dot plot size (in mm)} 17 | } 18 | \value{ 19 | 20 | } 21 | \description{ 22 | Plots a dot plot of prevalences of a variant in a specific location 23 | } 24 | \examples{ 25 | 26 | # Calculate the proportion of sequences assigned to BA.2 or BA.2.12.1 by U.S. State 27 | prev_by_state = getCumulativeBySubadmin(pangolin_lineage = c("BA.2", "BA.2.12.1"), location = "United States", ndays = 90) 28 | 29 | # Plot the results 30 | plotPrevalenceDotPlot(prev_by_state, "Prevalence over the last 90 days in the United States", subtitle = paste0("As of ", format(Sys.Date(), '\%d \%B \%Y'))) 31 | } 32 | -------------------------------------------------------------------------------- /docs/lineagevignette.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Lineage Report (B.1.1.7)" 3 | date: "June 7, 2021" 4 | output: html_document 5 | --- 6 | 7 | ```{r setup, include=FALSE} 8 | knitr::opts_chunk$set(echo = TRUE) 9 | library(jsonlite) 10 | library(ggplot2) 11 | library(readr) 12 | source("/Users/manar/Downloads/outbreakfunc.R") 13 | ``` 14 | 15 | ------ 16 | 17 | #### **Average daily B.1.1.7 prevalence** 18 | 19 | ```{r} 20 | p <- plotPrevalenceByLocation(pangolin_lineage = "b.1.1.7", location = "united states", include_title = T) 21 | show(p) 22 | ``` 23 | 24 | --------- 25 | 26 | #### **Cumulative B.1.1.7 prevalence** 27 | 28 | ```{r} 29 | us_df <- getCumulativeBySubadmin(pangolin_lineage = "B.1.1.7", location = "United States") 30 | 31 | states_map <- usmap::us_map() 32 | 33 | us_df <- merge(us_df, states_map, by.x="name", by.y="full", all.y=TRUE) 34 | us_df <- us_df[order(us_df$order),] 35 | 36 | p <- ggplot() + geom_polygon(data = us_df, aes(x, y, group=group, fill=proportion), color="gray25", size=0.3) + scale_fill_gradient(low = "lemonchiffon", high = "lightseagreen", name = "Cumulative prevalence \nof B.1.1.7", labels = scales::percent) + ggplot2::theme_void() + coord_map(projection="albers", lat0=39, lat1=45) 37 | show(p) 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /man/getCumulativeBySubadmin.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getCumulativeBySubadmin.R 3 | \name{getCumulativeBySubadmin} 4 | \alias{getCumulativeBySubadmin} 5 | \title{Retrieve cumulative prevalence of a lineage} 6 | \usage{ 7 | getCumulativeBySubadmin( 8 | pangolin_lineage, 9 | location = NULL, 10 | mutations = NULL, 11 | ndays = NULL 12 | ) 13 | } 14 | \arguments{ 15 | \item{pangolin_lineage}{PANGO lineage name} 16 | 17 | \item{location}{(optional) a location name (if not specified, cumulative prevalence at the country level globally returned)} 18 | 19 | \item{mutations}{(optional) a `vector` of mutation(s)} 20 | 21 | \item{ndays}{(optional) an `integer` specifying number of days from current date to calculative cumuative counts (if not specified, no limit on window)} 22 | } 23 | \value{ 24 | dataframe 25 | } 26 | \description{ 27 | Retrieve cumulative prevalence of a PANGO lineage by the immediate administrative level of a location 28 | } 29 | \examples{ 30 | # Worldwide prevalence of B.1.1.7 by country 31 | head(getCumulativeBySubadmin(pangolin_lineage="B.1.1.7")) 32 | 33 | # County-level prevalence of B.1.1.7 34 | head(getCumulativeBySubadmin(pangolin_lineage="B.1.1.7", location="California")) 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /.github/workflows/testing-r-versions.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | # 6 | # See https://github.com/r-lib/actions/tree/master/examples#readme for 7 | # additional example workflows available for the R community. 8 | 9 | name: R version testing 10 | 11 | on: 12 | push: 13 | branches: [ dev ] 14 | pull_request: 15 | branches: [ dev ] 16 | 17 | jobs: 18 | build: 19 | runs-on: macos-latest 20 | strategy: 21 | matrix: 22 | r-version: ['3.6.3', '4.1.1'] 23 | 24 | steps: 25 | - uses: actions/checkout@v2 26 | - name: Set up R ${{ matrix.r-version }} 27 | uses: r-lib/actions/setup-r@f57f1301a053485946083d7a45022b278929a78a 28 | with: 29 | r-version: ${{ matrix.r-version }} 30 | - name: Install dependencies 31 | run: | 32 | install.packages(c("remotes", "rcmdcheck")) 33 | remotes::install_deps(dependencies = TRUE) 34 | shell: Rscript {0} 35 | - name: Check 36 | run: | 37 | Sys.setenv(OUTBREAK_INFO_TOKEN = ${{secrets.OUTBREAK_INFO_TOKEN}}) 38 | rcmdcheck::rcmdcheck(args = "--no-manual", error_on = "error") 39 | shell: Rscript {0} 40 | -------------------------------------------------------------------------------- /R/getCumulativeBySubadmin.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve cumulative prevalence of a lineage 2 | #' 3 | #' @description Retrieve cumulative prevalence of a PANGO lineage by the immediate administrative level of a location 4 | #' 5 | #'@param pangolin_lineage PANGO lineage name 6 | #'@param location (optional) a location name (if not specified, cumulative prevalence at the country level globally returned) 7 | #'@param mutations (optional) a `vector` of mutation(s) 8 | #'@param ndays (optional) an `integer` specifying number of days from current date to calculative cumuative counts (if not specified, no limit on window) 9 | #' 10 | #'@return dataframe 11 | #' 12 | #' @examples 13 | #' # Worldwide prevalence of B.1.1.7 by country 14 | #' head(getCumulativeBySubadmin(pangolin_lineage="B.1.1.7")) 15 | #' 16 | #' # County-level prevalence of B.1.1.7 17 | #' head(getCumulativeBySubadmin(pangolin_lineage="B.1.1.7", location="California")) 18 | #' 19 | #' 20 | #' @export 21 | 22 | getCumulativeBySubadmin <- function(pangolin_lineage, location=NULL, mutations=NULL, ndays=NULL){ 23 | df <- getGenomicData(query_url="lineage-by-sub-admin-most-recent", pangolin_lineage = pangolin_lineage, location = location, mutations = mutations, ndays = ndays) 24 | 25 | 26 | if(!is.null(df) && nrow(df) != 0){ 27 | df <- df %>% 28 | rename(lineage = query_key) 29 | } 30 | 31 | return(df) 32 | } 33 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(authenticateUser) 4 | export(epidemiologyDataDictionary) 5 | export(genomicsDataDictionary) 6 | export(getAdmn0) 7 | export(getAdmn1ByCountry) 8 | export(getAdmn2ByState) 9 | export(getAllLineagesByLocation) 10 | export(getByAdmnLevel) 11 | export(getCollectionDateByLocation) 12 | export(getCountryByRegion) 13 | export(getCumulativeBySubadmin) 14 | export(getCuratedLineages) 15 | export(getEpiData) 16 | export(getGenomicData) 17 | export(getGenomicsResponse) 18 | export(getGlobalPrevalence) 19 | export(getISO3) 20 | export(getLag) 21 | export(getLocationData) 22 | export(getLocationIdGenomic) 23 | export(getMutationAcrossLineage) 24 | export(getMutationDetails) 25 | export(getMutationsByLineage) 26 | export(getPrevalence) 27 | export(getResourcesData) 28 | export(getResourcesResponse) 29 | export(getSeqCounts) 30 | export(getSubmissionDateByLocation) 31 | export(lookupSublineages) 32 | export(plotAllLineagesByLocation) 33 | export(plotChoropleth) 34 | export(plotEpiData) 35 | export(plotMutationHeatmap) 36 | export(plotPrevalenceDotPlot) 37 | export(plotPrevalenceOverTime) 38 | export(searchLocations) 39 | import(RcppSimdJson) 40 | import(crayon) 41 | import(dplyr) 42 | import(ggplot2) 43 | import(httr) 44 | import(jsonlite) 45 | import(progress) 46 | import(purrr) 47 | import(sf) 48 | import(stringr) 49 | import(tidyr) 50 | import(yaml) 51 | -------------------------------------------------------------------------------- /R/getMutationsByLineage.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve mutations by lineage 2 | #' 3 | #' @description Retrieve all mutations in a specified lineage above a threshold 4 | #' 5 | #'@param pangolin_lineage PANGO lineage name or vector 6 | #'@param frequency a number between 0 and 1 specifying the frequency threshold above which to return mutations (default=0.8) 7 | #' @param logInfo (optional) `Boolean` (T/F), T logs helper messages during API calls. 8 | #' 9 | #' @return dataframe 10 | #' 11 | #' @examples 12 | #' p1 = getMutationsByLineage(pangolin_lineage="P.1", frequency=0.5) 13 | #' 14 | #' @export 15 | 16 | 17 | getMutationsByLineage <- function(pangolin_lineage, frequency=0.75, logInfo=TRUE){ 18 | 19 | if(length(pangolin_lineage) > 1) { 20 | # Set frequency to 0 and then filter after the fact. 21 | df <- map_df(pangolin_lineage, function(lineage) getGenomicData(query_url="lineage-mutations", pangolin_lineage = lineage, frequency = 0, logInfo = logInfo)) 22 | 23 | if(!is.null(df) && nrow(df) != 0){ 24 | mutations = df %>% 25 | filter(prevalence >= frequency) %>% 26 | pull(mutation) %>% 27 | unique() 28 | 29 | df <- df %>% 30 | filter(mutation %in% mutations) 31 | } 32 | 33 | } else { 34 | df <- getGenomicData(query_url="lineage-mutations", pangolin_lineage = pangolin_lineage, frequency = frequency, logInfo = logInfo) 35 | } 36 | 37 | return(df) 38 | } 39 | -------------------------------------------------------------------------------- /man/getEpiData.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getEpiData.R 3 | \name{getEpiData} 4 | \alias{getEpiData} 5 | \title{Retrieve epidemiological data from outbreak.info} 6 | \usage{ 7 | getEpiData( 8 | name = NULL, 9 | location_id = NULL, 10 | wb_region = NULL, 11 | country_name = NULL, 12 | state_name = NULL, 13 | admin_level = NULL, 14 | date = NULL, 15 | mostRecent = NULL, 16 | fields = NULL, 17 | sort = NULL, 18 | size = 1000 19 | ) 20 | } 21 | \arguments{ 22 | \item{name}{vector of location names} 23 | 24 | \item{location_id}{vector of ISO3 code representing locations} 25 | 26 | \item{wb_region}{World Bank region name(s)} 27 | 28 | \item{country_name}{country name(s)} 29 | 30 | \item{state_name}{state name(s)} 31 | 32 | \item{admin_level}{an integer representing an administrative level (World Bank regions = -1, countries = 0, states/provinces = 1, metropolitan areas = 1.5, counties = 2)} 33 | 34 | \item{date}{date(s) (YYYY-MM-DD)} 35 | 36 | \item{mostRecent}{T/F} 37 | 38 | \item{fields}{vector of API fields to include in results} 39 | 40 | \item{sort}{parameter to sort results by} 41 | 42 | \item{size}{size} 43 | } 44 | \value{ 45 | dataframe 46 | } 47 | \description{ 48 | Retrieve up-to-date epidemiological data from outbreak.info according to user specifications 49 | } 50 | \examples{ 51 | getEpiData(name="United States of America", date="2020-07-01") 52 | 53 | } 54 | -------------------------------------------------------------------------------- /man/lookupSublineages.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/lookupSublineages.R 3 | \name{lookupSublineages} 4 | \alias{lookupSublineages} 5 | \title{Lookup sublineages for a given Pango lineage or WHO name} 6 | \usage{ 7 | lookupSublineages(lineage, returnQueryString = FALSE) 8 | } 9 | \arguments{ 10 | \item{lineage}{String with the name of a Pango lineage or WHO name} 11 | 12 | \item{returnQueryString}{Boolean to return a query string to be piped into functions like \link[outbreakinfo]{getPrevalence} (collapses vector by `"OR"`)} 13 | } 14 | \value{ 15 | list containing the sublineages associated with that lineage or WHO designation 16 | } 17 | \description{ 18 | Retrieve all sublineages of a given Pango lineage or WHO designation. 19 | Based on a phylogeny maintained by the [Pango team](https://github.com/cov-lineages/lineages-website/blob/master/data/lineages.yml) 20 | to grab all sublineages associated with a lineage, and a curated list of Variants of Concern, Variants of Interest, 21 | Variants Under Monitoring, and de-escalated variants maintained by the [outbreak.info team](https://outbreak.info/situation-reports) 22 | } 23 | \examples{ 24 | # WHO-designated lineages 25 | lookupSublineages("epsilon") 26 | lookupSublineages("epsilon", returnQueryString = TRUE) 27 | # Pango lineage 28 | lookupSublineages("B.1.1.7") 29 | #' # Not a recognized lineage 30 | lookupSublineages("VOC-21APR-02") 31 | } 32 | -------------------------------------------------------------------------------- /R/getCuratedLineages.R: -------------------------------------------------------------------------------- 1 | #' Lookup curated lineages from outbreak.info 2 | #' 3 | #' @description Retrieve a curated list of Variants of Concern, Variants of Interest, 4 | #' Variants Under Monitoring, and de-escalated variants maintained by the [outbreak.info team](https://outbreak.info/situation-reports) 5 | #' 6 | #' 7 | #' @import httr 8 | #' @import jsonlite 9 | #' @return dataframe containing VOCs, VOIs, VUMs, and associated metadata. 10 | #' @export 11 | #' 12 | #' @examples 13 | #' curated = getCuratedLineages() 14 | #' # Pull out the curated lineages which are WHO-desginated 15 | #' curated[!is.na(curated$who_name),] 16 | #' # Pull out the Variants of Concern 17 | #' curated[curated$variantType == "Variant of Concern",] 18 | 19 | 20 | getCuratedLineages = function() { 21 | ALIAS_URL = "https://raw.githubusercontent.com/outbreak-info/outbreak.info/master/web/src/assets/genomics/curated_lineages.json" 22 | 23 | tryCatch({ 24 | curated_resp = GET(ALIAS_URL) 25 | 26 | 27 | if(curated_resp$status_code != 200) { 28 | stop("Cannot access the Pango sublineages dictionary. Please contact the outbreak.info team at help@outbreak.info.") 29 | } 30 | 31 | curated = fromJSON(content(curated_resp, as="text")) 32 | return(curated) 33 | }, error = function(cond){ 34 | message(cond) 35 | stop("Cannot access the curated lineages dataframe. Please contact the outbreak.info team at help@outbreak.info."); 36 | }, warning = function(cond){ 37 | message(cond) 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /R/getAllLineagesByLocation.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve prevalence of lineages by location 2 | #' 3 | #' @description Retrieve prevalence of all lineages above a specified frequency over time by location 4 | #' 5 | #'@param location a location name 6 | #'@param other_threshold minimum prevalence threshold below which lineages are accumulated under "Other" (default=0.05) 7 | #'@param nday_threshold minimum number of days in which the prevalence of a lineage must be below other_threshold to be accumulated under "Other" (default=10) 8 | #'@param ndays the number of days before the current date to be used as a window to accumulate lineages under "Other" (default=180) 9 | #'@param other_exclude (optional) lineage(s) that are NOT to be included under "Other" even if the conditions specified by the three thresholds above are met 10 | #'@param cumulative `Boolean` (T/F), T returns cumulative prevalence of lineages (default=F) 11 | #' 12 | #'@return dataframe 13 | #' 14 | #'@examples 15 | #'india = getAllLineagesByLocation(location = "India", other_threshold=0.03, ndays=60) 16 | #'india[india$date == "2021-06-25",] 17 | #' 18 | #' @export 19 | 20 | getAllLineagesByLocation <- function(location, other_threshold=0.05, nday_threshold=10, ndays=180, other_exclude=NULL, cumulative=F){ 21 | df <- getGenomicData(query_url="prevalence-by-location-all-lineages", location = location, other_threshold = other_threshold, nday_threshold = nday_threshold, ndays = ndays, other_exclude = other_exclude, cumulative = cumulative) 22 | return(df) 23 | } 24 | -------------------------------------------------------------------------------- /man/getAllLineagesByLocation.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getAllLineagesByLocation.R 3 | \name{getAllLineagesByLocation} 4 | \alias{getAllLineagesByLocation} 5 | \title{Retrieve prevalence of lineages by location} 6 | \usage{ 7 | getAllLineagesByLocation( 8 | location, 9 | other_threshold = 0.05, 10 | nday_threshold = 10, 11 | ndays = 180, 12 | other_exclude = NULL, 13 | cumulative = F 14 | ) 15 | } 16 | \arguments{ 17 | \item{location}{a location name} 18 | 19 | \item{other_threshold}{minimum prevalence threshold below which lineages are accumulated under "Other" (default=0.05)} 20 | 21 | \item{nday_threshold}{minimum number of days in which the prevalence of a lineage must be below other_threshold to be accumulated under "Other" (default=10)} 22 | 23 | \item{ndays}{the number of days before the current date to be used as a window to accumulate lineages under "Other" (default=180)} 24 | 25 | \item{other_exclude}{(optional) lineage(s) that are NOT to be included under "Other" even if the conditions specified by the three thresholds above are met} 26 | 27 | \item{cumulative}{`Boolean` (T/F), T returns cumulative prevalence of lineages (default=F)} 28 | } 29 | \value{ 30 | dataframe 31 | } 32 | \description{ 33 | Retrieve prevalence of all lineages above a specified frequency over time by location 34 | } 35 | \examples{ 36 | india = getAllLineagesByLocation(location = "India", other_threshold=0.03, ndays=60) 37 | india[india$date == "2021-06-25",] 38 | 39 | } 40 | -------------------------------------------------------------------------------- /man/plotAllLineagesByLocation.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotAllLineagesByLocation.R 3 | \name{plotAllLineagesByLocation} 4 | \alias{plotAllLineagesByLocation} 5 | \title{Plot prevalence of lineages by location} 6 | \usage{ 7 | plotAllLineagesByLocation( 8 | location, 9 | other_threshold = 0.05, 10 | nday_threshold = 10, 11 | ndays = 180, 12 | other_exclude = NULL, 13 | cumulative = FALSE, 14 | include_title = TRUE 15 | ) 16 | } 17 | \arguments{ 18 | \item{location}{a location name} 19 | 20 | \item{other_threshold}{minimum prevalence threshold below which lineages are accumulated under "Other" (default=0.05)} 21 | 22 | \item{nday_threshold}{minimum number of days in which the prevalence of a lineage must be below other_threshold to be accumulated under "Other" (default=10)} 23 | 24 | \item{ndays}{the number of days before the current date to be used as a window to accumulate lineages under "Other" (default=180)} 25 | 26 | \item{other_exclude}{(optional) lineage(s) that are NOT to be included under "Other" even if the conditions specified by the three thresholds above are met} 27 | 28 | \item{cumulative}{`Boolean` (T/F), T returns cumulative prevalence of lineages (default=F)} 29 | 30 | \item{include_title}{`Boolean` (T/F), T returns plot with title, F returns plot without title (default=F)} 31 | } 32 | \value{ 33 | ggplot2 object 34 | } 35 | \description{ 36 | Plot prevalence of all lineages above a specified frequency over time by location 37 | } 38 | \examples{ 39 | plotAllLineagesByLocation(location = "India", other_threshold=0.03, ndays=60) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /R/genomicsDataDictionary.R: -------------------------------------------------------------------------------- 1 | #' Documentation of genomics (SARS-CoV-2 variant prevalence) API fields 2 | #' @description Returns a dataframe describing the fields included when making calls to the genomics API. 3 | #' 4 | #' @return dataframe 5 | #' @import dplyr 6 | #' 7 | #' @examples 8 | #' knitr::kable(genomicsDataDictionary()) 9 | #' @export 10 | 11 | genomicsDataDictionary <- function() { 12 | dict = tribble(~"API Field", ~Documentation, 13 | "date", "Sequence collection date, in YYYY-MM-DD format", 14 | "lineage", "Pango lineage", 15 | "lineage_count", "Total number of samples on a given day assigned to the Pango lineage", 16 | "lineage_count_rolling", "7 day rolling average of samples assigned to the Pango lineage on that day", 17 | "prevalence", "Estimated prevalence of the variant on that day", 18 | "prevalence_rolling", "7 day rolling average estimate of prevalence of the variant on that day", 19 | "proportion", "Estimated prevalence of a variant: lineage_count_rolling / total_count_rolling", 20 | "proportion_ci_lower", "95% confidence interval lower bound of estimated prevalence of a variant, calculated using Jeffrey's interval", 21 | "proportion_ci_upper", "95% confidence interval upper bound of estimated prevalence of a variant, calculated using Jeffrey's interval", 22 | "total_count", "Total number of samples sequenced on a given day", 23 | "total_count_rolling", "7 day rolling average of total samples sequenced on that day" 24 | ) 25 | return(dict) 26 | } 27 | -------------------------------------------------------------------------------- /man/plotPrevalenceOverTime.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotPrevalenceOverTime.R 3 | \name{plotPrevalenceOverTime} 4 | \alias{plotPrevalenceOverTime} 5 | \title{Plot daily prevalence of a lineage by location} 6 | \usage{ 7 | plotPrevalenceOverTime( 8 | df, 9 | colorVar = "lineage", 10 | title = "Prevalence over time", 11 | labelDictionary = NULL 12 | ) 13 | } 14 | \arguments{ 15 | \item{df}{result of the call to \link[outbreakinfo]{getPrevalence}} 16 | 17 | \item{colorVar}{variable to used to color the line traces. `lineage` by default} 18 | 19 | \item{title}{(optional) Title to add to the plot} 20 | 21 | \item{labelDictionary}{(optional) a named list of values to replace in the plot legend.} 22 | } 23 | \value{ 24 | ggplot2 object 25 | } 26 | \description{ 27 | Plots the daily prevalence of a PANGO lineage by location 28 | } 29 | \examples{ 30 | p1_brazil <- getPrevalence(pangolin_lineage = "P.1", location = "Brazil") 31 | plotPrevalenceOverTime(p1_brazil) 32 | 33 | us <- getPrevalence(pangolin_lineage = c("B.1.1.7", "B.1.427 OR B.1.429", "B.1.617.2"), location = "United States") 34 | plotPrevalenceOverTime(us, labelDictionary = c("B.1.427 OR B.1.429" = "Epsilon")) 35 | 36 | # Overlay locations 37 | b117_india = getPrevalence(pangolin_lineage = "B.1.1.7", location = "India") 38 | b117_us = getPrevalence(pangolin_lineage = "B.1.1.7", location = "United States") 39 | b117_uk = getPrevalence(pangolin_lineage = "B.1.1.7", location = "United Kingdom") 40 | b117 = dplyr::bind_rows(b117_uk, b117_india, b117_us) 41 | plotPrevalenceOverTime(b117, colorVar = "location", title="B.1.1.7 prevalence over time") 42 | } 43 | -------------------------------------------------------------------------------- /R/plotChoropleth.R: -------------------------------------------------------------------------------- 1 | #' Basic plotting function to create a choropleth (map with areas shaded by prevalence) 2 | #' 3 | #' @param df Dataframe resulting from calling \link[outbreakinfo]{getCumulativeBySubadmin} 4 | #' @param fillVar (optional) Which variable within `df` that should be used to fill the location areas. (`proportion` by default) 5 | #' @param title (optional) Title to include on plot 6 | #' @param subtitle (optional) Subtitle to include on plot 7 | #' @param proj4 (optional) PROJ4 projection string used to project geographic coordinates. \href{Wagner VII}{https://proj.org/operations/projections/wag7.html}, appropriate for World maps, is used by default 8 | #' 9 | #' @import sf 10 | #' @return 11 | #' @export 12 | #' 13 | #' @examples 14 | 15 | plotChoropleth = function(df, fillVar = "proportion", title = NULL, subtitle = NULL, proj4 = "+proj=wag7 +lon_0=11 +datum=WGS84 +units=m +no_defs") { 16 | if(!is.null(df) && nrow(df) > 1){ 17 | # color palette: ColorBrewer's YlGnBu:https://colorbrewer2.org/#type=sequential&scheme=YlGnBu&n=9 18 | CHOROPLETH_PALETTE = c('#ffffd9','#edf8b1','#c7e9b4','#7fcdbb','#41b6c4','#1d91c0','#225ea8','#253494','#081d58') 19 | 20 | # Reproject as Mollweide projection 21 | df_projected = st_transform(df, crs = proj4) 22 | 23 | df_projected = df_projected %>% 24 | filter(NAME_0 != "Antarctica") 25 | 26 | 27 | p = ggplot(df_projected, aes_string(fill = fillVar)) + 28 | geom_sf(size = 0.1, colour = "#555555") + 29 | scale_fill_gradientn(colours = CHOROPLETH_PALETTE, na.value = "#babab0", labels=scales::percent, limits = c(0,1)) + 30 | labs(caption="Enabled by data from GISAID (https://gisaid.org/)") + 31 | theme_void() + 32 | ggtitle(title, subtitle = subtitle) + 33 | theme(legend.position = "bottom", plot.caption = element_text(size = 18)) 34 | 35 | return(p) 36 | } else { 37 | warning("No data supplied to the plotting function.") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /man/getResourcesResponse.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getResourcesResponse.R 3 | \name{getResourcesResponse} 4 | \alias{getResourcesResponse} 5 | \title{Access outbreak.info Research Library API} 6 | \usage{ 7 | getResourcesResponse( 8 | queryString = NULL, 9 | size = 10, 10 | fetchAll = FALSE, 11 | fields = NULL, 12 | sort = NULL, 13 | facets = NULL, 14 | facet_size = 10, 15 | queryStub = "https://api.outbreak.info/resources/query?" 16 | ) 17 | } 18 | \arguments{ 19 | \item{size}{(optional) number of records to return (default = 10)} 20 | 21 | \item{fetchAll}{(optional) Boolean whether to return all results for the query} 22 | 23 | \item{fields}{(optional) vector specifying which fields to return. Returns all by default} 24 | 25 | \item{sort}{(optional) field to sort by. Add `-` to sort in descending order} 26 | 27 | \item{facets}{(optional) field by which to aggregate (count) their frequency} 28 | 29 | \item{facet_size}{(optional) how many facet groups to include in the facet total (default = 10, max = 1000)} 30 | 31 | \item{query}{(optional) constructs a query over ALL fields, or a fielded query searching within specific fields. Fielded query terms should be separated by ` AND ` or ` OR `. See \href{https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax}{Elasticserach query strings} for more info.} 32 | } 33 | \value{ 34 | dataframe or list (for facetted queries) containing the response of the API query 35 | } 36 | \description{ 37 | Access outbreak.info Research Library API 38 | } 39 | \examples{ 40 | # Return only the first 10 hits for "ivermectin" 41 | df = getResourcesResponse("ivermectin", size = 10) 42 | 43 | # Find the first 10 results which contain the variable `topicCategory` 44 | df = getResourcesResponse("_exists_:topicCategory", size = 10) 45 | 46 | # Get `date`/`name` from the first 10 hits for the query "ivermectin" plus a count of the `@type` field for ALL results 47 | df = getResourcesResponse("ivermectin", size = 10, facets="@type", fields=c("date", "name")) 48 | } 49 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | template: 2 | params: 3 | ganalytics: G-VK9KSJ8ENE 4 | bootswatch: flatly 5 | reference: 6 | - title: "SARS-CoV-2 Variant Prevalence" 7 | desc: > 8 | Functions to track SARS-CoV-2 variant prevalence worldwide, by country, 9 | by state/province, or by U.S. county. All sequence data is provided by 10 | [GISAID](https://www.gisaid.org/). Note that these functions require free 11 | **[registration with GISAID](https://www.gisaid.org/registration/register/)**, and 12 | you'll need to call `authenticateUser()` at the start of each session. 13 | - contents: 14 | - genomicsDataDictionary 15 | - authenticateUser 16 | - getAllLineagesByLocation 17 | - getCollectionDateByLocation 18 | - getGenomicData 19 | - getGlobalPrevalence 20 | - getLocationIdGenomic 21 | - getLag 22 | - starts_with("getMutation") 23 | - getPrevalence 24 | - getCumulativeBySubadmin 25 | - getSeqCounts 26 | - getSubmissionDateByLocation 27 | - getCuratedLineages 28 | - lookupSublineages 29 | - plotAllLineagesByLocation 30 | - plotChoropleth 31 | - plotMutationHeatmap 32 | - plotPrevalenceDotPlot 33 | - plotPrevalenceOverTime 34 | - title: "Research Library" 35 | desc: > 36 | Functions to track metadata of COVID-19 publications, clinical trials, datasets, protocols, and more. 37 | Note that unlike the variant prevalence functions, these functions **do not require a GISAID account** 38 | or a call to `authenticateUser()`to use them. 39 | - contents: 40 | - getResourcesData 41 | - getResourcesResponse 42 | - title: "Cases & Deaths" 43 | desc: > 44 | Functions to track COVID-19 cases and deaths worldwide, by country, 45 | by state/province, or by U.S. county. All epidemiological data is provided by 46 | the [Center for Systems Science and Engineering (CSSE)](https://github.com/CSSEGISandData/COVID-19) 47 | at Johns Hopkins University 48 | and the [New York Times](https://github.com/nytimes/covid-19-data). Note that unlike the variant prevalence functions, these functions **do not require a GISAID account** 49 | or a call to `authenticateUser()` to use them. 50 | - contents: 51 | - starts_with("getAdm") 52 | - epidemiologyDataDictionary 53 | - getByAdmnLevel 54 | - getCountryByRegion 55 | - getEpiData 56 | - getISO3 57 | - getLocationData 58 | - getMetroByCountry 59 | - plotEpiData 60 | - searchLocations 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 | -------------------------------------------------------------------------------- /R/plotPrevalenceDotPlot.R: -------------------------------------------------------------------------------- 1 | #' Plots a dot plot of prevalences of a variant in a specific location 2 | #' 3 | #' @param df Dataframe resulting from calling \link[outbreakinfo]{getCumulativeBySubadmin} 4 | #' @param title (optional) Title to include on the plot 5 | #' @param subtitle (optional) Subtitle to include on the plot 6 | #' @param dot_size (optional) Dot plot size (in mm) 7 | #' 8 | #' @import ggplot2 9 | #' 10 | #' @return 11 | #' @export 12 | #' 13 | #' @examples 14 | #' 15 | #' # Calculate the proportion of sequences assigned to BA.2 or BA.2.12.1 by U.S. State 16 | #' prev_by_state = getCumulativeBySubadmin(pangolin_lineage = c("BA.2", "BA.2.12.1"), location = "United States", ndays = 90) 17 | #' 18 | #' # Plot the results 19 | #' plotPrevalenceDotPlot(prev_by_state, "Prevalence over the last 90 days in the United States", subtitle = paste0("As of ", format(Sys.Date(), '%d %B %Y'))) 20 | 21 | plotPrevalenceDotPlot = function(df, title = NULL, subtitle = NULL, dot_size = 3) { 22 | if(!is.null(df) && nrow(df) > 0){ 23 | xlim = c(0, max(df$proportion)) 24 | 25 | if(length(unique(xlim)) == 1) 26 | xlim <- c(0,1) 27 | 28 | # Sort the values, so they're arranged from high to low prevalence 29 | sorted_locations = df %>% arrange(proportion) %>% pull(name) 30 | df$name = factor(df$name, sorted_locations) 31 | 32 | # color palette: ColorBrewer's YlGnBu:https://colorbrewer2.org/#type=sequential&scheme=YlGnBu&n=9 33 | CHOROPLETH_PALETTE = c('#ffffd9','#edf8b1','#c7e9b4','#7fcdbb','#41b6c4','#1d91c0','#225ea8','#253494','#081d58') 34 | 35 | 36 | ggplot(df, aes(x = proportion, y = name, fill = proportion)) + 37 | geom_segment(aes(x = proportion_ci_lower, xend = proportion_ci_upper, yend = name), alpha = 0.15, size = 3) + 38 | geom_point(size = dot_size, shape = 21) + 39 | scale_x_continuous(limits = xlim, labels = scales::percent) + 40 | scale_fill_gradientn(values = xlim, colours = CHOROPLETH_PALETTE) + 41 | ggtitle(title, subtitle = subtitle) + 42 | labs(caption="Enabled by data from GISAID (https://gisaid.org/)") + 43 | theme_minimal() + 44 | theme(panel.grid.major.y = element_blank(), 45 | panel.grid.minor.y = element_blank(), 46 | axis.title.y = element_blank(), 47 | legend.position = "bottom", 48 | plot.caption = element_text(size = 18)) 49 | } 50 | } -------------------------------------------------------------------------------- /man/getPrevalence.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getPrevalence.R 3 | \name{getPrevalence} 4 | \alias{getPrevalence} 5 | \title{Retrieve daily prevalence of a lineage by location} 6 | \usage{ 7 | getPrevalence( 8 | pangolin_lineage = NULL, 9 | location = NULL, 10 | mutations = NULL, 11 | cumulative = FALSE, 12 | logInfo = TRUE 13 | ) 14 | } 15 | \arguments{ 16 | \item{pangolin_lineage}{(optional) PANGO lineage name or vector of PANGO lineage names. Either `pangolin_lineage` or `mutations` needs to be specified. A list of lineages will return a long dataframe with `lineage` as a variable; if you want to calculate the prevalence of lineage1 or lineage2 together, enter the lineages separated by " OR ". For instance, to calculate the prevalence of Delta, you'll need to supply `"B.1.617.2 OR AY.1 OR AY.2 OR ..."` **Be sure to include the space around "OR" and it must be capitalized.**} 17 | 18 | \item{location}{(optional) a location name} 19 | 20 | \item{mutations}{(optional) a `vector` of mutation(s). Either `pangolin_lineage` or `mutations` needs to be specified. Mutations should be specified in the format `gene:mutation`, like "S:E484K"} 21 | 22 | \item{cumulative}{(optional) `Boolean` (T/F), T returns cumulative prevalence since first day of detection} 23 | 24 | \item{logInfo}{(optional) `Boolean` (T/F), T logs helper messages during API calls.} 25 | } 26 | \value{ 27 | dataframe 28 | } 29 | \description{ 30 | Retrieves the daily prevalence of a PANGO lineage(s) by location 31 | } 32 | \examples{ 33 | # lineage: P.1 in Brazil 34 | p1_brazil = getPrevalence(pangolin_lineage = "P.1", location = "Brazil") 35 | 36 | # AY.4, AY.34, and B.1.617.2 in Brazil (AY.4, AY.34, and B.1.617.2 separately) 37 | delta_and_brazil = getPrevalence(pangolin_lineage = c("AY.4", "AY.34", "B.1.617.2"), location = "Brazil") 38 | delta_and_brazil[delta_and_brazil$date == "2021-09-01",] 39 | 40 | # AY.4 OR B.1.617.2 in Brazil (AY.4, AY.34 and B.1.617.2 combined) 41 | delta_or_brazil = getPrevalence(pangolin_lineage = "AY.4 OR AY.34 OR B.1.617.2", location = "Brazil") 42 | delta_or_brazil[delta_and_brazil$date == "2021-09-01",] 43 | 44 | # S:E484K mutation prevalence worldwide 45 | se484k = getPrevalence(mutations = c("S:E484K")) 46 | 47 | # B.1.1.7 + S:E484K mutation worldwide 48 | b117_se484k = getPrevalence(pangolin_lineage = "B.1.1.7", mutations = c("S:E484K")) 49 | } 50 | -------------------------------------------------------------------------------- /docs/locationvignette.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Location Report (United States)" 3 | date: "May 7, 2021" 4 | output: html_document 5 | --- 6 | 7 | ```{r setup, include=FALSE} 8 | knitr::opts_chunk$set(echo = TRUE) 9 | library(jsonlite) 10 | library(ggplot2) 11 | library(readr) 12 | library(dplyr) 13 | library(purrr) 14 | library(outbreakinfo) 15 | ## source("../outbreakfunc.R") 16 | ``` 17 | 18 | ------ 19 | 20 | #### **Lineage prevalence in United States** 21 | *Lineages without daily prevalence > 3% on at least 5 days in the last 60 are grouped into "Other"* 22 | 23 | 24 | ```{r} 25 | p <- plotAllLineagesByLocation(location = "United States of America", other_threshold = 0.03, nday_threshold = 5, ndays = 60) 26 | p <- p + scale_fill_brewer(palette="Set1") 27 | show(p) 28 | ``` 29 | 30 | ------- 31 | 32 | #### **Characteristic S-gene mutations in common lineages** 33 | *Mutations in at least 75% of sequences* 34 | 35 | ```{r} 36 | lineage_df <- getAllLineagesByLocation("United States") 37 | 38 | lineage_list <- lineage_df %>% 39 | dplyr::filter(lineage != "other") %>% 40 | dplyr::pull(lineage) %>% 41 | unique() 42 | 43 | df_ll <- lineage_list %>% 44 | purrr::map_dfr(~{getMutationsByLineage(.x, frequency=0) %>% 45 | dplyr::mutate(lineage_name = .x)}) 46 | 47 | mut_df <- df_ll %>% 48 | dplyr::filter(prevalence > 0.75) %>% 49 | dplyr::pull(mutation) %>% 50 | unique() 51 | 52 | df_ll <- df_ll %>% 53 | dplyr::filter(mutation %in% mut_df) 54 | 55 | df_ll <- df_ll %>% 56 | dplyr::filter(gene == "S") 57 | 58 | p <- ggplot(df_ll, aes(mutation, lineage_name, fill = prevalence)) + geom_tile(color = "grey") + scale_fill_gradient2(labels = scales::percent, midpoint = 0.5, low = "#fff7f3", mid = "#f768a1", high = "#49006a") + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank()) + coord_equal() + ggtitle("Characteristic S-gene mutations in common lineages in the United States") 59 | 60 | show(p) 61 | ``` 62 | 63 | ------- 64 | 65 | #### **Tracked variants of concern in the United States** 66 | 67 | ```{r} 68 | voc <- c("B.1.1.7", "B.1.617.2", "P.1", "B.1.351") 69 | voc_df = NULL 70 | for (i in voc){ 71 | df <- getPrevalenceByLocation(i, "United States", cumulative=T) 72 | df <- cbind(lineage = i, df) 73 | voc_df = rbind(voc_df, df) 74 | } 75 | knitr::kable(voc_df) 76 | ``` 77 | -------------------------------------------------------------------------------- /man/getResourcesData.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/getResourcesData.R 3 | \name{getResourcesData} 4 | \alias{getResourcesData} 5 | \title{Get COVID-19 resource metadata} 6 | \usage{ 7 | getResourcesData( 8 | query = NULL, 9 | types = NULL, 10 | size = 10, 11 | fetchAll = FALSE, 12 | fields = NULL, 13 | sort = NULL, 14 | facets = NULL, 15 | facet_size = 10 16 | ) 17 | } 18 | \arguments{ 19 | \item{query}{(optional) constructs a query over ALL fields, or a fielded query searching within specific fields. Fielded query terms should be separated by ` AND ` or ` OR `. See \href{https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax}{Elasticserach query strings} for more info.} 20 | 21 | \item{types}{(optional) vector of resource type to return. The most frequent types include: "Publication", "ClinicalTrial", "Dataset", "Protocol", "SoftwareSourceCode", "Analysis".} 22 | 23 | \item{size}{(optional) number of records to return (default = 10)} 24 | 25 | \item{fetchAll}{(optional) Boolean whether to return all results for the query} 26 | 27 | \item{fields}{(optional) vector specifying which fields to return. Returns all by default. See the \href{https://discovery.biothings.io/view/outbreak}{outbreak schema} for possible fields.} 28 | 29 | \item{sort}{(optional) field to sort by. Add `-` to sort in descending order} 30 | 31 | \item{facets}{(optional) field by which to aggregate (count) their frequency} 32 | 33 | \item{facet_size}{(optional) how many facet groups to include in the facet total (default = 10, max = 1000)} 34 | } 35 | \value{ 36 | 37 | } 38 | \description{ 39 | Get COVID-19 resource metadata 40 | } 41 | \examples{ 42 | library(dplyr) 43 | # Get the date latest date for every resource (newest of dateModified, dateCreated, datePublished) 44 | resources_by_date = getResourcesData(query = "date:[2020-01-01 TO *]", fields = "date") 45 | 46 | # Get all metadata on remdesivir 47 | remdesivir = getResourcesData(query = "remdesivir", fetchAll = TRUE, fields = c("@type", "name", "curatedBy")) 48 | remdesivir \%>\% count(`@type`) \%>\% arrange(desc(n)) 49 | 50 | # Get all metadata for remdesivir Clinical Trials or Datasets 51 | remdesivir_trials_data = getResourcesData(query = "remdesivir", types = c("ClinicalTrial", "Dataset"), fetchAll = TRUE, fields = c("@type", "name", "curatedBy")) 52 | remdesivir_trials_data \%>\% count(`@type`) \%>\% arrange(desc(n)) 53 | } 54 | -------------------------------------------------------------------------------- /R/getResourcesData.R: -------------------------------------------------------------------------------- 1 | #' Get COVID-19 resource metadata 2 | #' 3 | #' @param query (optional) constructs a query over ALL fields, or a fielded query searching within specific fields. Fielded query terms should be separated by ` AND ` or ` OR `. See \href{https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax}{Elasticserach query strings} for more info. 4 | #' @param types (optional) vector of resource type to return. The most frequent types include: "Publication", "ClinicalTrial", "Dataset", "Protocol", "SoftwareSourceCode", "Analysis". 5 | #' @param size (optional) number of records to return (default = 10) 6 | #' @param fetchAll (optional) Boolean whether to return all results for the query 7 | #' @param fields (optional) vector specifying which fields to return. Returns all by default. See the \href{https://discovery.biothings.io/view/outbreak}{outbreak schema} for possible fields. 8 | #' @param sort (optional) field to sort by. Add `-` to sort in descending order 9 | #' @param facets (optional) field by which to aggregate (count) their frequency 10 | #' @param facet_size (optional) how many facet groups to include in the facet total (default = 10, max = 1000) 11 | #' 12 | #' @import stringr 13 | #' 14 | #' @return 15 | #' @export 16 | #' 17 | #' @examples 18 | #' library(dplyr) 19 | #' # Get the date latest date for every resource (newest of dateModified, dateCreated, datePublished) 20 | #' resources_by_date = getResourcesData(query = "date:[2020-01-01 TO *]", fields = "date") 21 | #' 22 | #' # Get all metadata on remdesivir 23 | #' remdesivir = getResourcesData(query = "remdesivir", fetchAll = TRUE, fields = c("@type", "name", "curatedBy")) 24 | #' remdesivir %>% count(`@type`) %>% arrange(desc(n)) 25 | #' 26 | #' # Get all metadata for remdesivir Clinical Trials or Datasets 27 | #' remdesivir_trials_data = getResourcesData(query = "remdesivir", types = c("ClinicalTrial", "Dataset"), fetchAll = TRUE, fields = c("@type", "name", "curatedBy")) 28 | #' remdesivir_trials_data %>% count(`@type`) %>% arrange(desc(n)) 29 | 30 | getResourcesData = function(query = NULL, types = NULL, size = 10, fetchAll = FALSE, fields = NULL, sort = NULL, facets = NULL, facet_size = 10) { 31 | 32 | # Append the `@type: filter` if selected 33 | if(!is.null(types)) { 34 | if(!is.null(query)) { 35 | query = str_c(query, " AND @type:(", paste(types, collapse = " OR "), ")") 36 | } else { 37 | query = str_c("@type:(", paste(types, collapse = " OR "), ")") 38 | } 39 | } 40 | 41 | return(getResourcesResponse(query, size, fetchAll, fields, sort, facets, facet_size)) 42 | } -------------------------------------------------------------------------------- /R/plotPrevalenceOverTime.R: -------------------------------------------------------------------------------- 1 | #' @title Plot daily prevalence of a lineage by location 2 | #' 3 | #' @description Plots the daily prevalence of a PANGO lineage by location 4 | #' 5 | #' @param df result of the call to \link[outbreakinfo]{getPrevalence} 6 | #' @param colorVar variable to used to color the line traces. `lineage` by default 7 | #' @param title (optional) Title to add to the plot 8 | #' @param labelDictionary (optional) a named list of values to replace in the plot legend. 9 | #' 10 | #' @import ggplot2 11 | #' 12 | #' @return ggplot2 object 13 | #' 14 | #'@examples 15 | #'p1_brazil <- getPrevalence(pangolin_lineage = "P.1", location = "Brazil") 16 | #'plotPrevalenceOverTime(p1_brazil) 17 | #' 18 | #'us <- getPrevalence(pangolin_lineage = c("B.1.1.7", "B.1.427 OR B.1.429", "B.1.617.2"), location = "United States") 19 | #'plotPrevalenceOverTime(us, labelDictionary = c("B.1.427 OR B.1.429" = "Epsilon")) 20 | #' 21 | #' # Overlay locations 22 | #' b117_india = getPrevalence(pangolin_lineage = "B.1.1.7", location = "India") 23 | #' b117_us = getPrevalence(pangolin_lineage = "B.1.1.7", location = "United States") 24 | #' b117_uk = getPrevalence(pangolin_lineage = "B.1.1.7", location = "United Kingdom") 25 | #' b117 = dplyr::bind_rows(b117_uk, b117_india, b117_us) 26 | #' plotPrevalenceOverTime(b117, colorVar = "location", title="B.1.1.7 prevalence over time") 27 | #' @export 28 | 29 | plotPrevalenceOverTime <- function(df, colorVar = "lineage", title = "Prevalence over time", labelDictionary = NULL) { 30 | if(!is.null(df) && nrow(df) > 0){ 31 | if(!is.null(labelDictionary)) { 32 | df = df %>% 33 | mutate(lineage = ifelse(is.na(unname(labelDictionary[lineage])), lineage, unname(labelDictionary[lineage]))) 34 | } 35 | 36 | p <- ggplot(df, aes(x = date, y = proportion, colour = .data[[colorVar]], fill = .data[[colorVar]], group = .data[[colorVar]])) + 37 | geom_ribbon(aes(ymin = proportion_ci_lower, ymax = proportion_ci_upper), alpha = 0.35, size = 0) + 38 | geom_line(size = 1.25) + 39 | scale_x_date(date_labels = "%b %Y", expand = c(0,0)) + 40 | scale_y_continuous(labels = scales::percent, expand = c(0,0)) + 41 | scale_colour_manual(values = COLORPALETTE[-1]) + 42 | scale_fill_manual(values = COLORPALETTE[-1]) + 43 | theme_minimal() + 44 | labs(caption="Enabled by data from GISAID (https://gisaid.org/)") 45 | theme(legend.position = "bottom", axis.title = element_blank(), plot.caption = element_text(size = 18)) 46 | 47 | 48 | if (!is.null(title)) { 49 | p <- p + ggtitle(title) 50 | } 51 | return(p) 52 | } else { 53 | warning("Dataframe is empty.") 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /R/plotMutationHeatmap.R: -------------------------------------------------------------------------------- 1 | #' Title Compare mutation prevalences between lineages 2 | #' 3 | #' @description Plots a heatamp of mutation prevalence across particular lineages. 4 | #' @param df Resulting dataframe from calling \link[outbreakinfo]{getMutationsByLineage} 5 | #' @param gene2Plot (optional) string containing which genes to include, e.g. "Orf1a" By default, will limit the mutations to those in the S-gene. 6 | #' @param title (optional) title to add to the plot 7 | #' @param lightBorders (optional) boolean; whether the borders between grid items should be separated with a light or dark border. 8 | #' 9 | #' @import stringr 10 | #' @import tidyr 11 | #' @return 12 | #' @export 13 | #' 14 | #' @examples 15 | #' p1 = getMutationsByLineage(pangolin_lineage = "P.1", frequency = 0.5) 16 | #' plotMutationHeatmap(p1, gene2Plot = "ORF1a") 17 | #' 18 | 19 | plotMutationHeatmap = function(df, gene2Plot = "S", title = NULL, lightBorders = TRUE) { 20 | MUTATIONPALETTE = c('#fff7f3','#fde0dd','#fcc5c0','#fa9fb5','#f768a1','#dd3497','#ae017e','#7a0177','#49006a') 21 | borderColour = ifelse(lightBorders, "#FFFFFF", "#555555") 22 | 23 | # Filter down to one gene 24 | if(!is.null(df) && nrow(df) != 0){ 25 | df = df %>% filter(gene == gene2Plot) 26 | } 27 | 28 | if(!is.null(df) && nrow(df) != 0){ 29 | df = df %>% 30 | rowwise() %>% 31 | mutate(mutation_simplified = toupper(str_split(mutation, ":")[[1]][2])) %>% 32 | arrange(codon_num) 33 | 34 | # create empty grid 35 | mutation_simplified = df %>% pull(mutation_simplified) %>% unique() 36 | lineage = df %>% pull(lineage) %>% unique() 37 | blank = crossing(lineage, mutation_simplified) 38 | 39 | # refactor the mutations to sort them 40 | blank$mutation_simplified = factor(blank$mutation_simplified, levels = mutation_simplified) 41 | df$mutation_simplified = factor(df$mutation_simplified, levels = mutation_simplified) 42 | 43 | p = ggplot(df, aes(x = mutation_simplified, y = lineage, fill = prevalence)) + 44 | geom_tile(colour = borderColour, fill = "#dedede", data = blank) + 45 | geom_tile(colour = borderColour) + 46 | theme_minimal() + 47 | coord_fixed() + 48 | xlab("mutation") + 49 | scale_fill_gradientn(colours = MUTATIONPALETTE, limits = c(0,1), labels = scales::percent) + 50 | labs(caption="Enabled by data from GISAID (https://gisaid.org/)") + 51 | theme(axis.text.x = element_text(angle = 45, vjust = 0.9, hjust=1), 52 | panel.grid = element_blank(), 53 | legend.position = "bottom", 54 | plot.caption = element_text(size = 18) 55 | ) 56 | 57 | if(!is.null(title)) { 58 | p = p + ggtitle(title) 59 | } 60 | return(p) 61 | } else { 62 | warning("No data found. Check if there are mutations present in the gene you specified.") 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /R/lookupSublineages.R: -------------------------------------------------------------------------------- 1 | #' Lookup sublineages for a given Pango lineage or WHO name 2 | #' 3 | #' @description Retrieve all sublineages of a given Pango lineage or WHO designation. 4 | #' Based on a phylogeny maintained by the [Pango team](https://github.com/cov-lineages/lineages-website/blob/master/data/lineages.yml) 5 | #' to grab all sublineages associated with a lineage, and a curated list of Variants of Concern, Variants of Interest, 6 | #' Variants Under Monitoring, and de-escalated variants maintained by the [outbreak.info team](https://outbreak.info/situation-reports) 7 | #' 8 | #' @param lineage String with the name of a Pango lineage or WHO name 9 | #' @param returnQueryString Boolean to return a query string to be piped into functions like \link[outbreakinfo]{getPrevalence} (collapses vector by `"OR"`) 10 | #' 11 | #' @import httr 12 | #' @import yaml 13 | #' @import dplyr 14 | #' @return list containing the sublineages associated with that lineage or WHO designation 15 | #' @export 16 | #' 17 | #' @examples 18 | #' # WHO-designated lineages 19 | #' lookupSublineages("epsilon") 20 | #' lookupSublineages("epsilon", returnQueryString = TRUE) 21 | #' # Pango lineage 22 | #' lookupSublineages("B.1.1.7") 23 | #' #' # Not a recognized lineage 24 | #' lookupSublineages("VOC-21APR-02") 25 | 26 | lookupSublineages = function (lineage, returnQueryString = FALSE) { 27 | curated = getCuratedLineages() 28 | who_lineage = curated %>% filter(tolower(who_name) == tolower(lineage)) %>% pull(pangolin_lineage) 29 | 30 | if(length(who_lineage) == 1){ 31 | # WHO lineage; convert the lineage to a list 32 | children = lapply(who_lineage[[1]], getSublineages) %>% unlist() 33 | } else { 34 | children = getSublineages(lineage) 35 | } 36 | if(returnQueryString) { 37 | return(paste(children, collapse = " OR ")) 38 | } else { 39 | return(children) 40 | } 41 | } 42 | 43 | getSublineages = function(lineage) { 44 | SUBLINEAGE_URL = "https://raw.githubusercontent.com/outbreak-info/outbreak.info/master/curated_reports_prep/lineages.yml" 45 | 46 | tryCatch({ 47 | sublineages_resp = GET(SUBLINEAGE_URL) 48 | 49 | if(sublineages_resp$status_code != 200) { 50 | stop("Cannot access the Pango sublineages dictionary. Please contact the outbreak.info team at help@outbreak.info.") 51 | } 52 | 53 | sublineages = yaml.load(content(sublineages_resp, as="text")) 54 | 55 | filtered = sublineages[sapply(sublineages, function(x) x$name == toupper(lineage))] 56 | if(length(filtered) == 1) { 57 | children = filtered[[1]]$children 58 | return(children) 59 | } else { 60 | warning(paste("Lineage", lineage, "not recognized as a Pango lineage")) 61 | } 62 | 63 | }, error = function(cond){ 64 | message(cond) 65 | stop("Cannot access the Pango sublineages dictionary. Please contact the outbreak.info team at help@outbreak.info."); 66 | }, warning = function(cond){ 67 | message(cond) 68 | }) 69 | } 70 | -------------------------------------------------------------------------------- /R/plotAllLineagesByLocation.R: -------------------------------------------------------------------------------- 1 | #' @title Plot prevalence of lineages by location 2 | #' 3 | #' @description Plot prevalence of all lineages above a specified frequency over time by location 4 | #' 5 | #'@param location a location name 6 | #'@param other_threshold minimum prevalence threshold below which lineages are accumulated under "Other" (default=0.05) 7 | #'@param nday_threshold minimum number of days in which the prevalence of a lineage must be below other_threshold to be accumulated under "Other" (default=10) 8 | #'@param ndays the number of days before the current date to be used as a window to accumulate lineages under "Other" (default=180) 9 | #'@param other_exclude (optional) lineage(s) that are NOT to be included under "Other" even if the conditions specified by the three thresholds above are met 10 | #'@param cumulative `Boolean` (T/F), T returns cumulative prevalence of lineages (default=F) 11 | #'@param include_title `Boolean` (T/F), T returns plot with title, F returns plot without title (default=F) 12 | #' 13 | #'@import dplyr 14 | #'@import stringr 15 | #'@return ggplot2 object 16 | #' 17 | #'@examples 18 | #'plotAllLineagesByLocation(location = "India", other_threshold=0.03, ndays=60) 19 | #' 20 | #' @export 21 | 22 | plotAllLineagesByLocation <- function(location, other_threshold=0.05, nday_threshold=10, ndays=180, other_exclude=NULL, cumulative=FALSE, include_title = TRUE){ 23 | df <- getGenomicData(query_url="prevalence-by-location-all-lineages", location = location, other_threshold = other_threshold, nday_threshold = nday_threshold, ndays = ndays, other_exclude = other_exclude, cumulative = cumulative) 24 | 25 | if(is.null(df)) 26 | return(df) 27 | 28 | # set factors 29 | df$lineage = factor(df$lineage, levels = unique(c("other", df %>% arrange(desc(prevalence_rolling)) %>% pull(lineage)))) 30 | numLineages = levels(df$lineage) %>% length() 31 | # set anything beyond the 21 color palette to grey 32 | if(numLineages > length(COLORPALETTE)){ 33 | COLORPALETTE = c(COLORPALETTE, rep("#bab0ab", numLineages - length(COLORPALETTE))) 34 | } 35 | 36 | cat("Plotting data...", "\n") 37 | p <- ggplot(df, aes(x=date, y=prevalence_rolling, group=lineage, fill=lineage)) + 38 | geom_area(colour = "#555555", size = 0.2) + 39 | scale_x_date(date_labels = "%b %Y", expand = c(0,0)) + 40 | scale_y_continuous(labels = scales::percent, expand = c(0,0)) + 41 | scale_fill_manual(values = COLORPALETTE) + 42 | theme_minimal() + 43 | labs(caption="Enabled by data from GISAID (https://gisaid.org/)") + 44 | theme(legend.position = "bottom", legend.background = element_rect(fill = "#eeeeec", colour = NA), 45 | panel.grid = element_blank(), 46 | axis.ticks = element_line(size = 0.5, colour = "#555555"), axis.ticks.length = unit(5, "points"), 47 | axis.title = element_blank()) + 48 | theme(legend.position = "bottom", axis.title = element_blank(), plot.caption = element_text(size = 18)) 49 | 50 | if (include_title == T){ 51 | p <- p + 52 | ggtitle(paste0("Lineage prevalence in ", str_to_title(location))) 53 | } 54 | return(p) 55 | } 56 | -------------------------------------------------------------------------------- /R/getPrevalence.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve daily prevalence of a lineage by location 2 | #' 3 | #' @description Retrieves the daily prevalence of a PANGO lineage(s) by location 4 | #' 5 | #' @param pangolin_lineage (optional) PANGO lineage name or vector of PANGO lineage names. Either `pangolin_lineage` or `mutations` needs to be specified. A list of lineages will return a long dataframe with `lineage` as a variable; if you want to calculate the prevalence of lineage1 or lineage2 together, enter the lineages separated by " OR ". For instance, to calculate the prevalence of Delta, you'll need to supply `"B.1.617.2 OR AY.1 OR AY.2 OR ..."` **Be sure to include the space around "OR" and it must be capitalized.** 6 | #' @param mutations (optional) a `vector` of mutation(s). Either `pangolin_lineage` or `mutations` needs to be specified. Mutations should be specified in the format `gene:mutation`, like "S:E484K" 7 | #' @param location (optional) a location name 8 | #' @param cumulative (optional) `Boolean` (T/F), T returns cumulative prevalence since first day of detection 9 | #' @param logInfo (optional) `Boolean` (T/F), T logs helper messages during API calls. 10 | #' 11 | #' @return dataframe 12 | #' 13 | #' @import purrr 14 | #' 15 | #' @examples 16 | #' # lineage: P.1 in Brazil 17 | #' p1_brazil = getPrevalence(pangolin_lineage = "P.1", location = "Brazil") 18 | #' 19 | #' # AY.4, AY.34, and B.1.617.2 in Brazil (AY.4, AY.34, and B.1.617.2 separately) 20 | #' delta_and_brazil = getPrevalence(pangolin_lineage = c("AY.4", "AY.34", "B.1.617.2"), location = "Brazil") 21 | #' delta_and_brazil[delta_and_brazil$date == "2021-09-01",] 22 | #' 23 | #' # AY.4 OR B.1.617.2 in Brazil (AY.4, AY.34 and B.1.617.2 combined) 24 | #' delta_or_brazil = getPrevalence(pangolin_lineage = "AY.4 OR AY.34 OR B.1.617.2", location = "Brazil") 25 | #' delta_or_brazil[delta_and_brazil$date == "2021-09-01",] 26 | #' 27 | #' # S:E484K mutation prevalence worldwide 28 | #' se484k = getPrevalence(mutations = c("S:E484K")) 29 | #' 30 | #' # B.1.1.7 + S:E484K mutation worldwide 31 | #' b117_se484k = getPrevalence(pangolin_lineage = "B.1.1.7", mutations = c("S:E484K")) 32 | #' @export 33 | 34 | 35 | 36 | getPrevalence <- function(pangolin_lineage=NULL, location=NULL, mutations=NULL, cumulative=FALSE, logInfo=TRUE){ 37 | if(is.null(pangolin_lineage) && is.null(mutations)) { 38 | stop("Either `pangolin_lineage` or `mutations` needs to be specified") 39 | } 40 | 41 | if(length(pangolin_lineage) > 1) { 42 | df <- map_df(pangolin_lineage, function(lineage) getGenomicData(query_url="prevalence-by-location", pangolin_lineage = lineage, location = location, mutations = mutations, cumulative = cumulative, logInfo = logInfo)) 43 | } else { 44 | df <- getGenomicData(query_url="prevalence-by-location", pangolin_lineage = pangolin_lineage, location = location, mutations = mutations, cumulative = cumulative, logInfo = logInfo) 45 | } 46 | 47 | 48 | if(!is.null(df) && nrow(df) != 0 && cumulative == FALSE){ 49 | df <- df %>% 50 | rename(lineage = query_key) %>% 51 | mutate(location = ifelse(is.null(location), "Worldwide", location)) 52 | } 53 | 54 | if(!is.null(df) && nrow(df) != 0 && cumulative == TRUE){ 55 | df <- df %>% 56 | rename(lineage = key) %>% 57 | mutate(location = ifelse(is.null(location), "Worldwide", location)) 58 | } 59 | 60 | return(df) 61 | } 62 | -------------------------------------------------------------------------------- /R/getGenomicData.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve data from api.outbreak.info/genomics 2 | #' 3 | #' @description Retrieves up-to-date COVID-19 genomic data from outbreak.info according to user specifications. 4 | #' 5 | #' 6 | #' @return dataframe 7 | #' @export 8 | #' 9 | #' @examples 10 | #' uk_b117 = getGenomicData(query_url="prevalence-by-location", location="United Kingdom", pangolin_lineage = "B.1.1.7") 11 | #' head(uk_b117) 12 | 13 | getGenomicData <- function(query_url, location=NULL, cumulative=NULL, pangolin_lineage=NULL, mutations=NULL, ndays=NULL, frequency=NULL, subadmin=NULL, other_threshold=NULL, nday_threshold=NULL, other_exclude=NULL, logInfo=TRUE){ 14 | 15 | genomic_url <- "https://api.outbreak.info/genomics/" 16 | 17 | q <- c() 18 | 19 | q <- c(q, paste0(query_url), "?") 20 | 21 | if(!is.null(location)){ 22 | location <- getLocationIdGenomic(location) 23 | if(length(location) == 0){ 24 | cat(paste0("Could not find location ", location, "\n")) 25 | return(NULL) 26 | } 27 | q <- c(q, paste0("location_id=", location, "&")) 28 | } 29 | if(!is.null(cumulative)){ 30 | if (!is.logical(cumulative)){ 31 | stop("cumulative must be in Boolean format") 32 | }else{ 33 | q <- c(q, paste0("cumulative=", tolower(cumulative)), "&") 34 | } 35 | } 36 | if(!is.null(subadmin)){ 37 | if (!is.logical(subadmin)){ 38 | stop("subadmin must be in Boolean format") 39 | }else{ 40 | q <- c(q, paste0("subadmin=", tolower(subadmin)), "&") 41 | } 42 | } 43 | if(!is.null(pangolin_lineage)){ 44 | q <- c(q, paste0("pangolin_lineage=", pangolin_lineage, "&")) 45 | } 46 | if(!is.null(mutations)){ 47 | check_cond <- grepl("[A-Za-z0-9]+:[A-Za-z][0-9]+[A-Za-z]", mutations) 48 | if(!all(check_cond)) 49 | warning(paste0("Mutations should be specified in the format gene:mutation, like \"S:E484K\". The following mutations are not in the specified format: ", paste(mutations[!check_cond], collapse=", "))) 50 | mutations <- paste(mutations, collapse=" AND ") 51 | q <- c(q, paste0("mutations=", mutations, "&")) 52 | } 53 | if(!is.null(ndays)){ 54 | q <- c(q, paste0("ndays=", ndays, "&")) 55 | } 56 | if(!is.null(frequency)){ 57 | q <- c(q, paste0("frequency=", frequency, "&")) 58 | } 59 | if(!is.null(other_threshold)){ 60 | q <- c(q, paste0("other_threshold=", other_threshold, "&")) 61 | } 62 | if(!is.null(nday_threshold)){ 63 | q <- c(q, paste0("nday_threshold=", nday_threshold, "&")) 64 | } 65 | if(!is.null(other_exclude)){ 66 | other_exclude <- paste(other_exclude, collapse=",") 67 | q <- c(q, paste0("other_exclude=", other_exclude, "&")) 68 | } 69 | 70 | q <- paste(q, sep="", collapse = "") 71 | q <- sub("&$", "", q) 72 | 73 | dataurl <- paste0(genomic_url, q) 74 | results <- getGenomicsResponse(dataurl, logInfo); 75 | 76 | if (length(results) > 1){ 77 | hits <- rbind_pages(results) 78 | }else{ 79 | hits <- data.frame(results) 80 | } 81 | if ("date" %in% colnames(hits)){ 82 | hits$date=as.Date(hits$date, "%Y-%m-%d") 83 | hits <- hits[order(as.Date(hits$date, format = "%Y-%m-%d")),] 84 | } 85 | return(hits) 86 | } 87 | -------------------------------------------------------------------------------- /outbreakinfo/R/getGenomicsResponse.R~: -------------------------------------------------------------------------------- 1 | #' Get response from genomics endpoint 2 | #' @param dataurl genomics endpoint to be queried 3 | #' @NoRd 4 | #' 5 | 6 | ## If object is a list, return a long dataframe with query_key as new column. 7 | ## If object is a dataframe, return the object directly 8 | ## If object is neither, throw warning and return NULL 9 | convert_list_to_dataframe <- function(list_obj){ 10 | if(!(class(list_obj) %in% c("list", "data.frame"))){ 11 | warning("Supplied object is not a list or dataframe") 12 | return(NULL) 13 | } 14 | if(class(list_obj) == "data.frame"){ 15 | return(list_obj) 16 | } 17 | ## If list add a "query_key" column 18 | query_keys <- names(list_obj) 19 | res <- lapply(query_keys, 20 | function(query_key) { 21 | d <- list_obj[[query_key]] 22 | d$query_key <- query_key 23 | return(d) 24 | }) 25 | res_df <- do.call(rbind, res) 26 | return(res_df); 27 | } 28 | 29 | 30 | getGenomicsResponse <- function(dataurl){ 31 | scroll.id <- NULL 32 | results <- list() 33 | success <- NULL 34 | while(is.null(success)){ 35 | success <- FALSE 36 | cat("Retrieving data...", "\n") 37 | dataurl <- ifelse(is.null(scroll.id), dataurl, paste0(dataurl, "&scroll_id=", scroll.id)) 38 | dataurl <- URLencode(dataurl) 39 | resp <- NULL 40 | tryCatch({ 41 | if(Sys.getenv("OUTBREAK_INFO_TOKEN") != ""){ 42 | resp <- GET( 43 | dataurl, 44 | add_headers(Authorization = paste("Bearer", Sys.getenv("OUTBREAK_INFO_TOKEN"), sep=" ")) 45 | ) 46 | } else { 47 | resp <- GET( 48 | dataurl 49 | ) 50 | } 51 | auth_token = resp$headers$`x-auth-token` 52 | if(!is.null(auth_token)) 53 | Sys.setenv(OUTBREAK_INFO_TOKEN = auth_token) 54 | if(resp$status_code == 401){ 55 | warning("Please authenticateUser by calling authenticateUser() to access the API.") 56 | } else if (resp$status_code == 403) { 57 | warning("Invalid taken. Please reauthenticateUser by calling the authenticateUser() function.") 58 | } else if(resp$status_code == 500){ 59 | warning("There was an internal server error. Please cross check your query or contact help@outbreak.info for further assistance.") 60 | } else if(resp$status_code == 429){ 61 | warning("You have exceeded the API usage limit. Please limit the usage to 1 request/minute.") 62 | } else if (resp$status_code == 400){ 63 | warning("Malformed token. Please reauthenticateUser by calling the authenticateUser() function.") 64 | } else if(resp$status_code == 200){ 65 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 66 | resp_df <- convert_list_to_dataframe(resp$results) 67 | results[[length(results) + 1]] <- resp_df 68 | scroll.id <- resp$'_scroll_id' 69 | success <- resp$success 70 | return(results); 71 | } 72 | }, error = function(cond){ 73 | message(cond) 74 | stop("Could not connect to API. Please check internet connection and try again."); 75 | }, warning = function(cond){ 76 | message(cond) 77 | }) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /R/epidemiologyDataDictionary.R: -------------------------------------------------------------------------------- 1 | #' @title Documentation of Epidemiology API fields 2 | #' 3 | #' @description Documents fields included when extracting data from outbreak.info 4 | #' 5 | #' @return dataframe 6 | #' 7 | #' @examples 8 | #' df = epidemiologyDataDictionary() 9 | #' knitr::kable(df) 10 | #' 11 | #' @export 12 | 13 | epidemiologyDataDictionary <- function(){ 14 | df = data.frame("API Field" = c("admin_level", "cbsa", "confirmed", "confirmed_doublingRate", "confirmed_firstDate", "confirmed_newToday", "confirmed_numIncrease", "confirmed_pctIncrease", "confirmed_per_100k", "confirmed_rolling", "confirmed_rolling_14days_ago", "confirmed_rolling_14days_ago_diff", "confirmed_rolling_per_100k", "country_gdp_per_capita", "country_iso3", "country_name", "country_population", "date", "daysSince100Cases", "daysSince10Deaths", "daysSince50Deaths", "dead", "dead_doublingRate", "dead_firstDate", "dead_newToday", "dead_numIncrease", "dead_pctIncrease", "dead_per_100k", "dead_rolling", "dead_rolling_14days_ago", "dead_rolling_14days_ago_diff", "dead_rolling_per_100k", "first_dead-first_confirmed", "gdp_last_updated", "gdp_per_capita", "iso3", "lat", "location_id", "long", "mostRecent", "name", "num_subnational", "population", "state_iso3", "state_name", "sub_parts", "wb_region"), 15 | "Documentation" = c("Administrative level (World Bank regions = -1, countries = 0, states/provinces = 1, metropolitan areas = 1.5, counties = 2)", "Metropolitan area FIPS code", "Total number of confirmed COVID-19 cases", "Doubling rate of confirmed COVID-19 cases (number of days for COVID-19 cases to double)", "Date of first confirmed COVID-19 case", "T if new COVID-19 cases reported, F if none", "Number of new confirmed COVID-19 cases", "Percent increase in confirmed COVID-19 cases", "Total number of confirmed COVID-19 cases per 100,000 persons", "Weekly rolling average of new confirmed COVID-19 cases", "Weekly rolling average of new confirmed COVID-19 cases 14 days prior", "Difference between a weekly rolling average of new confirmed COVID-19 cases and the weekly rolling average of new confirmed COVID-19 cases 14 days prior", "Weekly rolling average of new confirmed COVID-19 cases per 100,000 persons", "Country GDP per capita", "Country ISO3", "Country name", "Total population of country", "Date", "Days since 100 new confirmed cases of COVID-19 reported", "Days since 10 new deaths due to COVID-19 reported", "Days since 50 new deaths due to COVID-19 reported", "Total number of deaths due to COVID-19", "Doubling rate of deaths due to COVID-19 (number of days for deaths due to COVID-19 to double)", "Date of first death due to COVID-19", "T if new deaths due to COVID-19 reported, F if none", "Number of new deaths due to COVID-19", "Percent increase in deaths due to COVID-19", "Total number of deaths due to COVID-19 per 100,000 persons", "Weekly rolling average of new deaths due to COVID-19", "Weekly rolling average of new deaths due to COVID-19 14 days prior", "Difference between a weekly rolling average of new deaths due to COVID-19 and the weekly rolling average of new deaths due to COVID-19 14 days prior", "Weekly rolling average of new deaths due to COVID-19 per 100,000 persons", "Number of days between first confirmed case of COVID-19 and first death due to COVID-19", "Year that GDP was last updated", "GDP per capita", "ISO3 code", "Latitude", "Location code", "Longitude", "T for most recent row of data, F for all others", "Location name", "Number of administrative divisions", "Total population", "State ISO3 code", "State name", "County name, county FIPS code, state name", "World Bank region"), 16 | stringsAsFactors = FALSE, 17 | check.names = F) 18 | return(df) 19 | } 20 | -------------------------------------------------------------------------------- /R/getLocationIdGenomic.R: -------------------------------------------------------------------------------- 1 | #' @title Get location id codes from genomic API 2 | #' 3 | #' @description Get location ID code for countries, states/provinces, metropolitan areas, and/or counties from genomic API 4 | #' 5 | #' @param locations_to_search a location name 6 | #' 7 | #' @return a location ID code (ISO3, FIPS) 8 | #' 9 | #' @examples 10 | #' getLocationIdGenomic("San Diego") 11 | #' 12 | #' @export 13 | 14 | getLocationIdGenomic <- function(locations_to_search){ 15 | loc_url <- "https://api.outbreak.info/genomics/location?" 16 | locs_of_interest=c() 17 | locs_not_found=c() 18 | for (i in locations_to_search){ 19 | location.ids <- paste0("name=", paste(i)) 20 | dataurl <- paste0(loc_url, location.ids) 21 | results <- getGenomicsResponse(dataurl, logInfo = F, logWarning = T, logError = T) 22 | hits <- data.frame() 23 | if(length(results) >= 1) 24 | hits <- rbind_pages(results) 25 | if(nrow(hits) == 0){ 26 | locs_not_found = c(locs_not_found, i) 27 | } else { 28 | hits <- rbind_pages(results) 29 | df=(hits) 30 | if (nrow(df)==1){ 31 | locs_of_interest=c(locs_of_interest, df$id) 32 | }else{ 33 | locs_not_found=c(locs_not_found, i) 34 | } 35 | } 36 | } 37 | if (length(locs_of_interest)==length(locations_to_search)){ 38 | return(locs_of_interest) 39 | } 40 | if (length(locs_of_interest)!=length(locations_to_search)){ 41 | locations=c() 42 | for (i in locs_not_found){ 43 | if (grepl(" ", i, fixed=TRUE)==T){ 44 | locs=paste0("*",i,"*") 45 | }else{ 46 | locs=paste0("*",i,"*") 47 | } 48 | locations=c(locations, locs) 49 | } 50 | for (i in 1:length(locations)){ 51 | location.ids <- paste0("name=", paste(locations[i])) 52 | dataurl <- paste0(loc_url, location.ids) 53 | results <- getGenomicsResponse(dataurl, F, logWarning = F, logError = T) 54 | hits <- data.frame() 55 | if(length(results) >= 1) 56 | hits <- rbind_pages(results) 57 | if(nrow(hits) == 0){ 58 | next 59 | } else { 60 | df=(hits) 61 | df$admin_level[df$admin_level == "-1"] <- "World Bank Region" 62 | df$admin_level[df$admin_level == "0"] <- "country" 63 | df$admin_level[df$admin_level == "1"] <- "state/province" 64 | df$admin_level[df$admin_level == "1.5"] <- "metropolitan area" 65 | df$admin_level[df$admin_level == "2"] <- "county" 66 | df$full <- paste0(df$label, " (", df$admin_level, ")") 67 | for (i in df$full){ 68 | cat(paste0(i, "\n")) 69 | loc_sel <- readline("Is this a location of interest? (Y/N): ") 70 | if ((loc_sel == "Y")|(loc_sel == "y")){ 71 | locs_of_interest = c(locs_of_interest, df$id[df$full==i]) 72 | break 73 | } 74 | if ((loc_sel != "Y")&(loc_sel != "y")&(loc_sel != "N")&(loc_sel != "n")){ 75 | cat("Expected input is Y or N\n\n") 76 | cat(i) 77 | loc_sel <- readline("Is this a location of interest? (Y/N): ") 78 | if ((loc_sel == "Y")|(loc_sel == "y")){ 79 | locs_of_interest = c(locs_of_interest, df$id[df$full==i]) 80 | break 81 | } 82 | } 83 | } 84 | } 85 | } 86 | } 87 | return(locs_of_interest) 88 | } 89 | -------------------------------------------------------------------------------- /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 | $("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.replace(/\n#>[^\n]*/g, ""); 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 | -------------------------------------------------------------------------------- /R/plotEpiData.R: -------------------------------------------------------------------------------- 1 | #' @title Plot COVID-19 data of interest 2 | #' 3 | #' @description Plot a metric of interest using up-to-date COVID-19 data from outbreak.info for location(s) of interest (World Bank region, country, state/province, metropolitan area, county). 4 | #' 5 | #'@param locations a vector or list of location names 6 | #'@param variable metric to plot 7 | #' 8 | #' @return ggplot2 object 9 | #' 10 | #' @import ggplot2 11 | #' @import progress 12 | #' 13 | #' @examples 14 | #' p = plotEpiData("Florida", "confirmed_per_100k") 15 | #' show(p) 16 | #' 17 | #' @export 18 | 19 | 20 | plotEpiData <- function(locations, variable){ 21 | if (missing(variable)){ 22 | stop("Variable to plot not specified") 23 | } 24 | location_codes <- getISO3(locations) 25 | df <- getEpiData(location_id=location_codes) 26 | 27 | if (!(variable %in% colnames(df))){ 28 | print(paste(variable, "is not a valid API field")) 29 | return(NULL) 30 | } 31 | 32 | # Hard-coded settings 33 | variable_dict = list(confirmed = "Cumulative COVID-19 cases", 34 | confirmed_numIncrease = "Daily new COVID-19 cases", 35 | confirmed_numIncrease_per_100k = "Daily new COVID-19 cases per 100,000 residents", 36 | confirmed_rolling_per_100k = "Daily new COVID-19 cases per 100,000 residents", 37 | confirmed_rolling = "Daily new COVID-19 cases", 38 | confirmed_per_100k = "Cumulative COVID-19 cases per 100,000 residents", 39 | dead = "Cumulative COVID-19 deaths", 40 | dead_numIncrease = "Daily new COVID-19 deaths", 41 | dead_numIncrease_per_100k = "Daily new COVID-19 deaths per 100,000 residents", 42 | dead_rolling_per_100k = "Daily new COVID-19 deaths per 100,000 residents", 43 | dead_rolling = "Daily new COVID-19 deaths", 44 | dead_per_100k = "Cumulative COVID-19 deaths per 100,000 residents" 45 | ) 46 | subtitle_dict = list(confirmed_rolling = "7 day rolling average", 47 | confirmed_rolling_per_100k = "7 day rolling average", 48 | dead_rolling = "7 day rolling average", 49 | dead_rolling_per_100k = "7 day rolling average") 50 | 51 | 52 | title = variable_dict[[variable]] 53 | subtitle = subtitle_dict[[variable]] 54 | 55 | title = ifelse(is.null(title), variable, title) 56 | 57 | colour_palette = c("#507ea3","#f28e2c","#e15759","#76b7b2","#59a14f","#edc949","#b475a3","#ff98a8","#9c755f","#bab0ab","#154d7e","#ba6000","#aa2230","#418d88","#277223","#b7990e","#834874","#828282") 58 | 59 | # plot 60 | # Plot a bargraph if the values are daily increases 61 | daily_variables = c("confirmed_numIncrease", "dead_numIncrease") 62 | if(variable %in% daily_variables) { 63 | p = ggplot(df, aes(date, get(variable), fill = name, group = name)) + 64 | geom_bar(stat = "identity") + 65 | scale_fill_manual(values = colour_palette) + 66 | theme_minimal() + 67 | theme(legend.position = "none") + 68 | facet_wrap(~name ) 69 | } else { 70 | p = ggplot(df, aes(date, get(variable), color = name, group = name)) + 71 | geom_line(size = 1.25) + 72 | theme_minimal() + 73 | theme(legend.position = "bottom", 74 | legend.background = element_rect(fill = "#eeeeec", colour = NA)) + 75 | scale_colour_manual(values = colour_palette) 76 | } 77 | 78 | nrow = ceiling(length(locations)/3) 79 | 80 | p = p + 81 | scale_x_date(date_labels = "%b %Y") + 82 | scale_y_continuous(labels = scales::comma) + 83 | theme(text = element_text(size = 16), 84 | legend.title = element_blank(), 85 | axis.title = element_blank()) + 86 | ggtitle(title, subtitle = subtitle) + 87 | guides(colour = guide_legend(nrow = nrow)) 88 | return(p) 89 | } 90 | 91 | -------------------------------------------------------------------------------- /R/authenticateUser.R: -------------------------------------------------------------------------------- 1 | OUTBREAK_INFO_AUTH = "https://api.outbreak.info/genomics/get-auth-token" 2 | 3 | #' @title Authenticate API 4 | #' 5 | #' @description Authenticate API to get access to genomics data 6 | #' 7 | #' @import httr 8 | #' @import crayon 9 | #' 10 | #' @return url 11 | #' 12 | #' @examples 13 | #'# Authenticate with GISAID credentials 14 | #'# authenticateUser() 15 | #' @export 16 | authenticateUser <- function(){ 17 | response <- POST(OUTBREAK_INFO_AUTH, body = '{}', encode = "raw") 18 | if (status_code(response) == 200) { 19 | response_content <- content(response) 20 | authToken <- response_content$authn_token 21 | setAuthToken(authToken) 22 | cat(paste("Please open this url in a browser and authenticate with your GISAID credentials.", response_content$authn_url, sep="\n\n")) 23 | browseURL(response_content$authn_url) 24 | } else { 25 | print("Could not get authentication-token") 26 | } 27 | start_time <- Sys.time() 28 | Sys.sleep(5) 29 | while (TRUE) { 30 | cat("\n\nWaiting for authentication... [press CTRL-C to abort]") 31 | response <- GET( 32 | OUTBREAK_INFO_AUTH, 33 | add_headers(Authorization = paste("Bearer", getAuthToken(), sep=" ")) 34 | ) 35 | if (response$status_code == 200){ 36 | cat("\nAuthenticated successfully!\n") 37 | printTerms() 38 | authToken = response$headers$`x-auth-token` 39 | if(!is.null(authToken)) 40 | setAuthToken(authToken) 41 | break 42 | } else if (response$status_code == 403){ 43 | cat("\nAuthentication failed!\nTrying again in 5 seconds ... \n") 44 | } else { 45 | cat("\nAuthentication error!\nTrying again in 5 seconds ... \n") 46 | } 47 | Sys.sleep(5) 48 | if(as.numeric(Sys.time() - start_time) > 60){ 49 | cat("\nAborting. Please try again.\n") 50 | break; 51 | } 52 | } 53 | } 54 | 55 | printTerms <- function(){ 56 | termsText <- " 57 | TERMS OF USE for R Package and 58 | 59 | Reminder of GISAID's Database Access Agreement 60 | 61 | Your ability to access and use Data in GISAID, including your access and 62 | use of same via R Package, is subject to the terms and conditions of 63 | GISAID's Database Access Agreement (“DAA”) (which you agreed to 64 | when you requested access credentials to GISAID), as well as the 65 | following terms: 66 | 67 | 1. You will treat all data contained in the R Package consistent with 68 | other Data in GISAID and in accordance with GISAID's Database Access 69 | Agreement; 70 | 71 | 2. You will not distribute, or re-distribute Data made available through 72 | GISAID to any third party other than Authorized Users as contemplated by 73 | the DAA; 74 | 75 | 3. USE OF R PACKAGE: Any visualizations, charts, graphs, 76 | graphics, pictographs, plots, or other displays you create via the R 77 | Package may be exclusively used for academic and research purposes. 78 | No other types of uses are allowed; 79 | 80 | 4. Any use of visualizations, charts, graphs, graphics, pictographs, 81 | plots, or other displays created via the R Package in an academic or 82 | research publication, including in a paper, manuscript, preprint, website, 83 | web service, or any other media material must be in conformity with the 84 | GISAID Publishing Guidelines, available at https://www.gisaid.org/publish, 85 | and the DAA, available at https://www.gisaid.org/daa; and 86 | 87 | 5. By using the R Package you reaffirm your understanding of these 88 | terms and the DAA. 89 | 90 | When using this data, please state, \"This data was obtained from GISAID via the outbreak.info API\". 91 | WE DO NOT SUPPORT THIRD PARTY APPLICATIONS. THIS PACKAGE IS MEANT FOR RESEARCH AND VISUALIZATION PURPOSES ONLY. 92 | If you want to build third party applications, please contact GISAID via https://www.gisaid.org/help/contact/. 93 | " 94 | cat(red$bold(termsText)) 95 | } 96 | -------------------------------------------------------------------------------- /R/getGenomicsResponse.R: -------------------------------------------------------------------------------- 1 | #' Get response from genomics endpoint 2 | #' @NoRd 3 | 4 | #' A function rather aimed at developers 5 | #' @description A function that does blabla, blabla. 6 | #' @keywords internal 7 | #' @export 8 | 9 | getGenomicsResponse <- function(dataurl, logInfo = T, logWarning = T, logError = T){ 10 | 11 | scroll.id <- NULL 12 | results <- list() 13 | success <- NULL 14 | while(is.null(success)){ 15 | success <- FALSE 16 | if(logInfo){ 17 | cat("Retrieving data...", "\n") 18 | } 19 | dataurl <- ifelse(is.null(scroll.id), dataurl, paste0(dataurl, "&scroll_id=", scroll.id)) 20 | dataurl <- URLencode(dataurl) 21 | resp <- NULL 22 | tryCatch({ 23 | authToken <- getAuthToken() 24 | if(!is.null(authToken)){ 25 | resp <- GET( 26 | dataurl, 27 | add_headers(Authorization = paste("Bearer", authToken, sep=" ")) 28 | ) 29 | } else { 30 | resp <- GET( 31 | dataurl 32 | ) 33 | } 34 | authToken = resp$headers$`x-auth-token` 35 | if(!is.null(authToken)) 36 | setAuthToken(authToken) 37 | if(resp$status_code == 401){ 38 | warning("Please authenticate by calling authenticateUser() to access the API.\n") 39 | } else if (resp$status_code == 403) { 40 | warning("Invalid token. Please reauthenticate by calling the authenticateUser() function.\n") 41 | } else if(resp$status_code == 500){ 42 | warning("There was an internal server error. Please cross check your query or contact help@outbreak.info for further assistance.\n") 43 | } else if(resp$status_code == 429){ 44 | warning("You have exceeded the API usage limit. Please limit the usage to 1 request/minute.\n") 45 | } else if (resp$status_code == 400){ 46 | warning("Malformed token. Please reauthenticate by calling the authenticateUser() function.\n") 47 | } else if (resp$status_code == 414){ 48 | warning("Your requested API URL is too long (> 2000 characters). This commonly happens when you add too many lineages and/or locations. Please try breaking up a single call into multiple requests.\n") 49 | } else if(resp$status_code == 200){ 50 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 51 | if(length(resp$results) > 0) resp_df <- convert_list_to_dataframe(resp$results) else resp_df <- data.frame() 52 | results[[length(results) + 1]] <- resp_df 53 | scroll.id <- resp$'_scroll_id' 54 | success <- resp$success 55 | return(results) 56 | } 57 | }, error = function(cond){ 58 | if(logError){ 59 | message(cond) 60 | } 61 | stop("Could not connect to API. Please check internet connection and try again.") 62 | }, warning = function(cond){ 63 | if(logWarning){ 64 | message(cond) 65 | } 66 | return(NULL) 67 | }) 68 | } 69 | } 70 | 71 | ## If object is a list, return a long dataframe with query_key as new column. 72 | ## If object is a dataframe, return the object directly 73 | ## If object is neither, throw warning and return NULL 74 | convert_list_to_dataframe <- function(list_obj){ 75 | if(!(class(list_obj) %in% c("list", "data.frame"))){ 76 | warning("Supplied object is not a list or dataframe") 77 | return(NULL) 78 | } 79 | if(class(list_obj) == "data.frame"){ 80 | return(list_obj) 81 | } 82 | ## Exclude items in list that have 0 columns 83 | list_obj <- list_obj[sapply(list_obj, function(x){length(x) > 0})] 84 | ## If list add a "query_key" column 85 | query_keys <- names(list_obj) 86 | res <- lapply(query_keys, 87 | function(query_key) { 88 | d <- list_obj[[query_key]] 89 | d <- d[!sapply(d, is.null)] 90 | if(class(d) == "data.frame"){ 91 | d$query_key <- query_key 92 | } else { 93 | d <- data.frame(key = query_key, value = d) 94 | } 95 | return(d) 96 | }) 97 | res_df <- do.call(rbind, res) 98 | return(res_df); 99 | } 100 | -------------------------------------------------------------------------------- /R/getEpiData.R: -------------------------------------------------------------------------------- 1 | #' @title Retrieve epidemiological data from outbreak.info 2 | #' 3 | #' @description Retrieve up-to-date epidemiological data from outbreak.info according to user specifications 4 | #' 5 | #' @param name vector of location names 6 | #' @param location_id vector of ISO3 code representing locations 7 | #' @param wb_region World Bank region name(s) 8 | #' @param country_name country name(s) 9 | #' @param state_name state name(s) 10 | #' @param admin_level an integer representing an administrative level (World Bank regions = -1, countries = 0, states/provinces = 1, metropolitan areas = 1.5, counties = 2) 11 | #' @param date date(s) (YYYY-MM-DD) 12 | #' @param mostRecent T/F 13 | #' @param fields vector of API fields to include in results 14 | #' @param sort parameter to sort results by 15 | #' @param size size 16 | #' 17 | #' @return dataframe 18 | #' 19 | #' @examples 20 | #' getEpiData(name="United States of America", date="2020-07-01") 21 | #' 22 | #' @export 23 | 24 | getEpiData <- function(name=NULL, location_id=NULL, wb_region=NULL, country_name=NULL, state_name=NULL, admin_level=NULL, date=NULL, mostRecent=NULL, fields=NULL, sort=NULL, size=1000){ 25 | q <- c() 26 | if(!is.null(name)){ 27 | q <- c(q, paste0("(name:\"", paste(name, collapse="\" OR name:\""), "\") AND ")) 28 | } 29 | if(!is.null(location_id)){ 30 | q <- c(q, paste0("(location_id:\"", paste(location_id, collapse="\" OR location_id:\""), "\") AND ")) 31 | } 32 | if(!is.null(wb_region)){ 33 | q <- c(q, paste0("(wb_region:\"", paste(wb_region, collapse="\" OR wb_region:\""), "\") AND ")) 34 | } 35 | if(!is.null(country_name)){ 36 | q <- c(q, paste0("(country_name:\"", paste(country_name, collapse="\" OR country_name:\""), "\") AND ")) 37 | } 38 | if(!is.null(state_name)){ 39 | q <- c(q, paste0("(admin1:\"", paste(state_name, collapse="\" OR admin1:\""), "\") AND ")) 40 | } 41 | if(!is.null(admin_level)){ 42 | q <- c(q, paste0("(admin_level:\"", paste(admin_level, collapse="\" OR admin_level:\""), "\") AND ")) 43 | } 44 | if(!is.null(date)){ 45 | if (!is.character(date)){ 46 | stop("Date must be in string format") 47 | }else{ 48 | q <- c(q, paste0("(date:\"", paste(date, collapse="\" OR date:\""), "\") AND ")) 49 | } 50 | } 51 | q <- paste(q, sep="", collapse = "") 52 | q <- substr(q, 1, nchar(q)-5) 53 | if(!is.null(mostRecent)){ 54 | if (!is.logical(mostRecent)){ 55 | stop("mostRecent must be in Boolean format") 56 | }else{ 57 | q <- c(q, paste0(" AND ", "mostRecent:", tolower(mostRecent))) 58 | } 59 | } 60 | q <- paste(q, sep="", collapse = "") 61 | if(!is.null(fields)){ 62 | q <- c(q, paste0("&fields=", paste(fields, collapse=","))) 63 | } 64 | if(!is.null(sort)){ 65 | q <- c(q, paste0("&sort=", paste(sort))) 66 | } 67 | 68 | q <- c(q, paste0("&size=", paste(size))) 69 | q <- paste(q, sep="", collapse = "") 70 | q <- paste0(q, "&fetch_all=true") 71 | 72 | scroll.id <- NULL 73 | results <- list() 74 | success <- NULL 75 | pb <- NULL 76 | firstQuery = TRUE 77 | while(is.null(success)){ 78 | dataurl <- paste0(api.url, "query?q=", q) 79 | dataurl <- ifelse(is.null(scroll.id), dataurl, paste0(dataurl, "&scroll_id=", scroll.id)) 80 | dataurl <- URLencode(dataurl) 81 | resp <- GET( 82 | dataurl 83 | ) 84 | if(resp$status_code == 200){ 85 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 86 | scroll.id <- resp$'_scroll_id' 87 | if(!is.null(resp$hits)) { 88 | if(class(resp$hits) == "data.frame") { 89 | results[[length(results) + 1]] <- resp$hits 90 | } 91 | } 92 | success <- resp$success 93 | } else if (resp$status_code == 400) { 94 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 95 | success <- resp$success 96 | } else { 97 | stop("Could not connect to API. Check internet connection and try again. If the problem persists please contact help@outbreak.info.") 98 | } 99 | if(firstQuery){ 100 | max = resp$total 101 | if(max == 0) 102 | return(data.frame()) 103 | pb <- progress_bar$new( 104 | format = " downloading [:bar] :percent eta: :eta", 105 | total = max, clear = FALSE, width= 60) 106 | pb$tick(0) 107 | firstQuery = FALSE 108 | } 109 | if (is.null(success)){ 110 | pb$tick(size) 111 | } else { 112 | pb$finished <- T 113 | } 114 | } 115 | pb$terminate() 116 | if(length(results) > 1){ 117 | hits <- rbind_pages(results) 118 | }else{ 119 | hits <- data.frame(results) 120 | } 121 | if ("date" %in% colnames(hits)){ 122 | hits$date=as.Date(hits$date, "%Y-%m-%d") 123 | hits <- hits[order(as.Date(hits$date, format = "%Y-%m-%d")),] 124 | } 125 | return(hits) 126 | } 127 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 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 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $(''); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (``, then ``, etc.) that has more than one element. Defaults to 1 (for ``). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /R/searchLocations.R: -------------------------------------------------------------------------------- 1 | #' @title Get exact location names 2 | #' 3 | #' @description Get exact spelling of locations at the same administrative level. 4 | #' 5 | #' @param locations_to_search vector or list of location (World Bank region, country, state/province, metropolitan area, county) name(s) at the same administrative level 6 | #' @param admin_level an integer representing an administrative level (World Bank regions = -1, countries = 0, states/provinces = 1, metropolitan areas = 1.5, counties = 2) 7 | #' 8 | #' @return a vector or list of location names 9 | #' 10 | #' @examples 11 | #' searchLocations(c("California", "Florida", "Texas"), admin_level=1) 12 | #' 13 | #' @export 14 | 15 | searchLocations <- function(locations_to_search, admin_level){ 16 | # TODO: Refactor getISO3 and searchLocations into one function 17 | if (missing(admin_level)){ 18 | stop("Administrative level not specified") 19 | } 20 | locs_of_interest=c() 21 | locs_not_found=c() 22 | for (i in locations_to_search){ 23 | scroll.id <- NULL 24 | location.ids <- paste0("(name:\"", paste(i, collapse="\" OR name:\""), "\")") 25 | results <- list() 26 | success <- NULL 27 | while(is.null(success)){ 28 | dataurl <- paste0(api.url, "query?q=", location.ids, " AND ", "admin_level:\"", admin_level, "\"", " AND mostRecent:true&fields=name,location_id,state_name&fetch_all=true") 29 | dataurl <- ifelse(is.null(scroll.id), dataurl, paste0(dataurl, "&scroll_id=", scroll.id)) 30 | dataurl <- URLencode(dataurl) 31 | tryCatch({ 32 | resp <- GET(dataurl) 33 | if(resp$status_code == 400){ 34 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 35 | success <- resp$success 36 | } else if (resp$status_code == 200) { 37 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 38 | scroll.id <- ifelse(is.null(resp$'_scroll_id'), scroll.id, resp$'_scroll_id') 39 | success <- resp$success 40 | hits <- data.frame() 41 | if(!is.null(resp$hits)) { 42 | if(class(resp$hits) == "data.frame"){ 43 | results[[length(results) + 1]] <- resp$hits 44 | hits <- rbind_pages(results) 45 | } 46 | if (nrow(hits)==1){ 47 | locs_of_interest=c(locs_of_interest, i) 48 | } else { 49 | locs_not_found=c(locs_not_found, i) 50 | } 51 | } 52 | } else { 53 | stop("Could not connect to API. Check internet connection and try again.") 54 | } 55 | }, error = function(cond){ 56 | stop(cond) 57 | }, warning = function(cond){ 58 | stop(cond) 59 | }) 60 | } 61 | } 62 | if (length(locs_of_interest)==length(locations_to_search)){ 63 | return(locs_of_interest) 64 | } 65 | if (length(locs_of_interest)!=length(locations_to_search)){ 66 | locations=c() 67 | for (i in locs_not_found){ 68 | if (grepl(" ", i, fixed=TRUE)==T){ 69 | locs=paste0("*",i,"*") 70 | locs=gsub(" ", "*", locs, fixed=TRUE) 71 | }else{ 72 | locs=paste0("*",i,"*") 73 | } 74 | locations=c(locations, locs) 75 | } 76 | for (i in 1:length(locations)){ 77 | scroll.id <- NULL 78 | location.ids <- paste0("(name:", paste(locations[i], collapse=" OR name:"), ")") 79 | results <- list() 80 | success <- NULL 81 | while(is.null(success)){ 82 | dataurl <- paste0(api.url, "query?q=", location.ids, " AND ", "admin_level:\"", admin_level, "\"", " AND mostRecent:true&fields=name,location_id,State&fetch_all=true") 83 | dataurl <- ifelse(is.null(scroll.id), dataurl, paste0(dataurl, "&scroll_id=", scroll.id)) 84 | dataurl <- URLencode(dataurl) 85 | tryCatch({ 86 | resp <- GET(dataurl) 87 | if(resp$status_code == 400){ 88 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 89 | success <- resp$success 90 | } else if (resp$status_code == 200) { 91 | resp <- fromJSON(dataurl, flatten=TRUE) 92 | scroll.id <- resp$'_scroll_id' 93 | if(!is.null(resp$hits)){ 94 | if(class(resp$hits) == "data.frame"){ 95 | results[[length(results) + 1]] <- resp$hits 96 | } 97 | } 98 | success <- resp$success 99 | } 100 | }) 101 | } 102 | if(length(results) == 0) { 103 | message(locs_not_found[i], " not found. Please check spelling.") 104 | next 105 | } else{ 106 | hits <- rbind_pages(results) 107 | df=(hits) 108 | df$name=apply(cbind(df$name, df$State), 1, function(x) paste(x[!is.na(x)], collapse = ", ")) 109 | } 110 | for (i in df$name){ 111 | cat(paste0(i, "\n")) 112 | loc_sel <- readline("Is this a location of interest? (Y/N): ") 113 | if ((loc_sel == "Y")|(loc_sel == "y")){ 114 | locs_of_interest = c(locs_of_interest, i) 115 | break 116 | } 117 | if ((loc_sel != "Y")&(loc_sel != "y")&(loc_sel != "N")&(loc_sel != "n")){ 118 | cat("Expected input is Y or N\n") 119 | cat(paste0(i, "\n")) 120 | loc_sel <- readline("Is this a location of interest? (Y/N): ") 121 | if ((loc_sel == "Y")|(loc_sel == "y")){ 122 | locs_of_interest = c(locs_of_interest, i) 123 | break 124 | } 125 | } 126 | } 127 | } 128 | } 129 | return(locs_of_interest) 130 | } 131 | -------------------------------------------------------------------------------- /R/getISO3.R: -------------------------------------------------------------------------------- 1 | #' @title Get ISO3 codes 2 | #' 3 | #' @description Get ISO3 codes for World Bank regions, countries, states/provinces, metropolitan areas, and/or counties. 4 | #' 5 | #' @param locations_to_search vector or list of location (World Bank region, country, state/province, metropolitan area, county) name(s) 6 | #' 7 | #' @import jsonlite 8 | #' 9 | #' @return a vector or list of ISO3 codes 10 | #' 11 | #' @examples 12 | #' getISO3(c("San Diego", "Virginia", "India")) 13 | #' 14 | #' @export 15 | 16 | getISO3 <- function(locations_to_search){ 17 | locs_of_interest=c() 18 | locs_not_found=c() 19 | locations_to_search <- tolower(locations_to_search) 20 | for (i in locations_to_search){ 21 | scroll.id <- NULL 22 | location.ids <- paste0("(name.lower:\"", paste(i, collapse="\" OR name.lower:\""), "\")") 23 | results <- list() 24 | success <- NULL 25 | while(is.null(success)){ 26 | dataurl <- paste0(api.url, "query?q=",location.ids," AND mostRecent:true&fields=name,location_id,state_name&fetch_all=true") 27 | dataurl <- ifelse(is.null(scroll.id), dataurl, paste0(dataurl, "&scroll_id=", scroll.id)) 28 | dataurl <- URLencode(dataurl) 29 | tryCatch({ 30 | resp <- GET(dataurl) 31 | if(resp$status_code == 400){ 32 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 33 | success <- resp$success 34 | } else if (resp$status_code == 200) { 35 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 36 | scroll.id <- ifelse(is.null(resp$'_scroll_id'), scroll.id, resp$'_scroll_id') 37 | success <- resp$success 38 | hits <- data.frame() 39 | if(!is.null(resp$hits)) { 40 | if(class(resp$hits) == "data.frame"){ 41 | results[[length(results) + 1]] <- resp$hits 42 | hits <- rbind_pages(results) 43 | } 44 | if (nrow(hits)==1){ 45 | locs_of_interest=c(locs_of_interest, hits$location_id) 46 | }else{ 47 | locs_not_found=c(locs_not_found, i) 48 | } 49 | } 50 | } else { 51 | stop("Could not connect to API. Check internet connection and try again.") 52 | } 53 | }, error = function(cond){ 54 | stop(cond) 55 | }, warning = function(cibd){ 56 | stop(cond) 57 | }) 58 | } 59 | } 60 | if (length(locs_of_interest)==length(locations_to_search)){ 61 | return(locs_of_interest) 62 | } 63 | if (length(locs_of_interest)!=length(locations_to_search)){ 64 | locations=c() 65 | for (i in locs_not_found){ 66 | if (grepl(" ", i, fixed=TRUE)==T){ 67 | locs=paste0("*",i,"*") 68 | locs=gsub(" ", "*", locs, fixed=TRUE) 69 | }else{ 70 | locs=paste0("*",i,"*") 71 | } 72 | locations=c(locations, locs) 73 | } 74 | for (i in 1:length(locations)){ 75 | scroll.id <- NULL 76 | location.ids <- paste0("(name.lower:", paste(locations[i], collapse=" OR name.lower:"), ")") 77 | results <- list() 78 | success <- NULL 79 | while(is.null(success)){ 80 | dataurl <- paste0(api.url, "query?q=",location.ids," AND mostRecent:true&fields=name,location_id,state_name,admin_level&fetch_all=true") 81 | dataurl <- ifelse(is.null(scroll.id), dataurl, paste0(dataurl, "&scroll_id=", scroll.id)) 82 | dataurl <- URLencode(dataurl) 83 | tryCatch({ 84 | resp <- GET(dataurl) 85 | if(resp$status_code == 400){ 86 | resp <- fromJSON(content(resp, "text"), flatten=TRUE) 87 | success <- resp$success 88 | } else if (resp$status_code == 200) { 89 | resp <- fromJSON(dataurl, flatten=TRUE) 90 | scroll.id <- resp$'_scroll_id' 91 | if(!is.null(resp$hits)){ 92 | if(class(resp$hits) == "data.frame"){ 93 | results[[length(results) + 1]] <- resp$hits 94 | } 95 | } 96 | success <- resp$success 97 | } 98 | }) 99 | } 100 | if(length(results) == 0) { 101 | message(locs_not_found[i], " not found. Please check spelling.") 102 | next 103 | } else{ 104 | hits <- rbind_pages(results) 105 | df=(hits) 106 | df$name=apply(cbind(df$name, df$state_name), 1, function(x) paste(x[!is.na(x)], collapse = ", ")) 107 | df$admin_level[df$admin_level == "-1"] <- "World Bank Region" 108 | df$admin_level[df$admin_level == "0"] <- "country" 109 | df$admin_level[df$admin_level == "1"] <- "state/province" 110 | df$admin_level[df$admin_level == "1.5"] <- "metropolitan area" 111 | df$admin_level[df$admin_level == "2"] <- "county" 112 | df$fullname <- paste0(df$name, " (", df$admin_level, ")") 113 | } 114 | for (i in df$fullname){ 115 | cat(paste0(i, "\n")) 116 | loc_sel <- readline("Is this a location of interest? (Y/N): ") 117 | if ((loc_sel == "Y")|(loc_sel == "y")){ 118 | locs_of_interest = c(locs_of_interest, df$location_id[df$fullname==i]) 119 | break 120 | } 121 | if ((loc_sel != "Y")&(loc_sel != "y")&(loc_sel != "N")&(loc_sel != "n")){ 122 | cat("Expected input is Y or N\n") 123 | cat(paste0(i, "\n")) 124 | loc_sel <- readline("Is this a location of interest? (Y/N): ") 125 | if ((loc_sel == "Y")|(loc_sel == "y")){ 126 | locs_of_interest = c(locs_of_interest, df$location_id[df$fullname==i]) 127 | break 128 | } 129 | } 130 | } 131 | } 132 | } 133 | return(locs_of_interest) 134 | } 135 | -------------------------------------------------------------------------------- /R/getResourcesResponse.R: -------------------------------------------------------------------------------- 1 | #' Access outbreak.info Research Library API 2 | #' 3 | #' @param query (optional) constructs a query over ALL fields, or a fielded query searching within specific fields. Fielded query terms should be separated by ` AND ` or ` OR `. See \href{https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax}{Elasticserach query strings} for more info. 4 | #' @param size (optional) number of records to return (default = 10) 5 | #' @param fetchAll (optional) Boolean whether to return all results for the query 6 | #' @param fields (optional) vector specifying which fields to return. Returns all by default 7 | #' @param sort (optional) field to sort by. Add `-` to sort in descending order 8 | #' @param facets (optional) field by which to aggregate (count) their frequency 9 | #' @param facet_size (optional) how many facet groups to include in the facet total (default = 10, max = 1000) 10 | #' 11 | #' @import httr 12 | #' @import RcppSimdJson 13 | #' @import progress 14 | #' @import stringr 15 | #' @import dplyr 16 | #' 17 | #' @return dataframe or list (for facetted queries) containing the response of the API query 18 | #' @export 19 | #' 20 | #' @examples 21 | #' # Return only the first 10 hits for "ivermectin" 22 | #' df = getResourcesResponse("ivermectin", size = 10) 23 | #' 24 | #' # Find the first 10 results which contain the variable `topicCategory` 25 | #' df = getResourcesResponse("_exists_:topicCategory", size = 10) 26 | #' 27 | #' # Get `date`/`name` from the first 10 hits for the query "ivermectin" plus a count of the `@type` field for ALL results 28 | #' df = getResourcesResponse("ivermectin", size = 10, facets="@type", fields=c("date", "name")) 29 | 30 | getResourcesResponse = function(queryString = NULL, size = 10, fetchAll = FALSE, fields = NULL, sort = NULL, facets = NULL, facet_size = 10, queryStub = "https://api.outbreak.info/resources/query?") { 31 | 32 | # Construct the query 33 | query = queryStub 34 | 35 | # add base query 36 | if(!is.null(queryString)){ 37 | query = str_c(queryStub, "q=", queryString) 38 | } 39 | 40 | 41 | # add sorting 42 | if(!is.null(sort)){ 43 | query = str_c(query, "&sort=", sort) 44 | } 45 | 46 | # add size param 47 | if(!is.null(size)){ 48 | query = str_c(query, "&size=", size) 49 | } 50 | 51 | # add fields param 52 | if(!is.null(fields)){ 53 | query = str_c(query, "&fields=", paste(fields, collapse=",")) 54 | } 55 | 56 | # add facets param 57 | if(!is.null(facets)){ 58 | query = str_c(query, "&facets=", facets, "&facet_size=", facet_size) 59 | } 60 | 61 | 62 | # --- RUN THE QUERY(-IES) -- 63 | if(fetchAll) { 64 | # Fetch all queries -- keep going till you hit the end 65 | query = str_c(query, "&fetch_all=true") 66 | 67 | df = tibble() 68 | res = getResourcesQuery(query) 69 | 70 | # add progress bar 71 | pb <- progress_bar$new(total = res$total, clear = FALSE, show_after = 0) 72 | 73 | while(!is.null(res)){ 74 | pb$update(nrow(df) / res$total) 75 | df = df %>% bind_rows(res$hits) 76 | res = getResourcesQuery(query, res$id) 77 | } 78 | 79 | pb$update(1) 80 | pb$terminate() 81 | 82 | # return statement 83 | if(!is.null(facets)) { 84 | results = list(hits = df, total = res[["total"]], facets = res[["facets"]]) 85 | } else { 86 | results = list(hits = df) 87 | } 88 | 89 | 90 | } else { 91 | # Single query 92 | results = getResourcesQuery(query) 93 | } 94 | 95 | # Data cleanup! 96 | # remove `_score` 97 | if(!is.null(results$hits)){ 98 | results$hits = results$hits %>% 99 | select(-`_score`) 100 | } 101 | 102 | if("date" %in% colnames(results$hits)) { 103 | results$hits = results$hits %>% 104 | mutate(date = as.Date(date, "%Y-%m-%d")) 105 | } 106 | 107 | if("datePublished" %in% colnames(results$hits)) { 108 | results$hits = results$hits %>% 109 | mutate(datePublished = as.Date(datePublished, "%Y-%m-%d")) 110 | } 111 | 112 | if("dateModified" %in% colnames(results$hits)) { 113 | results$hits = results$hits %>% 114 | mutate(dateModified = as.Date(dateModified, "%Y-%m-%d")) 115 | } 116 | 117 | 118 | if("dateCreated" %in% colnames(results$hits)) { 119 | results$hits = results$hits %>% 120 | mutate(dateCreated = as.Date(dateCreated, "%Y-%m-%d")) 121 | } 122 | 123 | 124 | if("dateCompleted" %in% colnames(results$hits)) { 125 | results$hits = results$hits %>% 126 | mutate(dateCompleted = as.Date(dateCompleted, "%Y-%m-%d")) 127 | } 128 | 129 | # Flatten the results, if they don't include an aggregation 130 | if(!is.null(facets)) { 131 | return(results) 132 | } else { 133 | return(results$hits) 134 | } 135 | 136 | } 137 | 138 | # helper function to grab the results 139 | getResourcesQuery = function(query, scroll_id = NA) { 140 | if(!is.na(scroll_id)){ 141 | query = str_c(query, "&scroll_id=", scroll_id) 142 | } 143 | resp = GET(URLencode(query)) 144 | 145 | if(resp$status_code == 200) { 146 | resp_content = content(resp, as="text") 147 | results = fparse(resp$content) 148 | if(length(results[["success"]] == 0)) { 149 | return(NULL) 150 | } else { 151 | return(list(hits = results[["hits"]], id = results[["_scroll_id"]], total = results[["total"]], facets = results[["facets"]])) 152 | } 153 | } else if(resp$status_code == 429) { 154 | warning("You have exceeded the API usage limit. Please limit the usage to 1 request/minute.\n") 155 | return(NULL) 156 | } else if(resp$status_code == 500){ 157 | stop("There was an internal server error. Please check your query (", query, ") or contact help@outbreak.info for further assistance.\n") 158 | } 159 | else { 160 | stop("Hmm. Some unknown error happened. Please reach out to help@outbreak.info for help.") 161 | return(NULL) 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /docs/LICENSE-text.html: -------------------------------------------------------------------------------- 1 | 2 | License • outbreakinfo 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Toggle navigation 20 | 21 | 22 | 23 | 24 | 25 | outbreakinfo 26 | 0.2.0 27 | 28 | 29 | 30 | 31 | 32 | Get started 33 | 34 | 35 | Reference 36 | 37 | 38 | 39 | Articles 40 | 41 | 42 | 43 | 44 | Cases & Deaths data 45 | 46 | 47 | Location Tracker 48 | 49 | 50 | Research Library 51 | 52 | 53 | Variant Tracker 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | License 72 | 73 | 74 | YEAR: 2021 75 | COPYRIGHT HOLDER: outbreakinfo authors 76 | 77 | 78 | 79 | 80 | 81 | Contents 82 | 83 | 84 | 85 | 86 | 87 | 88 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Page not found (404) • outbreakinfo 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Toggle navigation 43 | 44 | 45 | 46 | 47 | 48 | outbreakinfo 49 | 0.2.0 50 | 51 | 52 | 53 | 54 | 55 | 56 | Get started 57 | 58 | 59 | Reference 60 | 61 | 62 | 63 | Articles 64 | 65 | 66 | 67 | 68 | 69 | Cases & Deaths data 70 | 71 | 72 | Location Tracker 73 | 74 | 75 | Research Library 76 | 77 | 78 | Variant Tracker 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | Page not found (404) 104 | 105 | 106 | Content not found. Please use links in the navbar. 107 | 108 | 109 | 110 | 111 | Contents 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Articles • outbreakinfo 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 65 | 66 | 67 | 68 | 69 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | Toggle navigation 88 | 89 | 90 | 91 | 92 | 93 | outbreakinfo 94 | 0.2.0 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | Get started 108 | 109 | 110 | Reference 111 | 112 | 113 | 114 | Articles 115 | 116 | 117 | 118 | 119 | 120 | Cases & Deaths data 121 | 122 | 123 | Location Tracker 124 | 125 | 126 | Research Library 127 | 128 | 129 | Variant Tracker 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | Articles 155 | 156 | 157 | 158 | All vignettes 159 | 160 | 161 | 162 | Cases & Deaths data 163 | 164 | Location Tracker 165 | 166 | Introduction to outbreakinfo 167 | 168 | Research Library 169 | 170 | Variant Tracker 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | --------------------------------------------------------------------------------
YEAR: 2021 75 | COPYRIGHT HOLDER: outbreakinfo authors 76 |