diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..c5166261a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,131 @@ +# These settings are for any web project + +# Handle line endings automatically for files detected as text +# and leave all files detected as binary untouched. +* text=auto eol=lf + +# +# The above will handle all files NOT found below +# + +# +## These files are text and should be normalized (Convert crlf => lf) +# + +# source code +*.php text +*.css text +*.sass text +*.scss text +*.less text +*.styl text +*.js text +*.ts text +*.coffee text +*.json text +*.htm text +*.html text +*.xml text +*.txt text +*.ini text +*.inc text +*.pl text +*.rb text +*.py text +*.scm text +*.sql text +*.sh text eof=LF +*.bat text +*.R text + +# templates +*.hbt text +*.jade text +*.haml text +*.hbs text +*.dot text +*.tmpl text +*.phtml text + +# server config +.htaccess text + +# git config +.gitattributes text +.gitignore text + +# code analysis config +.jshintrc text +.jscsrc text +.jshintignore text +.csslintrc text + +# misc config +*.yaml text +*.yml text +*.editorconfig text +*.toml text + +# build config +*.npmignore text +*.bowerrc text +*.prettierignore text +Dockerfile text eof=LF + +# Heroku +Procfile text +.slugignore text + +# Documentation +*.md text +LICENSE text +AUTHORS text + + +# +## These files are binary and should be left untouched +# + +# (binary is a macro for -text -diff) +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.mov binary +*.mp4 binary +*.mp3 binary +*.flv binary +*.fla binary +*.swf binary +*.gz binary +*.zip binary +*.7z binary +*.ttf binary +*.pyc binary +*.pdf binary + +# Source files +# ============ +*.pxd text +*.py text +*.py3 text +*.pyw text +*.pyx text +*.sh text eol=lf +*.json text + +# Binary files +# ============ +*.db binary +*.p binary +*.pkl binary +*.pyc binary +*.pyd binary +*.pyo binary + +# Note: .db, .p, and .pkl files are associated +# with the python modules ``pickle``, ``dbm.*``, +# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb`` +# (among others). +*.rda binary diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fb2a77da9..214f432eb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,9 +1,9 @@ on: push: paths: # run only when an Rmd file changes - - '**.Rmd' - - 'environment.yml' - - '.github/workflows/ci.yaml' + - "**.Rmd" + - "environment.yml" + - ".github/workflows/ci.yaml" name: ci @@ -17,7 +17,7 @@ jobs: fetch-depth: 3 - name: Cache Conda uses: actions/cache@v1 - with: + with: path: ~/conda_pkgs_dir key: ${{ runner.os }}-conda6-${{ hashFiles('environment.yml') }} restore-keys: | @@ -50,13 +50,13 @@ jobs: restore-keys: | ${{ runner.os }}-blogdown2- - name: Build site - shell: bash -l {0} + shell: bash -l {0} run: | npm run build:blog - + - uses: actions/setup-node@v1 with: - node-version: '12' + node-version: "12" - uses: actions/cache@v2 with: path: ~/.npm @@ -64,6 +64,8 @@ jobs: restore-keys: | ${{ runner.os }}-node- - run: npm ci + - name: Lint + run: npm run lint - name: Build run: npm run build diff --git a/.github/workflows/ci_fast.yaml b/.github/workflows/ci_fast.yaml index 9f43d90c3..e1d1948ea 100644 --- a/.github/workflows/ci_fast.yaml +++ b/.github/workflows/ci_fast.yaml @@ -1,9 +1,9 @@ on: push: paths-ignore: # don't run the fast version when an Rmd file changes - - '**.Rmd' - - 'environment.yml' - - '.github/workflows/ci.yaml' + - "**.Rmd" + - "environment.yml" + - ".github/workflows/ci.yaml" name: ci_fast @@ -14,11 +14,11 @@ jobs: - uses: actions/checkout@v2 with: # submodules: true # Fetch Hugo themes (true OR recursive) - fetch-depth: 3 # Fetch all history for .GitInfo and .Lastmod - + fetch-depth: 3 # Fetch all history for .GitInfo and .Lastmod + - uses: actions/setup-node@v1 with: - node-version: '12' + node-version: "12" - uses: actions/cache@v2 with: path: ~/.npm @@ -26,6 +26,8 @@ jobs: restore-keys: | ${{ runner.os }}-node- - run: npm ci + - name: Lint + run: npm run lint - name: Build run: npm run build diff --git a/.gitignore b/.gitignore index b35019050..c9bd7f824 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ /public /resources/_gen *.exe -/.vscode /blogdown /.Rhistory *_cache diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..80f9e07c5 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,30 @@ +*.toml +*.jpg +*.png +*.rda +*.rdx +*.RData +*.svg +/blogdown +/.htaccess +/.Rhistory +.gitignore +.prettierignore +/.gitattributes +/LICENSE +/package-lock.json +/content/blog/**/*.html +/static +/public +/Dockerfile +/resources +/assets +*.woff +*.ttf +*.woff2 +*.R +*.xml +*.Rmd +*.md +*.jpeg +*.ico \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..1b522730e --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,14 @@ +module.exports = { + printWidth: 120, + semi: true, + trailingComma: "es5", + + overrides: [ + { + files: ["*.html"], + options: { + parser: "go-template", + }, + }, + ], +}; diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..c83e26348 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["esbenp.prettier-vscode"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..d3860b2a3 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "editor.formatOnSaveMode": "modifications", + "[scss]": { + "files.trimTrailingWhitespace": true, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[js]": { + "files.trimTrailingWhitespace": true, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[html]": { + "files.trimTrailingWhitespace": true, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" + } +} diff --git a/README.md b/README.md index 545db57ef..0bf390001 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,54 @@ Delphi's homepage at https://cmu-delphi-main.netlify.app/ -This site is based on [Hugo](https://gohugo.io). +This site is based on [Hugo](https://gohugo.io) and uses [Prettier](https://prettier.io) for formatting. + +## Structure + +The main content is in the `/content` directory written in Markdown or RMarkdown for blog posts. +In addition to the Markdown content frontmatter with YAML syntax is used at the beginning of the file to customize and describe the content. Common fields include `title` and `description`. +However, depending on the file it can have additional fields. For example for blog posts additional fields are used to list the authors, hero images, summaries, tags, and so on. + +### Linking + +Hugo uses so called shortcodes for embedding logic into Markdown files. A good example is linking to other pages. + +A relative reference to another page can be created using the `relref` shortcode. The argument is the filename with an optional `#` anchor to jump to a specific section. + +**Examples** + +``` +national daily survey]({{< relref "surveys">}}) +[syndromic COVID-19 indicator based on doctor visits]({{< relref "2020-10-14-dv-signal" >}}) +[self-reported symptoms]({{< relref "2020-08-26-fb-survey#whats-in-the-survey" >}}) +``` + +Instead of a direct link to the API reference there is the `apiref` shortcode. The advantage is that it is easy to later change the API base URL without changing each appearance. The argument is the path segment to point to. + +**Examples** + +``` +[public API]({{< apiref "api/covidcast.html" >}}) +[Epidata API]({{< apiref "/" >}}) +``` + +In RMarkdown things are slightly more different since the R Markdown parser is used before Hugo takes over. Blogdown has a special function for handling shortcodes: `blogdown::shortcode_html`. + +**Examples** + +``` +[Facebook](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey")`) +[previous exploratory investigations](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#some-interesting-examples")`) +[public API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`) + +``` + +### Data + +In addition, there in the `/data` directory there are the following listings in YAML syntax + +- `authors.yaml` list of blog authors referenced in the `authors` field in blog posts. This list is used to generated the author information at the end of a blog post +- `supporters.yaml` list of supporters/collaborators ## Development Environment @@ -13,8 +60,9 @@ This site is based on [Hugo](https://gohugo.io). #### Commands -1. run `npm start` to create a development Hugo server -1. run `npm build` to build a minified build in `/public` +1. run `npm start` to create a development Hugo server running at http://localhost:1313 +1. run `npm run format` to run prettier and format files +1. run `npm run build` to build a minified build in `/public` ### Blog Editor @@ -38,10 +86,15 @@ In order to convert the Rmd files to HTML files for Hugo you also need to: - `local=TRUE` similar to `-D` to process draft files - `run_hugo=FALSE` to manually run hugo - `build_rmd=TRUE` force a (re)build of the Rmd pages +1. Alternatively, run `npm run build:blog` 1. Run Hugo server as usual -blogdown also has an integrated server `blogdown::serve_site()` which will render RMarkdown files on the fly and does a similar thing as `hugo server -D` +blogdown also has an integrated server `blogdown::serve_site()` which will render RMarkdown files on the fly and does a similar thing as `hugo server -D`. +A shortcut is available through `npm run start:blog`. #### Adding a new blog post In case you use new dependencies don't forget to either edit `environment.yml` or `dependencies.R`. +A Github action should runs when Rmd files changes so it will verify that the blog post can be built. +However, the converted HTML file along with all generated images are committed to the repository. +This simplifies the deployment and ensures that we have a blog post even when the API or data changes. diff --git a/_output.yml b/_output.yml index 9005ea665..c3455883a 100644 --- a/_output.yml +++ b/_output.yml @@ -1,3 +1,3 @@ blogdown::html_page: # force svglite device, since cairo is a mess - dev: "svglite" \ No newline at end of file + dev: svglite diff --git a/config.toml b/config.toml index 6f7b434b6..ddacf6f18 100644 --- a/config.toml +++ b/config.toml @@ -1,6 +1,6 @@ baseURL = "https://delphi.cmu.edu/" languageCode = "en-us" -title = "The Delphi Team" +title = "DELPHI" theme = "delphi" googleAnalytics = "UA-88748454-1" ignoreFiles = ["\\.Rmd$", "\\.Rmarkdown$", "_cache$", "\\.knit\\.md$", "\\.utf8\\.md$", "\\.rda$"] @@ -46,21 +46,16 @@ relativeURLs = false name = "Surveys" url = "/covidcast/surveys" weight = 2 -[[menu.main]] - parent = "covidcast" - name = "Data & Methods" - url = "/covidcast/methodology" - weight = 3 [[menu.main]] parent = "covidcast" name = "Release Log" url = "/covidcast/release-log" - weight = 4 + weight = 3 [[menu.main]] parent = "covidcast" name = "Terms Of Use" url = "/covidcast/terms-of-use" - weight = 5 + weight = 4 [[menu.main]] identifier = "flu" name = "Flu and Other Diseases" @@ -89,12 +84,5 @@ relativeURLs = false [params] description = "Developing the Theory and Practice of Epidemiological Forecasting" mission = "Develop the theory and practice of epidemiological forecasting, with a long-term vision of seeing this technology become as universally accepted and useful as weather forecasting is today." - showReadMore = true apiUrl = "https://cmu-delphi.github.io/delphi-epidata" twitter = "CmuDelphi" - - [params.logo] - url = "delphi_logo.png" - width = 50 - height = 50 - alt = "Logo" diff --git a/content/_index.md b/content/_index.md index 8164227a3..5f36b8ff8 100644 --- a/content/_index.md +++ b/content/_index.md @@ -2,4 +2,21 @@ title: DELPHI description: Developing the Theory and Practice of Epidemiological Forecasting layout: landing + +carousel: + - pre: Our Tools + title: Real-time Indicators of COVID-19 Activity + ref: covidcast + alt: Explore COVIDCast + image: covidcast_withfill.png + - pre: Our Blog Post + title: New and improved COVID Symptom Survey Tracks Testing and Mask-Wearing + ref: 2020-10-06-survey-wave-4 + alt: Learn more + image: landing-pg_hero-img-2_New and Improved COVID Symptom Survey Tracks Testing and Mask-Wearing.png + - pre: Our Research and White Papers + title: "Pancasting: forecasting epidemics from provisional data" + link: https://delphi.cmu.edu/~lcbrooks/brooks2020pancasting.pdf + alt: View Paper + image: landing-pg_hero-img-2_Pancasting_ forecasting epidemics from provisional data.png --- diff --git a/content/about/_index.md b/content/about/_index.md index 2d7101d9e..c30071ff0 100644 --- a/content/about/_index.md +++ b/content/about/_index.md @@ -5,28 +5,28 @@ layout: about ### Who are we? -We're a research group based out of Carnegie Mellon University dedicated to developing the theory and practice of epidemic tracking and forecasting. Pre-pandemic our focus was influenza; now it's COVID. We procure unique data streams that reflect epidemic (or pandemic) activity, extract relevant indicators, and make these publicly and continuously available. These indicators are then used for nowcasting (situational awareness) and short-term forecasting. +We're a research group based out of Carnegie Mellon University dedicated to developing the theory and practice of epidemic tracking and forecasting. Pre-pandemic we worked mostly on influenza, dengue and norovirus; now we focus on COVID. We procure unique data streams that reflect epidemic (or pandemic) activity, extract relevant indicators, and make these publicly and continuously available. We and others then use these indicators for nowcasting (situational awareness) and short-term forecasting. ### Who is our audience? -Public health authorities (federal, state, local), fellow researchers (working on epidemic tracking and forecasting), public and private sectors, data journalists, and the general public. +Public health authorities (federal, state, local), the healthcare industry, the public and private sectors, fellow researchers working on epidemic tracking and forecasting, data journalists, and the general public. ### Delphi's milestones -- Since 2013, we've supported CDC's Influenza Division in advancing and growing a [scientific community around flu forecasting](https://www.cdc.gov/flu/weekly/flusight/index.html). We've been perennial leaders in forecasting accuracy. +- Since 2013, we've supported U.S. CDC's Influenza Division in advancing and growing a [scientific community around flu forecasting](https://www.cdc.gov/flu/weekly/flusight/index.html). We've been perennial leaders in forecasting accuracy. -- Since 2016, we've developed the [Epidata API]({{< apiref "/" >}}), which provides real-time access to epidemiological surveillance data. +- Since 2016, we've developed the [Delphi Epidata API]({{< apiref "/" >}}), which provides real-time access to epidemiological surveillance data. -- Since 2016, we've been providing [flu nowcasts](https://delphi.cmu.edu/nowcast/) to state departments of health. +- Since 2016, we've been providing [flu nowcasts](https://delphi.cmu.edu/nowcast/) to U.S. CDC, states' departments of health, and the public. -- Since 2019, we've been working directly with CDC as a National Center of Excellence for Influenza Forecasting (a 5-year designation). +- Since 2019, we've been working directly with U.S. CDC as a National Center of Excellence for Influenza Forecasting (a 5-year designation). -- Since March 2020, we've created and maintained the [nation's largest public repository of diverse, geographically-detailed, real-time indicators of COVID-19 activity]({{< relref "covidcast" >}}) in the U.S. Our indicators cover every rung of the [severity pyramid](https://docs.google.com/presentation/d/1jvIycxDRMEIozKIowv2UyvSqZyF5y6jR8EAXUEK22D4/edit?usp=sharing), and they're freely available through a [public API]({{< apiref "api/covidcast.html" >}}). +- Since March 2020, we've created and maintained the [nation's largest public repository of diverse, geographically-detailed, real-time indicators of COVID-19 activity]({{< relref "covidcast" >}}) in the U.S. Our indicators cover every rung of the [severity pyramid](https://docs.google.com/presentation/d/1jvIycxDRMEIozKIowv2UyvSqZyF5y6jR8EAXUEK22D4/edit?usp=sharing), and are freely available through a [public API]({{< apiref "api/covidcast.html" >}}). -- Several of the underlying data sources (on which these indicators are built) would not exist or be publicly available without our efforts. This includes: +- Several of the underlying data sources (on which these indicators are built) would not exist or be publicly available without our efforts. This includes: - * A massive [national daily survey]({{< relref "surveys">}}) we're running in [partnership with Facebook](https://covid-survey.dataforgood.fb.com/survey_and_map_data.html). This has reached over 12 million Americans since April, providing real-time insights into, e.g., [self-reported symptoms]({{< relref "2020-08-26-fb-survey#whats-in-the-survey" >}}), [mask wearing]({{< relref "2020-10-06-survey-wave-4.html#mask-wearing" >}}), [testing]({{< relref "2020-10-06-survey-wave-4#testing" >}}), and contacts, all broken down by various demographics. + - A massive [national daily survey]({{< relref "surveys">}}) we're running in [partnership with Facebook](https://covid-survey.dataforgood.fb.com/survey_and_map_data.html). Over 12 million Americans have answered the survey since April, providing real-time insights into, e.g., [self-reported symptoms]({{< relref "2020-08-26-fb-survey#whats-in-the-survey" >}}), [mask wearing]({{< relref "2020-10-06-survey-wave-4.html#mask-wearing" >}}), [testing]({{< relref "2020-10-06-survey-wave-4#testing" >}}), and contacts, all broken down by various demographics. - * An enormous database of de-identified medical insurance claims, covering more than half the US population, made possible through health system partners including Change Healthcare. We use this to produce a new [syndromic COVID-19 indicator based on doctor visits]({{< relref "2020-10-14-dv-signal" >}}), and other indicators based on hospitalizations and ICU admissions. + - An enormous database of medical insurance claims that have been de-identified in accordance with HIPAA privacy regulations, covering more than half the US population, made possible through health system partners including Change Healthcare. We use this to produce a new [syndromic COVID-19 indicator based on doctor visits]({{< relref "2020-10-14-dv-signal" >}}), and other indicators based on hospitalizations and ICU admissions. -- Since April 2020, we've been supporting and advising the CDC in their community-driven COVID-19 forecasting effort, which includes [creating and evaluating an ensemble forecast]({{< relref "2020-09-21-forecast-demo" >}}) from the 70+ forecasts under submission that serves as the basis for the [CDC's official COVID-19 forecast communications](https://www.cdc.gov/coronavirus/2019-ncov/covid-data/forecasting-us.html). We also contribute our own short-term forecasts of COVID-19 cases and deaths, which can be found in the [COVID-19 Forecast Hub](https://covid19forecasthub.org). +- Since April 2020, we've been supporting and advising U.S. CDC in their community-driven COVID-19 forecasting effort, which includes [creating and evaluating an ensemble forecast]({{< relref "2020-09-21-forecast-demo" >}}) from the 70+ forecasts under submission that serves as the basis for the [CDC's official COVID-19 forecast communications](https://www.cdc.gov/coronavirus/2019-ncov/covid-data/forecasting-us.html). We also contribute our own short-term forecasts of COVID-19 cases and deaths, which can be found in the [COVID-19 Forecast Hub](https://covid19forecasthub.org). diff --git a/content/about/publications/index.md b/content/about/publications/index.md index a7b8ff765..2ba78888b 100644 --- a/content/about/publications/index.md +++ b/content/about/publications/index.md @@ -1,54 +1,54 @@ --- title: Research and White Papers papers: -- title: "Pancasting: forecasting epidemics from provisional data" - image: pancasting.png - authors: Brooks - link: https://delphi.cmu.edu/~lcbrooks/brooks2020pancasting.pdf - journal: PhD thesis - year: 2020 -- title: "Kalman filter, sensor fusion, and constrained regression: equivalences and insights" - image: kalman_filter.png - authors: Jahja, Farrow, Rosenfeld, Tibshirani - link: https://papers.nips.cc/paper/9475-kalman-filter-sensor-fusion-and-constrained-regression-equivalences-and-insights - journal: Neural Information Processing Systems - year: 2019 -- title: "Nonmechanistic forecasts of seasonal influenza with iterative one-week-ahead distributions" - image: nonmechanistic_forecasts.png - authors: Brooks, Farrow, Hyun, Tibshirani, Rosenfeld - link: https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1006134 - journal: PLOS Computational Biology - year: 2018 -- title: "A human judgment approach to epidemiological forecasting" - image: human.png - authors: Farrow, Brooks, Hyun, Tibshirani, Burke, Rosenfeld - link: https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1005248 - journal: PLOS Computational Biology - year: 2017 -- title: "Modeling the past, present, and future of influenza" - image: modeling.png - authors: Farrow - link: https://delphi.cmu.edu/~dfarrow/thesis.pdf - journal: PhD thesis - year: 2016 -- title: "Flexible modeling of epidemics with an empirical Bayes framework" - image: flexible_modeling.png - authors: Brooks, Farrow, Hyun, Tibshirani, Rosenfeld - link: https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1004382 - journal: PLOS Computational Biology - year: 2015 -- title: "Predicting the predictable" - image: predicting.png - authors: Rosenfeld - link: https://delphi.cmu.edu/files/PredictingThePredictable_13-04-03.pdf - journal: presentation - year: 2013 -- title: "A proposal for standardized evaluation of epidemiological models" - image: evaluation.png - authors: Rosenfeld, Grefenstette, Burke - link: http://www.cs.cmu.edu/~roni/standardized-evaluation-of-epi-models-rev-09nov2012.pdf - journal: White paper - year: 2012 + - title: "Pancasting: forecasting epidemics from provisional data" + image: pancasting.png + authors: Brooks + link: https://delphi.cmu.edu/~lcbrooks/brooks2020pancasting.pdf + journal: PhD thesis + year: 2020 + - title: "Kalman filter, sensor fusion, and constrained regression: equivalences and insights" + image: kalman_filter.png + authors: Jahja, Farrow, Rosenfeld, Tibshirani + link: https://papers.nips.cc/paper/9475-kalman-filter-sensor-fusion-and-constrained-regression-equivalences-and-insights + journal: Neural Information Processing Systems + year: 2019 + - title: "Nonmechanistic forecasts of seasonal influenza with iterative one-week-ahead distributions" + image: nonmechanistic_forecasts.png + authors: Brooks, Farrow, Hyun, Tibshirani, Rosenfeld + link: https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1006134 + journal: PLOS Computational Biology + year: 2018 + - title: "A human judgment approach to epidemiological forecasting" + image: human.png + authors: Farrow, Brooks, Hyun, Tibshirani, Burke, Rosenfeld + link: https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1005248 + journal: PLOS Computational Biology + year: 2017 + - title: "Modeling the past, present, and future of influenza" + image: modeling.png + authors: Farrow + link: https://delphi.cmu.edu/~dfarrow/thesis.pdf + journal: PhD thesis + year: 2016 + - title: "Flexible modeling of epidemics with an empirical Bayes framework" + image: flexible_modeling.png + authors: Brooks, Farrow, Hyun, Tibshirani, Rosenfeld + link: https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1004382 + journal: PLOS Computational Biology + year: 2015 + - title: "Predicting the predictable" + image: predicting.png + authors: Rosenfeld + link: https://delphi.cmu.edu/files/PredictingThePredictable_13-04-03.pdf + journal: presentation + year: 2013 + - title: "A proposal for standardized evaluation of epidemiological models" + image: evaluation.png + authors: Rosenfeld, Grefenstette, Burke + link: http://www.cs.cmu.edu/~roni/standardized-evaluation-of-epi-models-rev-09nov2012.pdf + journal: White paper + year: 2012 --- {{}} diff --git a/content/about/team/images/ana-karina-van-nortwick.jpeg b/content/about/team/images/ana-karina-van-nortwick.jpeg new file mode 100644 index 000000000..68e632339 Binary files /dev/null and b/content/about/team/images/ana-karina-van-nortwick.jpeg differ diff --git a/content/about/team/images/benjamin-smith_head-shot.jpg b/content/about/team/images/benjamin-smith_head-shot.jpg new file mode 100644 index 000000000..6a2613e4e Binary files /dev/null and b/content/about/team/images/benjamin-smith_head-shot.jpg differ diff --git a/content/about/team/images/benjamin-smith_head-shot.png b/content/about/team/images/benjamin-smith_head-shot.png deleted file mode 100644 index 6bc839cc9..000000000 Binary files a/content/about/team/images/benjamin-smith_head-shot.png and /dev/null differ diff --git a/content/about/team/images/benjamin-weaver_head-shot.png b/content/about/team/images/benjamin-weaver_head-shot.png index 8a18c80ea..74b061386 100644 Binary files a/content/about/team/images/benjamin-weaver_head-shot.png and b/content/about/team/images/benjamin-weaver_head-shot.png differ diff --git a/content/about/team/images/chris-scott_head-shot.jpg b/content/about/team/images/chris-scott_head-shot.jpg new file mode 100644 index 000000000..334485b70 Binary files /dev/null and b/content/about/team/images/chris-scott_head-shot.jpg differ diff --git a/content/about/team/images/chris-scott_head-shot.png b/content/about/team/images/chris-scott_head-shot.png deleted file mode 100644 index 51329a300..000000000 Binary files a/content/about/team/images/chris-scott_head-shot.png and /dev/null differ diff --git a/content/about/team/images/daniel-laliberte_head-shot.jpg b/content/about/team/images/daniel-laliberte_head-shot.jpg new file mode 100644 index 000000000..62ab4d377 Binary files /dev/null and b/content/about/team/images/daniel-laliberte_head-shot.jpg differ diff --git a/content/about/team/images/daniel-laliberte_head-shot.png b/content/about/team/images/daniel-laliberte_head-shot.png deleted file mode 100644 index 8e85b5b7f..000000000 Binary files a/content/about/team/images/daniel-laliberte_head-shot.png and /dev/null differ diff --git a/content/about/team/images/daniel-mcdonald-photo.jpeg b/content/about/team/images/daniel-mcdonald-photo.jpeg new file mode 100644 index 000000000..99a0d62f3 Binary files /dev/null and b/content/about/team/images/daniel-mcdonald-photo.jpeg differ diff --git a/content/about/team/images/david-farrow-500x500-min.jpg b/content/about/team/images/david-farrow-500x500-min.jpg deleted file mode 100644 index 14cf61893..000000000 Binary files a/content/about/team/images/david-farrow-500x500-min.jpg and /dev/null differ diff --git a/content/about/team/images/david-farrow_head-shot.jpg b/content/about/team/images/david-farrow_head-shot.jpg new file mode 100644 index 000000000..92b514938 Binary files /dev/null and b/content/about/team/images/david-farrow_head-shot.jpg differ diff --git a/content/about/team/images/david-farrow_head-shot.png b/content/about/team/images/david-farrow_head-shot.png deleted file mode 100644 index cc1c7038a..000000000 Binary files a/content/about/team/images/david-farrow_head-shot.png and /dev/null differ diff --git a/content/about/team/images/george-haff-photo.jpg b/content/about/team/images/george-haff-photo.jpg new file mode 100644 index 000000000..8e762fc28 Binary files /dev/null and b/content/about/team/images/george-haff-photo.jpg differ diff --git a/content/about/team/images/jed-gradmn_head-shot.png b/content/about/team/images/jed-gradmn_head-shot.png index 7d5a99f55..1414b3cef 100644 Binary files a/content/about/team/images/jed-gradmn_head-shot.png and b/content/about/team/images/jed-gradmn_head-shot.png differ diff --git a/content/about/team/images/kate-harwood_head-shot.jpg b/content/about/team/images/kate-harwood_head-shot.jpg new file mode 100644 index 000000000..d66f61490 Binary files /dev/null and b/content/about/team/images/kate-harwood_head-shot.jpg differ diff --git a/content/about/team/images/kate-harwood_head-shot.png b/content/about/team/images/kate-harwood_head-shot.png deleted file mode 100644 index 956cf3b8b..000000000 Binary files a/content/about/team/images/kate-harwood_head-shot.png and /dev/null differ diff --git a/content/about/team/images/mike-o'brian_head-shot.png b/content/about/team/images/mike-o'brian_head-shot.png deleted file mode 100644 index 0e1e8a3bf..000000000 Binary files a/content/about/team/images/mike-o'brian_head-shot.png and /dev/null differ diff --git a/content/about/team/images/mike-o'brien_head-shot.jpg b/content/about/team/images/mike-o'brien_head-shot.jpg new file mode 100644 index 000000000..ce93db3e2 Binary files /dev/null and b/content/about/team/images/mike-o'brien_head-shot.jpg differ diff --git a/content/about/team/images/nat-defries.jpg b/content/about/team/images/nat-defries.jpg new file mode 100644 index 000000000..0f86a630a Binary files /dev/null and b/content/about/team/images/nat-defries.jpg differ diff --git a/content/about/team/images/phil-mcguinness_head-shot.png b/content/about/team/images/phil-mcguinness_head-shot.png index e2c3721f5..70071d977 100644 Binary files a/content/about/team/images/phil-mcguinness_head-shot.png and b/content/about/team/images/phil-mcguinness_head-shot.png differ diff --git a/content/about/team/images/raphael-hyde_head-shot.jpg b/content/about/team/images/raphael-hyde_head-shot.jpg new file mode 100644 index 000000000..0c5a12ce4 Binary files /dev/null and b/content/about/team/images/raphael-hyde_head-shot.jpg differ diff --git a/content/about/team/images/raphael-hyde_head-shot.png b/content/about/team/images/raphael-hyde_head-shot.png deleted file mode 100644 index 2c3c26b41..000000000 Binary files a/content/about/team/images/raphael-hyde_head-shot.png and /dev/null differ diff --git a/content/about/team/images/sarah-colquhoun_head-shot.jpg b/content/about/team/images/sarah-colquhoun_head-shot.jpg new file mode 100644 index 000000000..0284ae2cf Binary files /dev/null and b/content/about/team/images/sarah-colquhoun_head-shot.jpg differ diff --git a/content/about/team/images/sarah-colquhoun_head-shot.png b/content/about/team/images/sarah-colquhoun_head-shot.png deleted file mode 100644 index 2c586ad7e..000000000 Binary files a/content/about/team/images/sarah-colquhoun_head-shot.png and /dev/null differ diff --git a/content/about/team/images/shreenath-regunathan-head-shot.jpg b/content/about/team/images/shreenath-regunathan-head-shot.jpg new file mode 100644 index 000000000..9db586e5c Binary files /dev/null and b/content/about/team/images/shreenath-regunathan-head-shot.jpg differ diff --git a/content/about/team/images/specer-whitman_head-shot.jpg b/content/about/team/images/specer-whitman_head-shot.jpg new file mode 100644 index 000000000..dfd6fb08b Binary files /dev/null and b/content/about/team/images/specer-whitman_head-shot.jpg differ diff --git a/content/about/team/images/specer-whitman_head-shot.png b/content/about/team/images/specer-whitman_head-shot.png deleted file mode 100644 index 8c687184e..000000000 Binary files a/content/about/team/images/specer-whitman_head-shot.png and /dev/null differ diff --git a/content/about/team/images/sumit-agrawal_head-shot.png b/content/about/team/images/sumit-agrawal_head-shot.png index 653a8294d..c4e58da16 100644 Binary files a/content/about/team/images/sumit-agrawal_head-shot.png and b/content/about/team/images/sumit-agrawal_head-shot.png differ diff --git a/content/about/team/images/wichada-lamotte-kerr-photo.png b/content/about/team/images/wichada-lamotte-kerr-photo.png new file mode 100644 index 000000000..1f60ce423 Binary files /dev/null and b/content/about/team/images/wichada-lamotte-kerr-photo.png differ diff --git a/content/about/team/index.md b/content/about/team/index.md index 145e67997..ca73255f1 100644 --- a/content/about/team/index.md +++ b/content/about/team/index.md @@ -7,344 +7,469 @@ team: lastName: Bien image: jacob-bien-500x500-min.jpg affiliation: University of Southern California - team: core + team: + - core - firstName: Logan lastName: Brooks image: logan-brooks-500x500-min.jpg affiliation: CMU/MLD - team: core + team: + - core + - highlight +- firstName: Andrew + lastName: Chin + image: andrew-chin-500x500-min.jpg + affiliation: CMU/MLD + team: + - core - firstName: Brian lastName: Clark image: brian-clark-500x500-min.jpg affiliation: CMU/MLD - team: core + team: + - core + - highlight +- firstName: Nat + lastName: DeFries + image: nat-defries.jpg + affiliation: CMU/MLD + team: + - core - firstName: Jodi lastName: Forlizzi image: jodi-forlizzi-500x500-min.jpg affiliation: CMU/HCII - team: core + team: + - core - firstName: George lastName: Haff - image: profile-placeholder.png + image: george-haff-photo.jpg affiliation: CMU/CSD - team: core + team: + - core - firstName: Addison lastName: Hu image: addison-hu-500x500-min.jpg affiliation: CMU/Stat - team: core + team: + - core - firstName: Maria lastName: Jahja image: maria-jahja-500x500-min.jpg affiliation: CMU/Stat - team: core + team: + - core + - highlight +- firstName: Ananya + lastName: Joshi + image: ananya-joshi-500x500-min.jpg + affiliation: CMU/CSD + team: + - core - firstName: Zack lastName: Lipton image: zachary-lipton-500x500-min.jpg affiliation: CMU/MLD - team: core + team: + - core - firstName: Kathryn lastName: Rivard lastName: Mazaitis image: kathryn-mazaitis-500x500-min.jpg affiliation: CMU/MLD - team: core + team: + - core + - highlight +- firstName: Daniel + lastName: McDonald + image: daniel-mcdonald-photo.jpeg + affiliation: University of British Columbia + team: + - core - firstName: Balasubramanian lastName: Narasimhan image: balasubramanian-narasimhan-500x500-min.jpg affiliation: Stanford University - team: core -- firstName: Adam - lastName: Perer - image: adam-perer-500x500-min.jpg - affiliation: CMU/HCII - team: core + team: + - core - firstName: Collin lastName: Politsch image: collin-politsch-500x500-min.jpg affiliation: CMU/MLD - team: core + team: + - core - firstName: Alex lastName: Reinhart image: alex-reinhart-500x500-min.jpg affiliation: CMU/Stat - team: core + team: + - core - firstName: Roni lastName: Rosenfeld image: roni-rosenfeld-500x500-min.jpg affiliation: CMU/MLD - team: leadership + team: + - leadership + - highlight - firstName: Aaron lastName: Rumack image: aaron-rumack-500x500-min.jpg affiliation: CMU/MLD - team: core + team: + - core + - highlight - firstName: James lastName: Sharpnack image: james-sharpnack-500x500-min.jpg affiliation: UC Davis - team: core + team: + - core - firstName: Dmitry lastName: Shemetov image: dmitry-shemetov-500x500-min.jpg - affiliation: UC Davis - team: core + affiliation: CMU/MLD + team: + - core - firstName: Jingjing lastName: Tang image: jinjing-tang-500x500-min.jpg affiliation: CMU/CompBio - team: core + team: + - core + - highlight - firstName: Robert lastName: Tibshirani image: robert-tibshirani-500x500-min.jpg affiliation: Stanford University - team: core + team: + - core - firstName: Ryan lastName: Tibshirani image: ryan-tibshirani-500x500-min.jpg affiliation: CMU/MLD/Stat - team: leadership + team: + - leadership + - highlight +- firstName: Ana Karina + lastName: Van Nortwick + image: ana-karina-van-nortwick.jpeg + affiliation: Tech Writer + team: + - core - firstName: Valérie lastName: Ventura image: valerie-ventura-500x500-min.jpg affiliation: CMU/Stat - team: core + team: + - core - firstName: Larry lastName: Wasserman image: larry-wasserman-500x500-min.jpg affiliation: CMU/Stat - team: core + team: + - core - firstName: Jeremy lastName: Weiss image: jeremy-weiss-500x500-min.jpg affiliation: CMU/Heinz College - team: core - -- firstName: Amartya - lastName: Basu - image: amartya-basu-500x500-min.jpg - affiliation: CMU/INI - team: interns -- firstName: Eu Jing - lastName: Chua - image: eu-jing-chua-500x500-min.jpg + team: + - core +- firstName: Wichada + lastName: La Motte‑Kerr + image: wichada-lamotte-kerr-photo.png affiliation: CMU/MLD - team: interns -- firstName: Robin - lastName: Han - image: robin-han-500x500-min.jpg - affiliation: CMU/HCII - team: interns -- firstName: Jenny - lastName: Lee - image: jenny-yeon-jin-lee-500x500-min.jpg - affiliation: CMU/HCII - team: interns -- firstName: Wael Al - lastName: Saeed - image: wael-al-saeed-500x50-min.jpg - affiliation: CMU/CSD - team: interns -- firstName: Vishnu - lastName: Shankar - image: vishn-hankar-500x500-min.jpg - affiliation: Stanford University - team: interns -- firstName: Vishakha - lastName: Srivastava - image: vishakha-srivastava-500x500-min.jpg - affiliation: Santa Clara University - team: interns - -- firstName: EJ - lastName: Fox - image: ej-fox-500x500-min.jpg - affiliation: Data visualization consultant - team: contractors + team: + - core - firstName: Samuel lastName: Gratzl image: sam-gratzl-500x500-min.jpg affiliation: Data visualization consultant - team: contractors - + team: + - contractors - firstName: Dawn lastName: Rucker image: dawn-rucker-500x500-min.jpg affiliation: The Rucker Group - team: advisors + team: + - advisors - firstName: Nigam lastName: Shah image: nigram-shah-500x500-min.jpg affiliation: Stanford University - team: advisors - + team: + - advisors - firstName: Taylor lastName: Arnold image: taylor-arnold-500x500-min.jpg affiliation: University of Richmond - team: contributors + team: + - contributors note: Core member, May–June 2020 -- firstName: Andrew - lastName: Chin - image: andrew-chin-500x500-min.jpg - affiliation: - team: contributors +- firstName: Eu Jing + lastName: Chua + image: eu-jing-chua-500x500-min.jpg + affiliation: CMU/MLD + team: + - contributors + note: Intern, Summer 2020 - firstName: Alden lastName: Green image: alden-green-500x500-min.jpg affiliation: CMU/Stat note: Core member, May–July 2020 - team: contributors -- firstName: Sangwon (Justin) - lastName: Hyun - image: sangwon-justin-hyun-500x500-min.jpg - affiliation: USC - team: contributors - note: Core member, March – May 2020 -- firstName: Jaemin - lastName: Jo - image: jaemin-jo-500x500-min.jpg - affiliation: Seoul National University - team: contributors -- firstName: Ananya - lastName: Joshi - image: ananya-joshi-500x500-min.jpg - affiliation: CMU/CSD - team: contributors + team: + - contributors - firstName: Jimi lastName: Kim image: jimi-kim-500x500-min.jpg affiliation: CMU/LTI - note: Core member, March – April 2020 - team: contributors -- firstName: Michael - lastName: Xieyang - lastName: Liu - image: michael-xieyang-liu-500x500-min.jpg + note: Core member, March–April 2020 + team: + - contributors +- firstName: Jenny + lastName: Lee + image: jenny-yeon-jin-lee-500x500-min.jpg affiliation: CMU/HCII - team: contributors - note: Core member, March – April 2020 + team: + - contributors + note: Intern, Summer 2020 +- firstName: Kenneth + lastName: Lee + image: profile-placeholder.png + affiliation: + team: + - contributors - firstName: Natalia - lastName: Lombardi de Oliveira + lastName: Lombardi de Oliveira image: natalia-lombardi-de-oliveira-500x500-min.jpg affiliation: CMU/Stat - team: contributors + team: + - contributors note: Core member, March – May 2020 -- firstName: Samyak - lastName: Rajanala - image: samyak-rajanala-500x500-min.jpg - affiliation: Stanford University - team: contributors - note: Core member, May – July 2020 -- firstName: Kristin - lastName: Williams - image: kristin-williams-500x500-min.jpg +- firstName: Adam + lastName: Perer + image: adam-perer-500x500-min.jpg affiliation: CMU/HCII - team: contributors - note: Core member, March – April 2020 - + team: + - contributors + note: Core member, March - October 2020 +- firstName: Vishnu + lastName: Shankar + image: vishn-hankar-500x500-min.jpg + affiliation: Stanford University + team: + - contributors + note: Intern, Summer 2020 +- firstName: Venkatesh + lastName: Sivaraman + image: profile-placeholder.png + affiliation: + team: + - contributors +- firstName: Helen + lastName: Zhou + image: profile-placeholder.png + affiliation: + team: + - contributors +- firstName: Wael Al + lastName: Saeed + image: wael-al-saeed-500x50-min.jpg + affiliation: CMU/CSD + team: + - past + note: Intern, Summer 2020 +- firstName: Amartya + lastName: Basu + image: amartya-basu-500x500-min.jpg + affiliation: CMU/INI + team: + - past + note: Intern, 2020 - firstName: Angel (Alex) lastName: Cabrera image: angel-alex-cabrera-500x500-min.jpg affiliation: CMU/HCII - team: past - note: Core member, March – April 2020 -- firstName: David - lastName: Farrow - image: david-farrow-500x500-min.jpg - affiliation: Google - team: past - note: Founding member 2012–2016, Core member March–April 2020 + team: + - past + note: Core member, March–April 2020 +- firstName: EJ + lastName: Fox + image: ej-fox-500x500-min.jpg + affiliation: Data visualization consultant + team: + - past + note: Contractor, 2020 +- firstName: Shantanu + lastName: Gupta + image: profile-placeholder.png + affiliation: + team: + - past + note: Contributor, 2020 +- firstName: Robin + lastName: Han + image: robin-han-500x500-min.jpg + affiliation: CMU/HCII + team: + - past + notes: Intern, summer 2020 +- firstName: Sangwon (Justin) + lastName: Hyun + image: sangwon-justin-hyun-500x500-min.jpg + affiliation: USC + team: + - past + note: Core member, March–May 2020; Contributor, May–July 2020 +- firstName: Jaemin + lastName: Jo + image: jaemin-jo-500x500-min.jpg + affiliation: Seoul National University + team: + - Contributor, 2020 - firstName: Andrew lastName: Kuznetsov image: andrew-kuznetsov-500x500-min.jpg affiliation: CMU/HCII - team: past - note: Core member, March – April 2020 + team: + - past + note: Core member, March–April 2020 +- firstName: Michael + lastName: Xieyang + lastName: Liu + image: michael-xieyang-liu-500x500-min.jpg + affiliation: CMU/HCII + team: + - past + note: Core member, March–April 2020; Contributor 2020 - firstName: Lester lastName: Mackey image: lester-mackey-500x500-min.jpg affiliation: Microsoft Research/Stanford - team: past - note: Core member, March – May 2020 + team: + - past + note: Core member, March–May 2020 - firstName: Pratik lastName: Patil image: pratik-patil-500x500-min.jpg affiliation: CMU/Stat - team: past - note: Core member, March – May 2020 + team: + - past + note: Core member, March–May 2020 +- firstName: Samyak + lastName: Rajanala + image: samyak-rajanala-500x500-min.jpg + affiliation: Stanford University + team: + - past + note: Core member, May–July 2020 - firstName: Noah lastName: Simon image: noah-simon-500x500-min.jpg affiliation: University of Washington - team: past - note: Core member, may – June 2020 - + team: + - past + note: Core member, May–June 2020 +- firstName: Vishakha + lastName: Srivastava + image: vishakha-srivastava-500x500-min.jpg + affiliation: Santa Clara University + team: + - past + note: Intern, Summer 2020 +- firstName: Kristin + lastName: Williams + image: kristin-williams-500x500-min.jpg + affiliation: CMU/HCII + team: + - past + note: Core member, March–April 2020; Contributor 2020 - firstName: Mike lastName: O'Brien - image: mike-o'brian_head-shot.png + image: mike-o'brien_head-shot.jpg affiliation: Software Engineer - team: google + team: + - google - firstName: Kate lastName: Harwood - image: kate-harwood_head-shot.png + image: kate-harwood_head-shot.jpg affiliation: Software Engineer - team: google + team: + - google - firstName: Sumit lastName: Agrawal image: sumit-agrawal_head-shot.png affiliation: Program Manager Lead - team: google + team: + - google - firstName: Benjamin lastName: Weaver image: benjamin-weaver_head-shot.png affiliation: Program / Project Manager - team: google + team: + - google - firstName: Spencer lastName: Whitman - image: specer-whitman_head-shot.png - affiliation: Project Manager - team: google + image: specer-whitman_head-shot.jpg + affiliation: Product Manager + team: + - google - firstName: Benjamin lastName: Smith - image: benjamin-smith_head-shot.png + image: benjamin-smith_head-shot.jpg affiliation: Tech Lead Software Engineer - team: google + team: + - google - firstName: Raphael lastName: Hyde - image: raphael-hyde_head-shot.png + image: raphael-hyde_head-shot.jpg affiliation: UX Designer - team: google + team: + - google - firstName: Phil lastName: McGuinness image: phil-mcguinness_head-shot.png affiliation: UX Researcher - team: google + team: + - google - firstName: Jed lastName: Grabman image: jed-gradmn_head-shot.png affiliation: Site Reliability Engineer, Data Scientist - team: google + team: + - google - firstName: Sarah lastName: Colquhoun - image: sarah-colquhoun_head-shot.png + image: sarah-colquhoun_head-shot.jpg affiliation: Site Reliability Engineer, Data Scientist - team: google + team: + - google - firstName: Chris lastName: Scott - image: chris-scott_head-shot.png + image: chris-scott_head-shot.jpg affiliation: Tech Lead Software Engineer - team: google + team: + - google - firstName: Daniel lastName: LaLiberte - image: daniel-laliberte_head-shot.png + image: daniel-laliberte_head-shot.jpg affiliation: Software Engineer - team: google + team: + - google - firstName: David lastName: Farrow - image: david-farrow_head-shot.png + image: david-farrow_head-shot.jpg affiliation: Software Engineer - team: google + team: + - google + note: Founding member 2012–2016, Core member March–April 2020 +- firstName: Shreenath + lastName: Regunathan + image: shreenath-regunathan-head-shot.jpg + affiliation: Product Manager + team: + - google + others: | MLD administrators Christy Melucci and Alison Chiocchi; CMU’s wonderful Communications, IT, Legal, OSP, and IRB teams, including Scott Ambrose, Amber Becker, Stacey Becker, Amanda Berneburg, Susan Brunner, Steve Chabassol, Cindy Chepanoske, Ethan Connor, Amy Coutu, John Dermott, Ed Garbade, Greg Gillotti, Akshaya Gupta, Scott Haas, Ryan Jackson, Rasha Kolia, Chris Kornell, Jason Maderer, Dave McMurtrie, Craig Miron, Roman Mitz, Matt Nagel, Allie Oswell, John Porco, Mark Power, Laura Raderman, Teri Reiche, Bob Rittiger, Edem Setodji, Jennifer Smith, Steve Snodgrass, Julia Sobol Dzurino, Byron Spice, Dom Travisano, Alex Visbisky, and Walter Wong; and the entire CMU senior leadership team. @@ -365,10 +490,6 @@ abbreviations: {{}} -## Interns - -{{}} - ## Google Fellows {{}} diff --git a/content/bibliography.md b/content/bibliography.md index 92df93b31..fb399fce1 100644 --- a/content/bibliography.md +++ b/content/bibliography.md @@ -1,8 +1,365 @@ --- title: Bibliography description: Developing the Theory and Practice of Epidemiological Forecasting + +bibliography: + - key: "2015 [Farrow ]" + link: /~dfarrow/thesis.pdf + title: "Modeling the Past, Present, and Future of Influenza." + authors: David C. Farrow - PhD Thesis + journal: Carnegie Mellon University + year: 2016 + + - key: "2015 [Brooks, ]" + link: http://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1004382 + title: "Flexible Modeling of Epidemics with an Empirical Bayes Framework." + authors: Logan C. Brooks, David C. Farrow, Sangwon Hyun, Ryan J. Tibshirani, and Roni Rosenfeld. + journal: PLoS Computational Biology + issue: "11(8): e1004382" + doi: 10.1371/journal.pcbi.1004382 + year: 2015 + + - key: "2015 [Farrow, ]" + link: http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0125047 + title: "Computational Characterization of Transient Strain-Transcending Immunity against Influenza A." + authors: David C. Farrow, Donald S. Burke, and Roni Rosenfeld. + journal: PLoS ONE + issue: "10(5): e0125047" + doi: 10.1371/journal.pone.0125047 + year: 2015 + + - key: "2014 [Santilla]" + link: http://www.sciencedirect.com/science/article/pii/S0749379714002384 + title: "What Can Digital Disease Detection Learn from (an External Revision to) Google Flu Trends?" + authors: Santillana, Mauricio, D. Wendong Zhang, Benjamin M. Althouse, and John W. Ayers. + journal: American Journal of Preventive Medicine + year: 2014 + + - key: "2014 [Panhuis,]" + link: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC4120682/ + title: "Risk of Dengue for Tourists and Teams during the World Cup 2014 in Brazil." + authors: Willem G. van Panhuis, Sangwon Hyun, Kayleigh Blaney, Ernesto T. A. Marques, Jr, Giovanini E. Coelho, João Bosco Siqueira, Jr, Ryan Tibshirani, Jarbas B. da Silva, Jr, Roni Rosenfeld. + journal: PLoS Neglected Tropical Diseases + issue: "July; 8(7): e3063." + doi: 10.1371/journal.pntd.0003063. + PMCID: PMC4120682 + year: 2014 + + - key: "2014 [Łuksza, ]" + link: http://www.nature.com/nature/journal/v507/n7490/abs/nature13087.html + title: "A predictive fitness model for influenza." + authors: Łuksza, Marta, and Michael Lässig. + journal: Nature + issue: "507, no. 7490 (2014): 57-61." + + - key: "2014 [Lowe, Ra]" + link: http://www.sciencedirect.com/science/article/pii/S1473309914707819 + title: "Dengue outlook for the World Cup in Brazil: an early warning model framework driven by real-time seasonal climate forecasts." + authors: Lowe, Rachel, Christovam Barcellos, Caio AS Coelho, Trevor C. Bailey, Giovanini Evelim Coelho, Richard Graham, Tim Jupp et al. + journal: The Lancet infectious diseases + year: "2014" + + - key: "2014 [Lazer, D]" + link: http://dash.harvard.edu/handle/1/12016836 + title: "The parable of Google Flu: Traps in big data analysis." + authors: Lazer, David M., Ryan Kennedy, Gary King, and Alessandro Vespignani. + year: "2014" + + - key: "2014 [Koelle, ]" + link: http://www.nature.com/nature/journal/vaop/ncurrent/full/nature13054.html + title: "Influenza: Prediction is worth a shot." + authors: Koelle, Katia, and David A. Rasmussen. + journal: Nature + year: "2014" + + - key: "2014 [Nsoesie,]" + link: http://onlinelibrary.wiley.com/doi/10.1111/irv.12226/full + title: "A systematic review of studies on forecasting the dynamics of influenza outbreaks." + authors: Nsoesie, Elaine O., John S. Brownstein, Naren Ramakrishnan, and Madhav V. Marathe. + journal: Influenza and other respiratory viruses + year: "2014" + + - key: "2013 [Sitepu, ]" + link: http://www.tm.mahidol.ac.th/seameo/2013-44-2-full/10-5657-16.pdf + title: "Temporal Patterns and a Disease Forecasting Model of Dengue Hemorrhagic Fever in Jakarta Based on 10 Years of Surveillance Data." + authors: Sitepu, Monika S., Jaranit Kaewkungwal, Nathanej Luplerdlop, Ngamphol Soonthornworasiri, Tassanee Silawan, Supawadee Poungsombat, and Saranath Lawpoolsri. + journal: The Southeast Asian journal of tropical medicine and public health + issue: "44, no. 2 (2013): 206-217." + + - key: "2013 [Nsoesie,]" + link: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3712489/ + title: "Forecasting peaks of seasonal influenza epidemics." + authors: Nsoesie, Elaine, Madhav Mararthe, and John Brownstein. + journal: PLoS currents + issue: "5" + year: 2013 + + - key: "2013 [Levinson]" + link: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3649003/ + title: "Targeting surveillance for zoonotic virus discovery." + authors: Levinson, Jordan, Tiffany L. Bogich, Kevin J. Olival, Jonathan H. Epstein, Christine K. Johnson, William Karesh, and Peter Daszak. + journal: Emerging infectious diseases + issue: "19, no. 5 (2013): 743." + + - key: "2013 [Fuller, ]" + link: http://www.eomf.ou.edu/media/docs/upload/Reassortment__EID_2013.pdf + title: "Predicting hotspots for influenza virus reassortment." + authors: Fuller, Trevon L., Marius Gilbert, Vincent Martin, Julien Cappelle, Parviez Hosseini, Kevin Y. Njabo, Soad Abdel Aziz, Xiangming Xiao, Peter Daszak, and Thomas B. Smith. + journal: On the Cover + issue: "(2013): 581." + + - key: "2013 [Dugas, A]" + link: http://dx.plos.org/10.1371/journal.pone.0056176.g003 + title: "Influenza forecasting with Google flu trends." + authors: Dugas, Andrea Freyer, Mehdi Jalalpour, Yulia Gel, Scott Levin, Fred Torcaso, Takeru Igusa, and Richard E. Rothman. + journal: PloS one + issue: "8, no. 2 (2013): e56176." + + - key: "2013 [Bogich, ]" + link: http://rsif.royalsocietypublishing.org/content/10/81/20120904.short + title: "Using network theory to identify the causes of disease outbreaks of unknown origin." + authors: Bogich, Tiffany L., Sebastian Funk, Trent R. Malcolm, Nok Chhun, Jonathan H. Epstein, Aleksei A. Chmura, A. Marm Kilpatrick et al. + journal: Journal of The Royal Society Interface + issue: "10, no. 81 (2013): 20120904." + + - key: "2012 [Shaman, ]" + link: http://www.pnas.org/content/109/50/20425.short + title: "Forecasting seasonal outbreaks of influenza." + authors: Shaman, Jeffrey, and Alicia Karspeck. + journal: Proceedings of the National Academy of Sciences + issue: "109, no. 50 (2012): 20425-20430." + + - key: "2012 [Morse, S]" + link: http://www.sciencedirect.com/science/article/pii/S0140673612616845 + title: "Prediction and prevention of the next pandemic zoonosis." + authors: Morse, Stephen S., Jonna AK Mazet, Mark Woolhouse, Colin R. Parrish, Dennis Carroll, William B. Karesh, Carlos Zambrana-Torrelio, W. Ian Lipkin, and Peter Daszak. + journal: The Lancet + issue: "380, no. 9857 (2012): 1956-1965." + + - key: "2012 [Hii, Yie]" + link: http://dx.plos.org/10.1371/journal.pntd.0001908 + title: "Forecast of dengue incidence using temperature and rainfall." + authors: Hii, Yien Ling, Huaiping Zhu, Nawi Ng, Lee Ching Ng, and Joacim Rocklöv. + journal: PLoS neglected tropical diseases + issue: "6, no. 11 (2012): e1908." + + - key: "2012 [Descloux]" + link: http://dx.plos.org/10.1371/journal.pntd.0001470.g009 + title: "Climate-based models for understanding and forecasting dengue epidemics." + authors: Descloux, Elodie, Morgan Mangeas, Christophe Eugène Menkes, Matthieu Lengaigne, Anne Leroy, Temaui Tehei, Laurent Guillaumot et al. + journal: PLoS neglected tropical diseases + issue: "6, no. 2 (2012): e1470." + + - key: "2012 [Bhatnaga]" + link: http://ijph.in/article.asp?issn=0019-557X;year=2012;volume=56;issue=4;spage=281;epage=285;aulast=Bhatnagar + title: "Forecasting incidence of dengue in Rajasthan, using time series analyses." + authors: Bhatnagar, Sunil, Vivek Lal, Shiv D. Gupta, and Om P. Gupta. + journal: Indian journal of public health + issue: "56, no. 4 (2012): 281." + + - key: "2011 [Martinez]" + link: http://www.scielo.br/scielo.php?pid=S0037-86822011000400007&script=sci_arttext + title: "A SARIMA forecasting model to predict the number of cases of dengue in Campinas, State of São Paulo, Brazil." + authors: Martinez, Edson Zangiacomi, Elisângela Aparecida Soares da Silva, and Amaury Lelis Dal Fabbro. + journal: Revista da Sociedade Brasileira de Medicina Tropical + issue: "44, no. 4 (2011): 436-440." + + - key: "2011 [Lowe, Ra]" + link: http://www.sciencedirect.com/science/article/pii/S0098300410001445 + title: "Spatio-temporal modelling of climate-sensitive disease risk: Towards an early warning system for dengue in Brazil." + authors: Lowe, Rachel, Trevor C. Bailey, David B. Stephenson, Richard J. Graham, Caio AS Coelho, Marilia Sá Carvalho, and Christovam Barcellos. + journal: Computers & Geosciences + issue: "37, no. 3 (2011): 371-381." + + - key: "2011 [Lipsitch]" + link: http://online.liebertpub.com/doi/abs/10.1089/bsp.2011.0007 + title: "Improving the evidence base for decision making during a pandemic: the example of 2009 influenza A/H1N1." + authors: Lipsitch, Marc, Lyn Finelli, Richard T. Heffernan, Gabriel M. Leung, and Stephen C. Redd; for the 2009 H1N1 Surveillance Group. + journal: "Biosecurity and bioterrorism: biodefense strategy, practice, and science" + issue: "9, no. 2 (2011): 89-115." + + - key: "2011 [Goldstei]" + link: http://dx.plos.org/10.1371/journal.pmed.1001051 + title: "Predicting the epidemic sizes of influenza A/H1N1, A/H3N2, and B: a statistical method." + authors: Goldstein, Edward, Sarah Cobey, Saki Takahashi, Joel C. Miller, and Marc Lipsitch. + journal: PLoS medicine + issue: "8, no. 7 (2011): e1001051." + + - key: "2010 [Shaman, ]" + link: http://dx.plos.org/10.1371/journal.pbio.1000316.g004 + title: "Absolute humidity and the seasonal onset of influenza in the continental United States." + authors: Shaman, Jeffrey, Virginia E. Pitzer, Cécile Viboud, Bryan T. Grenfell, and Marc Lipsitch. + journal: PLoS biology + issue: "8, no. 2 (2010): e1000316." + + - key: "2010 [Ong, Jim]" + link: http://dx.plos.org/10.1371/journal.pone.0010036.g005 + title: "Real-time epidemic monitoring and forecasting of H1N1-2009 using influenza-like illness from general practice and family doctor clinics in Singapore." + authors: Ong, Jimmy Boon Som, I. Mark, Cheng Chen, Alex R. Cook, Huey Chyi Lee, Vernon J. Lee, Raymond Tzer Pin Lin, Paul Ananth Tambyah, and Lee Gan Goh. + journal: PloS one + issue: "5, no. 4 (2010): e10036." + + - key: "2010 [Miller, ]" + link: http://www.sciencedirect.com/science/article/pii/S0140673609621267 + title: "Incidence of 2009 pandemic influenza A H1N1 infection in England: a cross-sectional serological study." + authors: Miller, Elizabeth, Katja Hoschler, Pia Hardelid, Elaine Stanford, Nick Andrews, and Maria Zambon. + journal: The Lancet + issue: "375, no. 9720 (2010): 1100-1108." + + - key: "2010 [Baguelin]" + link: http://www.sciencedirect.com/science/article/pii/S0264410X10000320 + title: "Vaccination against pandemic influenza A/H1N1v in England: a real-time economic evaluation." + authors: Baguelin, Marc, Albert Jan Van Hoek, Mark Jit, Stefan Flasche, Peter J. White, and W. John Edmunds. + journal: Vaccine + issue: "28, no. 12 (2010): 2370-2384." + + - key: "2009 [Shaman, ]" + link: http://www.pnas.org/content/106/9/3243.short + title: "Absolute humidity modulates influenza survival, transmission, and seasonality." + authors: Shaman, Jeffrey, and Melvin Kohn. + journal: Proceedings of the National Academy of Sciences + issue: "106, no. 9 (2009): 3243-3248." + + - key: "2009 [Ginsberg]" + link: http://www.nature.com/nature/journal/v457/n7232/abs/nature07634.html + title: "Detecting influenza epidemics using search engine query data." + authors: Ginsberg, Jeremy, Matthew H. Mohebbi, Rajan S. Patel, Lynnette Brammer, Mark S. Smolinski, and Larry Brilliant. + journal: Nature + issue: "457, no. 7232 (2009): 1012-1014." + + - key: "2009 [Flahault]" + link: http://www.biomedcentral.com/1471-2334/9/129/ + title: "Potential for a global dynamic of Influenza A (H1N1)." + authors: Flahault, Antoine, Elisabeta Vergu, and Pierre-Yves Boëlle. + journal: BMC infectious diseases + issue: "9, no. 1 (2009): 129." + + - key: "2008 [Silawan,]" + link: http://europepmc.org/abstract/MED/18567447 + title: "Temporal patterns and forecast of dengue infection in Northeastern Thailand." + authors: Silawan, Tassanee, Pratap Singhasivanon, Jaranit Kaewkungwal, Suchitra Nimmanitya, and Wanapa Suwonkerd. + year: 2008 + + - key: "2008 [Jones, K]" + link: http://www.nature.com/nature/journal/v451/n7181/abs/nature06536.html + title: "Global trends in emerging infectious diseases." + authors: Jones, Kate E., Nikkita G. Patel, Marc A. Levy, Adam Storeygard, Deborah Balk, John L. Gittleman, and Peter Daszak. + journal: Nature + issue: "451, no. 7181 (2008): 990-993." + + - key: "2008 [Boëlle, ]" + link: http://online.liebertpub.com/doi/abs/10.1089/vbz.2006.0620 + title: "Investigating transmission in a two-wave epidemic of Chikungunya fever, Reunion Island." + authors: Boëlle, P-Y., Guy Thomas, Elisa Vergu, Philippe Renault, A-J. Valleron, and Antoine Flahault. + journal: Vector-Borne and Zoonotic Diseases + issue: "8, no. 2 (2008): 207-218." + + - key: "2007 [Polgreen]" + link: http://cid.oxfordjournals.org/content/44/2/272.short + title: "Use of prediction markets to forecast infectious disease activity." + authors: Polgreen, Philip M., Forrest D. Nelson, George R. Neumann, and Robert A. Weinstein. + journal: Clinical Infectious Diseases + issue: "44, no. 2 (2007): 272-279." + + - key: "2007 [Pelat, C]" + link: http://www.biomedcentral.com/1472-6947/7/29?utm_source=twitterfeed&utm_medium=twitter + title: "Online detection and quantification of epidemics." + authors: Pelat, Camille, Pierre-Yves Boëlle, Benjamin J. Cowling, Fabrice Carrat, Antoine Flahault, Séverine Ansart, and Alain-Jacques Valleron. + journal: BMC medical informatics and decision making + issue: "7, no. 1 (2007): 29." + + - key: "2007 [Hall, I.]" + link: http://journals.cambridge.org/abstract_S0950268806007084 + title: "Real-time epidemic forecasting for pandemic influenza." + authors: Hall, I. M., R. Gani, H. E. Hughes, and S. Leach. + journal: Epidemiology and Infection + issue: "135, no. 03 (2007): 372-385." + + - key: "2006 [Viboud, ]" + link: http://www.sciencemag.org/content/312/5772/447.short + title: "Synchrony, waves, and spatial hierarchies in the spread of influenza." + authors: Viboud, Cécile, Ottar N. Bjørnstad, David L. Smith, Lone Simonsen, Mark A. Miller, and Bryan T. Grenfell. + journal: science + issue: "312, no. 5772 (2006): 447-451." + + - key: "2006 [Vergu, E]" + link: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3291431/ + title: "Medication sales and syndromic surveillance, France." + authors: Vergu, Elisabeta, Rebecca F. Grais, Hélène Sarter, Jean-Paul Fagot, Bruno Lambert, Alain-Jacques Valleron, and Antoine Flahault. + journal: Emerging infectious diseases + issue: "12, no. 3 (2006): 416." + + - key: "2006 [Smith, D]" + link: http://www.sciencemag.org/content/312/5772/392.short + title: "Predictability and preparedness in influenza control." + authors: Smith, Derek J. + journal: science + issue: "312, no. 5772 (2006): 392-394." + + - key: "2006 [Le Menac]" + link: http://rspb.royalsocietypublishing.org/content/273/1600/2467.short + title: "Key strategies for reducing spread of avian influenza among commercial poultry holdings: lessons for transmission to humans." + authors: Le Menach, Arnaud, Elisabeta Vergu, Rebecca F. Grais, David L. Smith, and Antoine Flahault. + journal: "Proceedings of the Royal Society B: Biological Sciences" + issue: "273, no. 1600 (2006): 2467-2475." + + - key: "2006 [Flahault]" + link: http://smm.sagepub.com/content/15/5/413.short + title: "Virtual surveillance of communicable diseases: a 20-year experience in France." + authors: Flahault, A., T. Blanchon, Y. Dorleans, L. Toubiana, J. F. Vibert, and A. J. Valleron. + journal: Statistical methods in medical research + issue: "15, no. 5 (2006): 413-421." + + - key: "2004 [Legrand,]" + link: http://journals.cambridge.org/abstract_S0950268803001390 + title: "Modelling responses to a smallpox epidemic taking into account uncertainty." + authors: Legrand, J., C. Viboud, P. Y. Boelle, A. J. Valleron, and A. Flahault. + journal: Epidemiology and infection + issue: "132, no. 01 (2004): 19-25." + + - key: "2003 [Viboud, ]" + link: http://aje.oxfordjournals.org/content/158/10/996.short + title: "Prediction of the spread of influenza epidemics by the method of analogues." + authors: Viboud, Cécile, Pierre-Yves Boëlle, Fabrice Carrat, Alain-Jacques Valleron, and Antoine Flahault. + journal: American Journal of Epidemiology + issue: "158, no. 10 (2003): 996-1006." + + - key: "2002 [Barbazan]" + link: http://www.sciencedirect.com/science/article/pii/S1286457902015897 + title: "Dengue hemorrhagic fever epidemiology in Thailand: description and forecasting of epidemics." + authors: Barbazan, Philippe, Sutee Yoksan, and Jean-Paul Gonzalez. + journal: Microbes and infection + issue: "4, no. 7 (2002): 699-705." + + - key: "2000 [Wernley,]" + link: http://books.google.com/books?id=HG5NAQAAIAAJ + title: "Storms, Chapter 6: Storms Forecasting for Emergency Response." + authors: Wernley, Donald, and Louis W. Uccellini. + issue: 'Chapter 6 in "Storms"; 1999, pp. 70-97' + journal: "Publisher: Routledge, 2000, ISBN: 0415212863, 9780415212861." + + - key: "2000 [Myers, M]" + link: http://www.sciencedirect.com/science/article/pii/S0065308X00470132 + title: "Forecasting disease risk for increased epidemic preparedness in public health." + authors: Myers, M. F., D. J. Rogers, J. Cox, A. Flahault, and S. I. Hay. + journal: Advances in Parasitology + issue: "47 (2000): 309-330." + + - key: "1998 [Krzyszto]" + link: http://journals.ametsoc.org/doi/abs/10.1175/1520-0477(1998)079%3C0243:PHFTAN%3E2.0.CO%3B2 + title: "Probabilistic hydrometeorological forecasts: Toward a new era in operational forecasting." + authors: Krzysztofowicz, Roman. + journal: Bulletin of the American Meteorological Society + issue: "79, no. 2 (1998): 243-251." + + - key: "1993 [Krzyszto]" + link: http://journals.ametsoc.org/doi/abs/10.1175/1520-0434(1993)008%3C0424:PQPFFR%3E2.0.CO%3B2 + title: "Probabilistic quantitative precipitation forecasts for river basins." + authors: Krzysztofowicz, Roman, William J. Drzal, Theresa Rossi Drake, James C. Weyman, and Louis A. Giordano. + journal: Weather and forecasting + issue: "8, no. 4 (1993): 424-439." --- We found the following publications to be particularly relevant to epi-forcasting. This list is work-in-progress and not meant to ever be exhaustive. We share it here in the hope that anyone looking for recent epi-forecasting literature will have a place to start. If there is a particular publication that you think ought to be included, please [let us know](mailto:dfarrow@andrew.cmu.edu). -{{}} \ No newline at end of file +{{}} diff --git a/content/blog/2015-07-23-template-post.Rmd b/content/blog/2015-07-23-template-post.Rmd index 6bc9172dc..ba4887db3 100644 --- a/content/blog/2015-07-23-template-post.Rmd +++ b/content/blog/2015-07-23-template-post.Rmd @@ -1,16 +1,22 @@ --- -title: "Template Post" -author: "Frida Gomam" +title: Template Post +author: Frida Gomam date: 2015-07-23 -tags: ["R Markdown", "plot", "regression"] -draft: true -authors: -- frida +tags: + - R Markdown + - plot + - regression +draft: true # remove this line in new blog posts +authors: # list of author keys, see /data/authors.yaml + - frida heroImage: /blog/images/blog-lg-img_hello-world.png heroImageThumb: /blog/images/blog-thumb-img_hello-world.png +summary: | + Blog summary, the first 150 characters are used for the blog list +acknowledgements: | + List acknowledgements here related: -- 2015-07-23-template-post -acknowledgements: Test + - 2015-07-23-template-post output: blogdown::html_page: toc: true @@ -21,10 +27,7 @@ knitr::opts_chunk$set(collapse = TRUE) ``` Each blog post is an R Markdown document. For more details on using R Markdown -see . The first paragraph or so will appear on the -front page; by default the first 70 words are used. If you want to specify the -exact text, you can specify a `summary` front matter variable. Usually we do -not include links in the teaser. +see . You can embed an R code chunk like this: @@ -53,6 +56,20 @@ of the code chunks would be great so that readers see how easy it is to use our data. But for other audiences, it's probably best to use the `echo=FALSE` chunk option so the code is not included in the post. +### Wide Figure + +To create a wide figure, add the `out.extra='class="wide-figure"'` markup: + +```{r wide-pie, fig.cap='A fancy pie chart.', tidy=FALSE, out.extra='class="wide-figure"'} +par(mar = c(0, 1, 0, 1)) +pie( + c(280, 60, 20), + c('Sky', 'Sunny side of pyramid', 'Shady side of pyramid'), + col = c('#0292D8', '#F7EA39', '#C4B632'), + init.angle = -50, border = NA +) +``` + ## Including Math You can embed mathematics by using dollar signs for inline math and double @@ -64,14 +81,12 @@ $$ ## Metadata -Each post has a title, author, date, and tags. The `draft` attribute marks a -post that should not be included in the rendered and published site, such as -this one. Choose bold, active titles, like "Delphi releases new survey data", +Each post has a title, author, date, and tags. +Choose bold, active titles, like "Delphi releases new survey data", rather than boring titles like "New survey aggregates". -The author metadata should credit the post author or authors; as shown at the -end of this example post, you should also include a block about the authors and -linking to their home pages. But in the post text, you should also generously +The author metadata should credit the post author or authors; But in the post acknowledgements, +you should also generously name anyone who helped with parts of your post, e.g., the team members who obtained data or set up a server or developed a package you use. @@ -80,13 +95,27 @@ obtained data or set up a server or developed a package you use. Each post can be tagged, as you can see in the metadata block at the top. I suggest we consider the following tags as base tags: -* forecasting -* nowcasting -* symptom surveys -* medical records -* COVIDcast API -* COVIDcast map -* data sources (for everthing else than symptom surveys and medical records) -* news (for announcements of new features, new models, etc.) -* R (for posts containing R, typically, our covidcast R package) -* Python (for posts containing Python, typically, our covicast Python package) \ No newline at end of file +- forecasting +- nowcasting +- symptom surveys +- medical records +- COVIDcast API +- COVIDcast map +- data sources (for everthing else than symptom surveys and medical records) +- news (for announcements of new features, new models, etc.) +- R (for posts containing R, typically, our covidcast R package) +- Python (for posts containing Python, typically, our covicast Python package) + +## Linking + +### Linking to other pages and blog posts: + +using the file name and the Hugo shortcodes, e.g.: [Facebook Post](`r blogdown::shortcode_html("relref", "2020-08-26-fb-survey")`). +Jumping to a specific section/anchor is supported too: +[previous exploratory investigations](`r blogdown::shortcode_html("relref", "2020-08-26-fb-survey#some-interesting-examples")`) + +### Linking to the API doc: + +there is another shortcode for creating an api link, e.g. +[public API](`r blogdown::shortcode_html("apiref", "/")`) or +[Doctor's Visits signal](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/doctor-visits.html")`) diff --git a/content/blog/2015-07-23-template-post.html b/content/blog/2015-07-23-template-post.html index d4507b21d..03936f4cc 100644 --- a/content/blog/2015-07-23-template-post.html +++ b/content/blog/2015-07-23-template-post.html @@ -1,16 +1,22 @@ --- -title: "Template Post" -author: "Frida Gomam" +title: Template Post +author: Frida Gomam date: 2015-07-23 -tags: ["R Markdown", "plot", "regression"] -draft: true -authors: -- frida +tags: + - R Markdown + - plot + - regression +draft: true # remove this line in new blog posts +authors: # list of author keys, see /data/authors.yaml + - frida heroImage: /blog/images/blog-lg-img_hello-world.png heroImageThumb: /blog/images/blog-thumb-img_hello-world.png +summary: | + Blog summary, the first 150 characters are used for the blog list +acknowledgements: | + List acknowledgements here related: -- 2015-07-23-template-post -acknowledgements: Test + - 2015-07-23-template-post output: blogdown::html_page: toc: true @@ -22,20 +28,25 @@

Each blog post is an R Markdown document. For more details on using R Markdown -see http://rmarkdown.rstudio.com. The first paragraph or so will appear on the -front page; by default the first 70 words are used. If you want to specify the -exact text, you can specify a summary front matter variable. Usually we do -not include links in the teaser.

+see http://rmarkdown.rstudio.com.

You can embed an R code chunk like this:

summary(cars)
 ##      speed           dist       
@@ -74,6 +85,23 @@ 

Including Plots

of the code chunks would be great so that readers see how easy it is to use our data. But for other audiences, it’s probably best to use the echo=FALSE chunk option so the code is not included in the post.

+
+

Wide Figure

+

To create a wide figure, add the out.extra='class="wide-figure"' markup:

+
par(mar = c(0, 1, 0, 1))
+pie(
+  c(280, 60, 20),
+  c('Sky', 'Sunny side of pyramid', 'Shady side of pyramid'),
+  col = c('#0292D8', '#F7EA39', '#C4B632'),
+  init.angle = -50, border = NA
+)
+
+A fancy pie chart. +

+Figure 2: A fancy pie chart. +

+
+

Including Math

@@ -85,13 +113,11 @@

Including Math

Metadata

-

Each post has a title, author, date, and tags. The draft attribute marks a -post that should not be included in the rendered and published site, such as -this one. Choose bold, active titles, like “Delphi releases new survey data”, +

Each post has a title, author, date, and tags. +Choose bold, active titles, like “Delphi releases new survey data”, rather than boring titles like “New survey aggregates”.

-

The author metadata should credit the post author or authors; as shown at the -end of this example post, you should also include a block about the authors and -linking to their home pages. But in the post text, you should also generously +

The author metadata should credit the post author or authors; But in the post acknowledgements, +you should also generously name anyone who helped with parts of your post, e.g., the team members who obtained data or set up a server or developed a package you use.

@@ -112,3 +138,18 @@

Tags

+
+

Linking

+
+

Linking to other pages and blog posts:

+

using the file name and the Hugo shortcodes, e.g.: }}">Facebook Post. +Jumping to a specific section/anchor is supported too: +}}">previous exploratory investigations

+
+
+

Linking to the API doc:

+

there is another shortcode for creating an api link, e.g.  +}}">public API or +}}">Doctor’s Visits signal

+
+
diff --git a/content/blog/2020-08-10-hello-world.Rmd b/content/blog/2020-08-10-hello-world.Rmd index 75993117e..31d12e6b7 100644 --- a/content/blog/2020-08-10-hello-world.Rmd +++ b/content/blog/2020-08-10-hello-world.Rmd @@ -1,11 +1,12 @@ --- -title: "Hello World!" -author: "Roni Rosenfeld and Ryan Tibshirani" +title: Hello World! +author: Roni Rosenfeld and Ryan Tibshirani date: 2020-08-10 -tags: ["COVIDcast"] +tags: + - COVIDcast authors: -- roni -- ryan + - roni + - ryan heroImage: /blog/images/blog-lg-img_hello-world.png heroImageThumb: /blog/images/blog-thumb-img_hello-world.png summary: | @@ -27,12 +28,12 @@ output: Hello from the Delphi research group at Carnegie Mellon University! We're a group of faculty, students, and staff, based primarily out of CMU together with strong collaborators from other universities and industry. -Our group was founded in 2012 to advance the theory and practice of epidemic -forecasting. Since March 2020, we have refocused efforts towards helping combat +Our group was founded in 2012 to advance the theory and practice of epidemic +forecasting. Since March 2020, we have refocused efforts towards helping combat the COVID-19 pandemic, by supporting informed decision-making at federal, state, and local levels of government and in the healthcare sector. Until now, we've -been pretty "heads down" with our work, and slow to communicate what we've been -up to. But at last ... Delphi finally has a blog! This first post serves as an +been pretty "heads down" with our work, and slow to communicate what we've been +up to. But at last ... Delphi finally has a blog! This first post serves as an introduction of sorts. Future posts will dive deeper into our various projects. ## A Little Bit About Us @@ -89,40 +90,40 @@ epidemic forecasting, since March 2020 our goals are to help combat the COVID-19 pandemic and save lives and livelihoods. We aim to support informed decision-making at federal, state, and local levels of government and in the healthcare sector. -Whenever possible, we strive to make our work useful -to the private and public sectors, other researchers, +Whenever possible, we strive to make our work useful +to the private and public sectors, other researchers, the press, and the general public. Our strategy: 1. Improve pandemic situational awareness and understanding -by providing comprehensive, geographically-detailed, -and continuously-updated indicators of pandemic activity and its impact, -helping to make meaning out of the pandemic information deluge. - -2. Support local, state, and federal governments' -ongoing decision-making in their attempts to balance -public health concerns with economic preservation, -by providing validated, verifiable, localized, -short-term forecasts of epidemic spread and healthcare demand, -under any assumed level of the local population's mobility and distancing -behavior. - -3. Analyze and demonstrate the impacts of governments' -past tightening or loosening of mitigation measures -(e.g., opening or closing schools or businesses, -imposing or lifting bans on gatherings, shelter in place orders, etc.) -on a population's mobility and distancing behavior. - -4. Engage continuously with our target users to communicate -our findings, and inform our directions and priorities. + by providing comprehensive, geographically-detailed, + and continuously-updated indicators of pandemic activity and its impact, + helping to make meaning out of the pandemic information deluge. + +2. Support local, state, and federal governments' + ongoing decision-making in their attempts to balance + public health concerns with economic preservation, + by providing validated, verifiable, localized, + short-term forecasts of epidemic spread and healthcare demand, + under any assumed level of the local population's mobility and distancing + behavior. + +3. Analyze and demonstrate the impacts of governments' + past tightening or loosening of mitigation measures + (e.g., opening or closing schools or businesses, + imposing or lifting bans on gatherings, shelter in place orders, etc.) + on a population's mobility and distancing behavior. + +4. Engage continuously with our target users to communicate + our findings, and inform our directions and priorities. 5. Make our products useful and accessible to other -researchers and tool developers, to amplify their impact. -To that end, we'll continue to make everything we invent or produce -publicly and freely available as soon as possible -and to the greatest degree allowed, including models, -algorithms, software, tools, estimates, and forecasts. + researchers and tool developers, to amplify their impact. + To that end, we'll continue to make everything we invent or produce + publicly and freely available as soon as possible + and to the greatest degree allowed, including models, + algorithms, software, tools, estimates, and forecasts. ## What We've Been Up To @@ -132,29 +133,29 @@ and have made good progress on some of them. Here's a quick summary: -- We've built a number of new indicators of COVID-19 activity. - These are fine-grained geographically - (most of them are available at the US county level) +- We've built a number of new indicators of COVID-19 activity. + These are fine-grained geographically + (most of them are available at the US county level) and temporally (all of them updated daily). - They are designed to shed light on the current picture of COVID in the US, + They are designed to shed light on the current picture of COVID in the US, beyond the typical publicly-available metrics like confirmed cases and deaths. -- Some of our indicators are based on massive-scale surveys that we’re running - through partnerships with Facebook and Google, and others are based on +- Some of our indicators are based on massive-scale surveys that we’re running + through partnerships with Facebook and Google, and others are based on aggregated counts from massive medical claims data sets through partners like Change Healthcare. -- We've built a [public - API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`), - and [R and Python - packages](`r blogdown::shortcode_html("apiref", "api/covidcast_clients.html")`), - to serve our indicators to researchers and the public. This API provides new +- We've built a [public + API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`), + and [R and Python + packages](`r blogdown::shortcode_html("apiref", "api/covidcast_clients.html")`), + to serve our indicators to researchers and the public. This API provides new data daily. -- We've built [interactive maps and graphics](`r blogdown::shortcode("ref", "covidcast")`) to +- We've built [interactive maps and graphics](`r blogdown::shortcode("ref", "covidcast")`) to display our indicators, and better inform the public and decision-makers. -- We've developed forecasts of the future spread of the pandemic, +- We've developed forecasts of the future spread of the pandemic, validated them prospectively, and started submitting them to CDC. In subsequent posts, we'll dive deeper into many of these projects, and touch on diff --git a/content/blog/2020-08-10-hello-world.html b/content/blog/2020-08-10-hello-world.html index 1f37a8225..bca6020a8 100644 --- a/content/blog/2020-08-10-hello-world.html +++ b/content/blog/2020-08-10-hello-world.html @@ -1,11 +1,12 @@ --- -title: "Hello World!" -author: "Roni Rosenfeld and Ryan Tibshirani" +title: Hello World! +author: Roni Rosenfeld and Ryan Tibshirani date: 2020-08-10 -tags: ["COVIDcast"] +tags: + - COVIDcast authors: -- roni -- ryan + - roni + - ryan heroImage: /blog/images/blog-lg-img_hello-world.png heroImageThumb: /blog/images/blog-thumb-img_hello-world.png summary: | diff --git a/content/blog/2020-08-26-fb-survey.Rmd b/content/blog/2020-08-26-fb-survey.Rmd index 99fdad276..01082460b 100644 --- a/content/blog/2020-08-26-fb-survey.Rmd +++ b/content/blog/2020-08-26-fb-survey.Rmd @@ -1,11 +1,14 @@ --- -title: "COVID-19 Symptom Surveys through Facebook" -author: "Alex Reinhart and Ryan Tibshirani" +title: COVID-19 Symptom Surveys through Facebook +author: Alex Reinhart and Ryan Tibshirani date: 2020-08-26 -tags: ["symptom surveys", "COVIDcast", "R"] +tags: + - symptom surveys + - COVIDcast + - R authors: -- alex -- ryan + - alex + - ryan heroImage: /blog/images/blog-lg-img_facebook-survey-post.png heroImageThumb: /blog/images/blog-thumb-img_facebook-survey-post.png summary: | @@ -50,11 +53,11 @@ we've been conducting a massive daily survey to monitor the spread and impact of the COVID-19 pandemic in the United States. Our survey is advertised through Facebook, but it's run on our own Qualtrics platform (Facebook never sees any of the survey responses). -This is an ongoing operation and our survey is taken by about 74,000 people +This is an ongoing operation and our survey is taken by about 74,000 people each day. Respondents provide information about COVID-related symptoms, contacts, risk factors, and demographics, allowing us to examine county-level trends across the US. -We believe that this combination of *detail* and *scale* +We believe that this combination of _detail_ and _scale_ has never before been available in a public health emergency. We make aggregated data publicly available daily through our @@ -74,7 +77,7 @@ some of the exciting new directions that we're pursuing now. ## Short Background -Back in March 2020, we began discussions with Facebook about running a +Back in March 2020, we began discussions with Facebook about running a survey, advertised through their site, to collect real-time, county-level information on people experiencing COVID-like symptoms. The basic premise was that we could use this information @@ -93,7 +96,7 @@ with buy-in from a platform like Facebook. Fortunately for us, they agreed! We launched our survey on April 6, 2020. -Every day since, Facebook directs a random sample of its users +Every day since, Facebook directs a random sample of its users to our survey, hosted on [Qualtrics](https://www.qualtrics.com/). As part of our agreement with Facebook, we receive the data directly from Qualtrics, @@ -104,15 +107,15 @@ with fully de-identified individual survey responses available only to researchers who agree to our [data use terms](https://dataforgood.fb.com/docs/covid-19-symptom-survey-request-for-data-access/). -As of this writing, our survey is taken by an average of 74,000 people per +As of this writing, our survey is taken by an average of 74,000 people per day, delivering enough data for us to create meaningful estimates for an average of nearly 1,000 counties per week. -Over the course of the survey so far, we have already collected over 10 million +Over the course of the survey so far, we have already collected over 10 million responses! An [international version of the survey](https://covidmap.umd.edu/), -available in over 50 languages, was launched soon after by a team at the +available in over 50 languages, was launched soon after by a team at the University of Maryland. -Before going into detail later about our survey and our survey-based +Before going into detail later about our survey and our survey-based indicators, here are a couple maps to ground your intuition. On the left is a state-level heatmap of the estimated percentage of people with COVID symptoms, @@ -128,7 +131,7 @@ which already provides a nice sanity check. knitr::opts_chunk$set(cache = TRUE, autodep = TRUE, cache.comments = TRUE) ``` -```{r, message = FALSE, warning = FALSE, fig.width = 10, fig.height = 4} +```{r, message = FALSE, warning = FALSE, fig.width = 10, fig.height = 4, out.extra = 'class="wide-figure"'} library(covidcast) library(dplyr) library(gridExtra) @@ -168,60 +171,60 @@ grid.arrange(p1, p2, nrow = 1) We generated these plots using our [covidcast R package](https://cmu-delphi.github.io/covidcast/covidcastR/). In all, fetching the data from our API and producing the heatmaps -requires only 15 lines of code. -If you're interested, click the "Code" button to reveal the source. +requires only 15 lines of code. +If you're interested, click the "Code" button to reveal the source. We'll cover our [R and Python covidcast packages](`r blogdown::shortcode_html("apiref", "api/covidcast_clients.html")`) in a future blog post. ## Why Run These Surveys? -Now let's unpack the main motivation behind our survey a bit: -a person typically experiences COVID-like symptoms -before they seek medical care or a COVID-19 test, +Now let's unpack the main motivation behind our survey a bit: +a person typically experiences COVID-like symptoms +before they seek medical care or a COVID-19 test, so data on how many people are self-reporting COVID-like symptoms in a -given county could potentially give us an **early indicator** -of COVID activity in that county. And to be clear, it's not just -*that* we're looking at symptoms that's important here, -it's the *way* we're measuring them: -since symptoms can be reported from home, -with no special equipment needed, -this data isn't subject to the same reporting delays +given county could potentially give us an **early indicator** +of COVID activity in that county. And to be clear, it's not just +_that_ we're looking at symptoms that's important here, +it's the _way_ we're measuring them: +since symptoms can be reported from home, +with no special equipment needed, +this data isn't subject to the same reporting delays as formal testing metrics like confirmed COVID-19 case counts. (Note that confirmed COVID-19 case counts aren't just delayed, they are confounded by issues like testing policy and capacity, -while self-reported symptom data shouldn't be subject to the same problems. -This is potentially a very important point, but much more subtle, and we +while self-reported symptom data shouldn't be subject to the same problems. +This is potentially a very important point, but much more subtle, and we won't delve into it in this post.) -It's also worth being clear about what we're *not* able to say with these +It's also worth being clear about what we're _not_ able to say with these surveys: - Symptoms alone are not sufficient to diagnose coronavirus infections: of -course, COVID-like symptoms can be caused by other conditions, and many true -infections are asymptomatic. Therefore, even if we ignore the issues brought on -by self-reporting and survey sampling, we can't expect the estimates we produce -to reflect the true rate of COVID-19 (and they're not intended to). + course, COVID-like symptoms can be caused by other conditions, and many true + infections are asymptomatic. Therefore, even if we ignore the issues brought on + by self-reporting and survey sampling, we can't expect the estimates we produce + to reflect the true rate of COVID-19 (and they're not intended to). - Our survey responses come from the population of Facebook users in the US, -which may be a sizeable fraction of the US population, but certainly not all of -it. We'll also likely see bias because some people on Facebook are more inclined -to take surveys than others. We attempt to correct for both of these biases -using a [statistical reweighting -scheme](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/fb-survey.html#survey-weighting")`), -but these corrections aren't perfect. + which may be a sizeable fraction of the US population, but certainly not all of + it. We'll also likely see bias because some people on Facebook are more inclined + to take surveys than others. We attempt to correct for both of these biases + using a [statistical reweighting + scheme](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/fb-survey.html#survey-weighting")`), + but these corrections aren't perfect. - Our symptom data is entirely self-reported, in contrast to data -reported by medical professionals. Some fraction of the responses could be -erroneous, either because a person misunderstood the question or chose to answer -incorrectly. + reported by medical professionals. Some fraction of the responses could be + erroneous, either because a person misunderstood the question or chose to answer + incorrectly. To summarize, our survey can't be used to make absolute statements about the true prevalence of coronavirus disease in the US; in fact, it shouldn't even be regarded as a foolproof way of deriving unbiased estimates of the number of -people with COVID-19 *symptoms* in the US (mainly due to the self-reporting -aspect). Nevertheless, as we'll see below, *changes in self-reported symptoms -over time* can still be a meaningful reflection of the changes in coronavirus +people with COVID-19 _symptoms_ in the US (mainly due to the self-reporting +aspect). Nevertheless, as we'll see below, _changes in self-reported symptoms +over time_ can still be a meaningful reflection of the changes in coronavirus infections over time. And in the best case, it can help predict changes to come some days into the future. @@ -229,9 +232,9 @@ some days into the future. Our survey has 4 sections and is about 35 questions long. The first section is short and gathers information on a core set of symptoms used to define a -condition called **COVID-like illness** or **CLI**, which we define as *fever of +condition called **COVID-like illness** or **CLI**, which we define as _fever of at least 100 °F, along with cough, shortness of breath, or difficulty -breathing*. This mirrors the standard definition of influenza-like illness or +breathing_. This mirrors the standard definition of influenza-like illness or ILI (defined as fever of at least 100 °F, along with sore throat or cough), and is in line with the working definition of CLI used by the US Centers for Disease Control and Prevention (CDC). @@ -241,8 +244,8 @@ quantities, in a given location, on a given day: - % CLI: the percentage of people with COVID-like illness; and -- % CLI-in-community: the percentage of people who *know someone in their local -community* with COVID-like illness. +- % CLI-in-community: the percentage of people who _know someone in their local + community_ with COVID-like illness. Details on how we compute the % CLI and % CLI-in-community estimates can be found in our [COVIDcast signals @@ -280,16 +283,16 @@ provided they agree to keep data from individual respondents confidential. ## Some Interesting Examples Now we'll turn to some interesting data examples that provide evidence -that our survey-based CLI signals can be early indicators of COVID activity. -We'll consider the % CLI-in-community indicator, which tends to be more stable +that our survey-based CLI signals can be early indicators of COVID activity. +We'll consider the % CLI-in-community indicator, which tends to be more stable than the % CLI indicator (which shows similar, but noisier, trends). -Let's start by looking at Miami-Dade County, -which experienced a surge of new COVID-19 cases +Let's start by looking at Miami-Dade County, +which experienced a surge of new COVID-19 cases between June and July: below we plot daily new confirmed COVID-19 cases over time (using a 7-day trailing average for smoothing) as a blue curve. -We also plot the % CLI-in-community indicator as a red curve. +We also plot the % CLI-in-community indicator as a red curve. Note that these two curves, case counts and % CLI-in-community, -are not measured in the same units, hence our use of two y-axes: +are not measured in the same units, hence our use of two y-axes: one on the left for case counts, and one on the right for % CLI-in-community. ```{r, message = FALSE, warning = FALSE, fig.width = 6, fig.height = 5} @@ -319,11 +322,11 @@ plot_one = function(geo_value, title = NULL, xlab = NULL, given_geo_value = geo_value df_fb_one = df_fb %>% filter(geo_value == given_geo_value) df_in_one = df_in %>% filter(geo_value == given_geo_value) - + # Compute ranges of the two signals range1 = df_in_one %>% select("value") %>% range range2 = df_fb_one %>% select("value") %>% range - + # Convenience functions for our two signal ranges trans12 = function(x) trans(x, range1, range2) trans21 = function(x) trans(x, range2, range1) @@ -339,7 +342,7 @@ plot_one = function(geo_value, title = NULL, xlab = NULL, df_in_one), c("time_value", "value")) df$signal = c(rep("% CLI-in-community", nrow(df_fb_one)), rep("New COVID-19 cases", nrow(df_in_one))) - + # Finally, plot both signals pos = ifelse(legend, "bottom", "none") return(ggplot(df, aes(x = time_value, y = value)) + @@ -366,13 +369,13 @@ This example, as with all code examples in this blog post, was produced using our [covidcast R package](https://cmu-delphi.github.io/covidcast/covidcastR/). A first glance reveals that the % CLI-in-community indicator -clearly rises alongside confirmed COVID-19 cases, -a reassuring sanity check: more people indeed report -that others are sick in their community at times +clearly rises alongside confirmed COVID-19 cases, +a reassuring sanity check: more people indeed report +that others are sick in their community at times when COVID-19 tests confirm more cases. But a closer look shows something quite interesting: -the % CLI-in-community signal begins to rise steeply on June 19 -(first dashed vertical line), which happens *6 days before* COVID-19 cases +the % CLI-in-community signal begins to rise steeply on June 19 +(first dashed vertical line), which happens _6 days before_ COVID-19 cases begin their steep ascent on June 25 (second dashed vertical line). This is just one county; to investigate further, we pulled the 20 counties with @@ -382,7 +385,7 @@ indicator in red. We can see that the % CLI-in-community indicator is (a) never lagging and (b) leading in many counties; for example, Dallas County, Orange County, Hidalgo County, and Nueces County are a few notable examples. -```{r, message = FALSE, fig.width = 10, fig.height = 10} +```{r, message = FALSE, fig.width = 10, fig.height = 10, out.extra = 'class="wide-figure"'} num = 20 geo_values = df_in %>% group_by(geo_value) %>% summarize(diff = last(value) - first(value)) %>% @@ -395,37 +398,37 @@ for (i in 1:num) { do.call(grid.arrange, c(p_list, nrow = 5, ncol = 4)) ``` -The examples above are an informal way of looking -at the *recall* of the % CLI-in-community signal. -Of course, this is only one half of the story: +The examples above are an informal way of looking +at the _recall_ of the % CLI-in-community signal. +Of course, this is only one half of the story: for the signal to be a useful early indicator, -we'd also need to know something about its *precision*: -we'd need to know that % CLI-in-community seldom rises -in periods where new COVID-19 cases remain flat. +we'd also need to know something about its _precision_: +we'd need to know that % CLI-in-community seldom rises +in periods where new COVID-19 cases remain flat. We save a formal precision-recall analysis for future work. ## Basic Correlation Analysis To complement the more exploratory, qualitative analysis of the last section, -we'll conduct a simple quantitative analysis here, -by computing some basic measures of correlation -between our survey-based indicators and confirmed COVID-19 case rates. +we'll conduct a simple quantitative analysis here, +by computing some basic measures of correlation +between our survey-based indicators and confirmed COVID-19 case rates. There are a couple of ways to slice the data---by day and by county---and we'll consider both ways in what follows. ### Correlations Sliced by Time -First we compute, for each day between April 15 and August 15, -the Spearman correlation between the % CLI indicator and COVID-19 case rates, -across the counties that had at least 500 cumulative confirmed COVID-19 cases. -(Spearman correlation assesses whether one variable is high when another is -high, even if their relationship is not linear.) -We do the same for the % CLI-in-community indicator, +First we compute, for each day between April 15 and August 15, +the Spearman correlation between the % CLI indicator and COVID-19 case rates, +across the counties that had at least 500 cumulative confirmed COVID-19 cases. +(Spearman correlation assesses whether one variable is high when another is +high, even if their relationship is not linear.) +We do the same for the % CLI-in-community indicator, and plot the results below, with the % CLI indicator correlations in -red, and the % CLI-in-community correlations in blue. -We can see clearly that the % CLI-in-community indicator produces, -consistently across all time, *much* higher correlations. -Even in an absolute sense, the correlations from the % CLI-in-community are +red, and the % CLI-in-community correlations in blue. +We can see clearly that the % CLI-in-community indicator produces, +consistently across all time, _much_ higher correlations. +Even in an absolute sense, the correlations from the % CLI-in-community are noteworthy: they reach over 0.8 for a period between July and August. ```{r, message = FALSE, warning = FALSE, fig.width = 6, fig.height = 5} @@ -470,19 +473,19 @@ ggplot(df_cor, aes(x = time_value, y = value)) + ``` Another interesting observation is that the correlations from either indicator -increase dramatically sometime around mid-June. -This could be because many counties saw big surges in COVID-19 activity around -that time. These surges created a larger spread between the COVID-19 case rates +increase dramatically sometime around mid-June. +This could be because many counties saw big surges in COVID-19 activity around +that time. These surges created a larger spread between the COVID-19 case rates across the country, and so county-to-county differences started to become easier -to track with the indicators, as the magnitude of these differences started to +to track with the indicators, as the magnitude of these differences started to swamp the noise. -Of course, this is really just speculation, -and we can't say for certain that this is the cause. -Some decent empirical evidence for our explanation, however, can be found -by looking at how COVID-19 case rates vary between counties over time, as shown -below. The median absolute deviation (a robust measure of spread) between -counties rises sharply sometime around mid-June, +Of course, this is really just speculation, +and we can't say for certain that this is the cause. +Some decent empirical evidence for our explanation, however, can be found +by looking at how COVID-19 case rates vary between counties over time, as shown +below. The median absolute deviation (a robust measure of spread) between +counties rises sharply sometime around mid-June, around the same time as the correlations increased. ```{r, message = FALSE, warning = FALSE, fig.width = 6, fig.height = 4} @@ -492,18 +495,18 @@ ggplot(df_in_act %>% group_by(time_value) %>% labs(title = "Median absolute deviation in COVID-19 case rates", subtitle = sprintf("Over all counties with at least %i cumulative cases", case_num), x = "Date", y = "Median abs deviation") + - theme_bw() + theme_bw() ``` ### Correlations Sliced by County Next we compute, for each county with at least 500 cumulative cases, -the Spearman correlations between each of our indicators and COVID-19 case +the Spearman correlations between each of our indicators and COVID-19 case rates, across all time. We can visualize this in a few different ways. -Below we plot estimated densities from these two sets of correlations: -from the % CLI indicator in red, and the % CLI-in-community indicator in blue. -With this slice of the data (correlations by county, rather than by day), -we again see that the % CLI-in-community indicator produces *much* higher +Below we plot estimated densities from these two sets of correlations: +from the % CLI indicator in red, and the % CLI-in-community indicator in blue. +With this slice of the data (correlations by county, rather than by day), +we again see that the % CLI-in-community indicator produces _much_ higher correlations. ```{r, message = FALSE, warning = FALSE, fig.width = 6, fig.height = 5} @@ -525,17 +528,17 @@ ggplot(df_cor, aes(value)) + theme_bw() + theme(legend.pos = "bottom", legend.title = element_blank()) ``` -We can also examine choropleth maps of these correlations to learn -where (geographically speaking) they're high and where they're not. -As we can see from the maps below, the % CLI-in-community indicator -yields high correlations throughout much of the US, -whereas the % CLI indicator is a bit more spotty. -Note that here a gray color denotes a missing value: -either that county had below 500 cumulative COVID-19 cases, +We can also examine choropleth maps of these correlations to learn +where (geographically speaking) they're high and where they're not. +As we can see from the maps below, the % CLI-in-community indicator +yields high correlations throughout much of the US, +whereas the % CLI indicator is a bit more spotty. +Note that here a gray color denotes a missing value: +either that county had below 500 cumulative COVID-19 cases, or we didn't have enough data from the surveys in order to estimate % CLI and % CLI-in-community signals there. -```{r, fig.width = 10, fig.height = 4} +```{r, fig.width = 10, fig.height = 4, out.extra = 'class="wide-figure"'} # Set a bunch of fields so that the data frames know how to plot themselves df_cor1$time_value = df_cor2$time_value = start_day df_cor1$issue = df_cor2$issue = start_day @@ -555,9 +558,9 @@ grid.arrange(p1, p2, nrow = 1) You might expect that a survey that reaches tens of thousands of respondents within the US daily---and has done so for months during a major pandemic---could -have *many* possible uses beyond simply surveying symptoms. You would be right. -Beyond the first section on the core COVID symptoms, our survey contains -questions on testing, behavior, medical care, mental health, and related topics, +have _many_ possible uses beyond simply surveying symptoms. You would be right. +Beyond the first section on the core COVID symptoms, our survey contains +questions on testing, behavior, medical care, mental health, and related topics, opening a multitude of possible research questions up to empirical inquiry. This is why Delphi and the University of Maryland (for the international @@ -572,34 +575,34 @@ Facebook](https://dataforgood.fb.com/docs/covid-19-symptom-survey-request-for-da and our goal is to build a network of researchers committed to fighting the pandemic through our survey data. -To take these efforts to the next level, we'll soon release a new version of the -survey. Based on feedback from other researchers, public health agencies, the +To take these efforts to the next level, we'll soon release a new version of the +survey. Based on feedback from other researchers, public health agencies, the University of Maryland, and Facebook, we've added items asking about: - More details on COVID testing (including whether the respondent tried to get -tested but could not). + tested but could not). - Mask wearing. - The types of activities the respondent has done with other people. - Mental health and social isolation. - Employment. - Demographics (including race and education). -These items will give us an unprecedented view into -how people have responded to the pandemic, +These items will give us an unprecedented view into +how people have responded to the pandemic, how they have been affected by the pandemic and the resulting economic downturn, -and how specific groups are affected. +and how specific groups are affected. We hope the mask and behavior items can help researchers studying -how best to prevent the spread of COVID-19, -and can even help inform forecasts, -while mental health and isolation items will help researchers to understand +how best to prevent the spread of COVID-19, +and can even help inform forecasts, +while mental health and isolation items will help researchers to understand how social distancing and recession have affected mental health. -Together with extended demographic data, this may help to inform policies +Together with extended demographic data, this may help to inform policies designed to help those most affected by the pandemic. -This new survey is currently being deployed, -and data should become available in the next few weeks. +This new survey is currently being deployed, +and data should become available in the next few weeks. Detailed data will be available to researchers, -while new aggregates---such as of mask-wearing---will +while new aggregates---such as of mask-wearing---will be made public, as usual, through our [COVIDcast -API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`) +API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`) and [COVIDcast interactive map](`r blogdown::shortcode_html("ref", "covidcast")`). diff --git a/content/blog/2020-08-26-fb-survey.html b/content/blog/2020-08-26-fb-survey.html index c3cb9d815..3138a7e7a 100644 --- a/content/blog/2020-08-26-fb-survey.html +++ b/content/blog/2020-08-26-fb-survey.html @@ -1,11 +1,14 @@ --- -title: "COVID-19 Symptom Surveys through Facebook" -author: "Alex Reinhart and Ryan Tibshirani" +title: COVID-19 Symptom Surveys through Facebook +author: Alex Reinhart and Ryan Tibshirani date: 2020-08-26 -tags: ["symptom surveys", "COVIDcast", "R"] +tags: + - symptom surveys + - COVIDcast + - R authors: -- alex -- ryan + - alex + - ryan heroImage: /blog/images/blog-lg-img_facebook-survey-post.png heroImageThumb: /blog/images/blog-thumb-img_facebook-survey-post.png summary: | @@ -170,7 +173,7 @@

Short Background

title = "Daily new confirmed COVID-19 cases per 100,000 people", range=c(0, 30), choro_params = list(subtitle = subtitle)) grid.arrange(p1, p2, nrow = 1)
-

+

We generated these plots using our covidcast R package. In all, fetching the data from our API and producing the heatmaps @@ -315,11 +318,11 @@

Some Interesting Examples

given_geo_value = geo_value df_fb_one = df_fb %>% filter(geo_value == given_geo_value) df_in_one = df_in %>% filter(geo_value == given_geo_value) - + # Compute ranges of the two signals range1 = df_in_one %>% select("value") %>% range range2 = df_fb_one %>% select("value") %>% range - + # Convenience functions for our two signal ranges trans12 = function(x) trans(x, range1, range2) trans21 = function(x) trans(x, range2, range1) @@ -335,7 +338,7 @@

Some Interesting Examples

df_in_one), c("time_value", "value")) df$signal = c(rep("% CLI-in-community", nrow(df_fb_one)), rep("New COVID-19 cases", nrow(df_in_one))) - + # Finally, plot both signals pos = ifelse(legend, "bottom", "none") return(ggplot(df, aes(x = time_value, y = value)) + @@ -384,7 +387,7 @@

Some Interesting Examples

p_list[[i]] = plot_one(geo_values[i], legend = FALSE) } do.call(grid.arrange, c(p_list, nrow = 5, ncol = 4)) -

+

The examples above are an informal way of looking at the recall of the % CLI-in-community signal. Of course, this is only one half of the story: @@ -475,7 +478,7 @@

Correlations Sliced by Time

labs(title = "Median absolute deviation in COVID-19 case rates", subtitle = sprintf("Over all counties with at least %i cumulative cases", case_num), x = "Date", y = "Median abs deviation") + - theme_bw() + theme_bw()

@@ -527,7 +530,7 @@

Correlations Sliced by County

p2 = plot(df_cor2, title = "Correlation between % CLI-in-community and case rates", range = c(-1, 1), choro_col = cm.colors(10)) grid.arrange(p1, p2, nrow = 1) -

+

diff --git a/content/blog/2020-08-28-api.Rmd b/content/blog/2020-08-28-api.Rmd index 7a68ee149..4d8bc32f0 100644 --- a/content/blog/2020-08-28-api.Rmd +++ b/content/blog/2020-08-28-api.Rmd @@ -1,11 +1,15 @@ --- -title: "Accessing Open COVID-19 Data via the COVIDcast Epidata API" -author: "Kathryn Mazaitis and Alex Reinhart" +title: Accessing Open COVID-19 Data via the COVIDcast Epidata API +author: Kathryn Mazaitis and Alex Reinhart date: 2020-10-07 -tags: ["COVIDcast API", "COVIDcast", "R", "Python"] +tags: + - COVIDcast API + - COVIDcast + - R + - Python authors: -- kathryn -- alex + - kathryn + - alex heroImage: /blog/images/blog-lg-img_Accessing Open COVID-19.png heroImageThumb: /blog/images/blog-thumb-img_Accessing Open COVID-19.png summary: | @@ -51,22 +55,22 @@ output: knitr::opts_chunk$set(collapse = TRUE) ``` -One of our primary initiatives at the Delphi COVIDcast project +One of our primary initiatives at the Delphi COVIDcast project ([learn more about our organization here](`r blogdown::shortcode_html("ref", "2020-08-10-hello-world")`)) -has been to curate a diverse set of COVID-related data streams, -and to make them freely available through our +has been to curate a diverse set of COVID-related data streams, +and to make them freely available through our [COVIDcast Epidata API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`). -These include both novel signals that we have collected and analyzed ourselves, +These include both novel signals that we have collected and analyzed ourselves, such as our symptom survey [distributed by Facebook](`r blogdown::shortcode_html("ref", "2020-09-18-google-survey")`) to its users, [Google's symptom survey](`r blogdown::shortcode_html("ref", "2020-09-18-google-survey")`) whose results are delivered to us, the percentage of doctor's visits due to COVID-like illness, and results from Quidel's antigen tests; -and also existing signals, such as the confirmed case counts -and deaths reported by USA Facts and Johns Hopkins University. -The COVIDcast API freely provides researchers and decision-makers -with the data they need to conduct their work, and -is conveniently accessible via easy-to-use -[Python](https://cmu-delphi.github.io/covidcast/covidcast-py/html/) +and also existing signals, such as the confirmed case counts +and deaths reported by USA Facts and Johns Hopkins University. +The COVIDcast API freely provides researchers and decision-makers +with the data they need to conduct their work, and +is conveniently accessible via easy-to-use +[Python](https://cmu-delphi.github.io/covidcast/covidcast-py/html/) and [R](https://cmu-delphi.github.io/covidcast/covidcastR/) packages. We have always made our code, data and estimates freely and publicly available, from the very beginning of our work on flu back in 2013, well before the COVID pandemic. @@ -85,18 +89,18 @@ do their jobs effectively. Making sense of the COVID-19 pandemic can be a frustratingly hard problem in part because no one signal can tell the whole story. -Case counts are important, but different states +Case counts are important, but different states use different reporting criteria and testing availability varies. -Deaths are more accurately observed, +Deaths are more accurately observed, but are a very lagging indicator of disease activity. We recognized early on that to make progress, -we require a diversity of data sources. +we require a diversity of data sources. This recognition caused us to shift priorities. Before we could build forecasts and other statistical models, -we needed to rapidly develop new relevant data streams. +we needed to rapidly develop new relevant data streams. This effort grew into the COVIDcast project---see our [introductory -post](`r blogdown::shortcode_html("ref", "2020-08-10-hello-world")`) +post](`r blogdown::shortcode_html("ref", "2020-08-10-hello-world")`) for more about our efforts since March. The data streams that we work with can be roughly mapped @@ -112,42 +116,42 @@ which follows the progression of disease: 7. Some hospitalized patients are subsequently **intubated** or otherwise transferred to an **ICU** ward. 8. Finally, **deaths** due to the illness are recorded. -Each level of the pyramid can be examined -through many different data sources. +Each level of the pyramid can be examined +through many different data sources. For example, aggregated cell phone mobility data -could address population behavior, +could address population behavior, while the volume of certain Google search queries -might correlate with how many people have symptoms or have heightened anxiety or awareness of the disease. -Levels 4 through 8 of the pyramid are medically attended, +might correlate with how many people have symptoms or have heightened anxiety or awareness of the disease. +Levels 4 through 8 of the pyramid are medically attended, and can be examined using various medical records. -Confirmed cases and deaths are reported +Confirmed cases and deaths are reported through local and state health authorities, as are some aspects of hospitalization. As we move from level 1 to level 8, -the data become more specific, -since it is based on more objective and specific criteria. -The data also become less timely: level 1 -can be a *leading indicator* of disease levels in the community, -since behavior affects spread, -whereas level 8 data only occurs after patients -have already been infected and died. -Only at level 5 and up do we actually -gain data involving definite diagnoses---data before level 5 is *behavioral* or *syndromic*, +the data become more specific, +since it is based on more objective and specific criteria. +The data also become less timely: level 1 +can be a _leading indicator_ of disease levels in the community, +since behavior affects spread, +whereas level 8 data only occurs after patients +have already been infected and died. +Only at level 5 and up do we actually +gain data involving definite diagnoses---data before level 5 is _behavioral_ or _syndromic_, meaning it only relates to behaviors and/or constellations of symptoms. -Data streams that are organized in this way +Data streams that are organized in this way can be used for many possible purposes, including: -* **Nowcasting.** If the data can provide a clear picture of what's - happening in each community *right now*, that knowledge can be used to make more informed and responsive decisions +- **Nowcasting.** If the data can provide a clear picture of what's + happening in each community _right now_, that knowledge can be used to make more informed and responsive decisions about re-opening, closures, resource allocation, and so on. -* **Forecasting.** Predicting the likely activity level of the pandemic in each community in the coming weeks can help guide local planning and preparations. For example, predicting the number of upcoming cases can help public health departments hire and train the necessary contact tracers. +- **Forecasting.** Predicting the likely activity level of the pandemic in each community in the coming weeks can help guide local planning and preparations. For example, predicting the number of upcoming cases can help public health departments hire and train the necessary contact tracers. Predicting hospitalizations can help hospitals prepare adequate supplies of PPE, clear hospital beds, and ensure availability of appropriate staff. -* **Scenario projections.** While forecasting predicts what is likely to happen if current circumstances continue unchanged, scenario projections can tell us how the pandemic is likely to unfold under different assumptions, such as changes in specific government policies (e.g. opening or closing schools or businesses), specific public behavior (stay-at-home, mask usage, social distancing), or changes in the properties of the virus or the environment. Scenario projections are most useful for contemplating various interventions. +- **Scenario projections.** While forecasting predicts what is likely to happen if current circumstances continue unchanged, scenario projections can tell us how the pandemic is likely to unfold under different assumptions, such as changes in specific government policies (e.g. opening or closing schools or businesses), specific public behavior (stay-at-home, mask usage, social distancing), or changes in the properties of the virus or the environment. Scenario projections are most useful for contemplating various interventions. -* **Epidemiological research.** The data may help us understand what behaviors +- **Epidemiological research.** The data may help us understand what behaviors are linked to spread, what symptoms commonly occur, and answer other important questions to better understand this and future pandemics and epidemics. @@ -163,27 +167,27 @@ permit us to publish estimates and other aggregated statistics in our COVIDcast Epidata API (often informally called the COVIDcast API). These data sources cover most levels of the severity pyramid and include: -* Massive surveys we conduct through Facebook: Facebook has been sending a +- Massive surveys we conduct through Facebook: Facebook has been sending a random sample of its users to Delphi's symptoms and behavior survey every day since April 6. Our survey averages over 70,000 respondents each day, making it---along with its [international sister survey](https://covidmap.umd.edu/) - run by University of Maryland---the largest public health survey ever conducted. + run by University of Maryland---the largest public health survey ever conducted. Our [previous blog post](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey")`) showed how the survey can indicate COVID-19 activity, and preliminary analysis also suggests [it can help forecast COVID-19 cases](`r blogdown::shortcode_html("ref", "2020-09-21-forecast-demo")`). See our [surveys site](`r blogdown::shortcode_html("ref", "surveys")`) for more on the survey, its questions, and getting access to data. -* Massive surveys we run through Google: +- Massive surveys we run through Google: From April 11 to May 14, 2020, Delphi conducted a single-question symptoms survey - through Google. It reached over 100,000 respondents daily during its - short run, and was a surprisingly informative measure - of pandemic activity preceding medical contact. For more, see our - [previous blog post](`r blogdown::shortcode_html("ref", "2020-09-18-google-survey")`), + through Google. It reached over 100,000 respondents daily during its + short run, and was a surprisingly informative measure + of pandemic activity preceding medical contact. For more, see our + [previous blog post](`r blogdown::shortcode_html("ref", "2020-09-18-google-survey")`), or our [technical documentation](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/google-survey.html")`). As explained in our past blog post, Delphi is currently considering new uses for these surveys. -* Insurance claims: Medical insurance claims include diagnostic codes, +- Insurance claims: Medical insurance claims include diagnostic codes, lab orders, and charge codes which can be used to estimate COVID-19 activity in a region. We have several partners who provide us with @@ -191,97 +195,97 @@ cover most levels of the severity pyramid and include: or allow us to derive such statistics from strictly de-identified claim records. We use this data to construct signals reflecting COVID activity in both outpatient and inpatient visits; see our - technical documentation sites for + technical documentation sites for [doctor's visits](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/doctor-visits.html")`) and [hospital admissions](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/hospital-admissions.html")`) for more details. -* Quidel COVID antigen tests: Quidel is a national provider of networked lab +- Quidel COVID antigen tests: Quidel is a national provider of networked lab testing devices, and began making de-identified records of their COVID-19 antigen tests available to us in early May. This data source fills an important gap because many public testing data sources only include PCR tests, not antigen - tests. Our [technical + tests. Our [technical documentation](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/quidel.html#covid-19-tests")`) gives more details. -* Google search trends: +- Google search trends: We query the Google Health Trends API - for overall searcher interest in a set - of COVID-19 related terms about anosmia - (loss of smell or taste), - which emerged as a specific symptom of COVID-19. + for overall searcher interest in a set + of COVID-19 related terms about anosmia + (loss of smell or taste), + which emerged as a specific symptom of COVID-19. More details, including the search terms and topics we analyze, - are available in our + are available in our [technical documentation](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/ght.html")`). Additionally, we host the following more widely-available signals in our API for the convenience of the research community, and to provide revision tracking: -* Confirmed cases and deaths as reported by [JHU CSSE](https://github.com/CSSEGISandData/COVID-19). -* Confirmed cases and deaths as reported by [USAFacts](https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/). -* Mobility data as made available by +- Confirmed cases and deaths as reported by [JHU CSSE](https://github.com/CSSEGISandData/COVID-19). +- Confirmed cases and deaths as reported by [USAFacts](https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/). +- Mobility data as made available by [SafeGraph](https://docs.safegraph.com/docs/social-distancing-metrics); SafeGraph makes detailed de-identified data available to researchers, and by agreement with SafeGraph, we make county-level aggregates publicly available. -Nearly all our data streams are available -at the county level across the United States. -We also aggregate our signals to metropolitan statistical areas and states, and some signals to Hospital Referral Regions (HRRs). -For a full list of all data streams, see our +Nearly all our data streams are available +at the county level across the United States. +We also aggregate our signals to metropolitan statistical areas and states, and some signals to Hospital Referral Regions (HRRs). +For a full list of all data streams, see our [COVIDcast signal documentation site](`r blogdown::shortcode_html("apiref", "api/covidcast_signals.html")`). The software we've developed to obtain and aggregate this data is open-source, shared in our [covidcast-indicators GitHub repository](https://github.com/cmu-delphi/covidcast-indicators). -All the above data streams are made publicly available -through our COVIDcast API---if you're interested +All the above data streams are made publicly available +through our COVIDcast API---if you're interested in using these signals for decision making, research, investigative journalism -or simply to understand trends in your area, -pulling the data is only a moment's work. +or simply to understand trends in your area, +pulling the data is only a moment's work. Let's discuss how the data is stored and how you can get access. ## Tracking Observations and Revisions -Each record in our database is an observation covering +Each record in our database is an observation covering a set of events aggregated by time and by geographic region. -Most signals in the API are available at a daily resolution, +Most signals in the API are available at a daily resolution, but some are available only weekly, -so we try to keep the definitions below general. +so we try to keep the definitions below general. Each record includes: -* `time_value`: The time period when the events occurred. -* `geo_value`: The geographic region where the events occurred. -* `value`: The estimated value. -* `stderr`: The standard error of the estimate, usually referring to the sampling error. -* `sample_size`: The number of events used in the estimation. +- `time_value`: The time period when the events occurred. +- `geo_value`: The geographic region where the events occurred. +- `value`: The estimated value. +- `stderr`: The standard error of the estimate, usually referring to the sampling error. +- `sample_size`: The number of events used in the estimation. -For example, a number of COVID-19 antigen tests -were performed in the state of New York on August 1. -The `time_value` would be August 1, +For example, a number of COVID-19 antigen tests +were performed in the state of New York on August 1. +The `time_value` would be August 1, with `geo_value` indicating the state of New York, -while the remaining fields would give the estimated test positivity rate -(the percentage of tests that were positive for COVID-19), +while the remaining fields would give the estimated test positivity rate +(the percentage of tests that were positive for COVID-19), its standard error, and the number of tests used to calculate the estimate. But crucially---and unlike most other sources of COVID-19 data---our API reports two additional fields with each record: -* `issue`: The time period when this observation was published. -* `lag`: The time delay between when the events occurred and when this +- `issue`: The time period when this observation was published. +- `lag`: The time delay between when the events occurred and when this observation was published. -For example, results of COVID-19 antigen tests may take -between four days and six weeks to reach us, -depending on the technology and staff available at each testing site. -We might publish our first estimate +For example, results of COVID-19 antigen tests may take +between four days and six weeks to reach us, +depending on the technology and staff available at each testing site. +We might publish our first estimate of August 1st's test positivity rate on August 6th, giving an issue date of August 6 and a lag of five days. -But when more data about August 1st's tests arrive the next day, -we issue a second estimate with an issue date of August 7 and a lag of six days. -Each record remains in the API, permitting users to see the changes -and ask "What was known *as of* this date?" -This is important because estimates -can change for *weeks* as new data arrives: +But when more data about August 1st's tests arrive the next day, +we issue a second estimate with an issue date of August 7 and a lag of six days. +Each record remains in the API, permitting users to see the changes +and ask "What was known _as of_ this date?" +This is important because estimates +can change for _weeks_ as new data arrives: ```{r q-versioning, warning=FALSE, message=FALSE, cache=TRUE} library(covidcast) @@ -304,17 +308,17 @@ covidcast_signal( Many data sources are subject to revisions: -* Case and death counts are frequently corrected or adjusted by authorities. -* Medical claims data can take weeks to be submitted and processed. -* Lab tests and medical records can be backlogged for a variety of reasons. -* Surveys are not always completed promptly. - -An accurate revision log is crucial for researchers -building forecasts of COVID-19 cases or outcomes. -A forecast that is made today can only rely -on information we have access to today. -Forecasting models are often developed by building them -to predict cases using historical data---but to do so, +- Case and death counts are frequently corrected or adjusted by authorities. +- Medical claims data can take weeks to be submitted and processed. +- Lab tests and medical records can be backlogged for a variety of reasons. +- Surveys are not always completed promptly. + +An accurate revision log is crucial for researchers +building forecasts of COVID-19 cases or outcomes. +A forecast that is made today can only rely +on information we have access to today. +Forecasting models are often developed by building them +to predict cases using historical data---but to do so, the model should use only data that was available on the forecast date, not the updates that would arrive later. @@ -325,20 +329,20 @@ date, and preserves the history of changes for future analysis. ## Accessing the API -A massive database of COVID-19 data is, of course, -of no use if nobody can access it. +A massive database of COVID-19 data is, of course, +of no use if nobody can access it. We provide several ways to access COVIDcast data. -First, the [public COVIDcast map](`r blogdown::shortcode_html("ref", "covidcast")`) -provides a selection of our signals, -and includes an "Export Data" tab that can -pull a selected signal and download it as a CSV. -Browse the map to choose which signal you are interested in, +First, the [public COVIDcast map](`r blogdown::shortcode_html("ref", "covidcast")`) +provides a selection of our signals, +and includes an "Export Data" tab that can +pull a selected signal and download it as a CSV. +Browse the map to choose which signal you are interested in, then use Export Data to obtain the data for further analysis. For more advanced users, we provide R and Python packages -to make data access easy for anyone conducting -data analysis in either language. +to make data access easy for anyone conducting +data analysis in either language. The first step of using the packages to acquire the data is to identify the source and signal name for the data you want to analyze. Suppose, for example, @@ -352,12 +356,12 @@ signals to choose from. Reviewing the technical details, you decide `smoothed_adj_covid19` fits your needs best, because it removes day-of-week effects. -With the source and signal names in hand, you can quickly pull the data. +With the source and signal names in hand, you can quickly pull the data. -An R user can install our -[R covidcast package](https://cmu-delphi.github.io/covidcast/covidcastR/) -and then quickly plot the percentage of hospital admissions -that are due to COVID-19 in several states. +An R user can install our +[R covidcast package](https://cmu-delphi.github.io/covidcast/covidcastR/) +and then quickly plot the percentage of hospital admissions +that are due to COVID-19 in several states. (Click the "Code" button to see the R code used to produce this example.) ```{r dv-graph, message=FALSE, cache=TRUE} @@ -371,12 +375,12 @@ plot(hosp, plot_type = "line", title = "% of hospital admissions due to COVID-19") ``` -Since the packages also support mapping, -we can examine the percentage -of outpatient doctor's visits +Since the packages also support mapping, +we can examine the percentage +of outpatient doctor's visits due to COVID-Like-Illness (CLI) in the South. -```{r dv-maps, message=FALSE, cache=TRUE, fig.width=10} +```{r dv-maps, message=FALSE, cache=TRUE, fig.width=10, out.extra = 'class="wide-figure"'} library(gridExtra) dv <- covidcast_signal( data_source = "doctor-visits", signal = "smoothed_adj_cli", @@ -390,11 +394,11 @@ g2 <- plot(dv, time_value = "2020-08-24", include = south, grid.arrange(g1, g2, nrow = 1) ``` -In Python, fetching data requires the +In Python, fetching data requires the [Python covidcast package](https://cmu-delphi.github.io/covidcast/covidcast-py/html/), -which can quickly produce a Pandas data frame. -For example, here we fetch the estimated percentage -of people in each state who know someone who is sick, +which can quickly produce a Pandas data frame. +For example, here we fetch the estimated percentage +of people in each state who know someone who is sick, based on Delphi's [symptom surveys](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey")`). According to the [relevant documentation @@ -421,7 +425,7 @@ Both packages support querying the latest version of data---as shown above---but can also fetch prior revisions or only the information that was available on a certain date. -Finally, R and Python are not required for access to our data; users can also +Finally, R and Python are not required for access to our data; users can also make HTTP requests to the API directly and receive data back in JSON format. By setting `data_source`, `signal`, `time_type`, `geo_type`, `time_values`, and `geo_value` parameters in the query URL, you can select the specific data source you @@ -443,33 +447,33 @@ most programming languages---to fetch up-to-date data. ## Putting the API to Work -The [COVIDcast API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`) +The [COVIDcast API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`) provides unified access to numerous COVID data streams, -which can be browsed through our [interactive map](`r blogdown::shortcode_html("ref", "covidcast")`) -and easily accessed through our +which can be browsed through our [interactive map](`r blogdown::shortcode_html("ref", "covidcast")`) +and easily accessed through our [R and Python packages](`r blogdown::shortcode_html("apiref", "api/covidcast_clients.html")`). Unlike most other sources of COVID data, -it tracks the complete revision history of every signal, +it tracks the complete revision history of every signal, allowing historical reconstructions of -what information was available at specific times. -Additionally, many of our data streams simply +what information was available at specific times. +Additionally, many of our data streams simply aren't available anywhere else. -We invite you to put the API to use for your own purposes. -Building a dashboard for your community? -Testing out forecasting methods? -Studying how the pandemic evolves? +We invite you to put the API to use for your own purposes. +Building a dashboard for your community? +Testing out forecasting methods? +Studying how the pandemic evolves? We might have the data you're looking for. -Many of our data streams are already being used to inform decision-making. -For example, [COVID Exit Strategy](https://www.covidexitstrategy.org/) -tracks the pandemic and whether states are ready to reopen, -using symptom survey data from the COVIDcast API as a key data source. -Anthem's [C19 Explorer](https://c19explorer.io/) -presents a comprehensive community picture of the pandemic, -including outpatient doctor's visit data from COVIDcast. -Aledade's [COVID-19 Interactive Map](https://covidmap.aledade.com/) -applies scan statistics algorithms to COVIDcast survey data +Many of our data streams are already being used to inform decision-making. +For example, [COVID Exit Strategy](https://www.covidexitstrategy.org/) +tracks the pandemic and whether states are ready to reopen, +using symptom survey data from the COVIDcast API as a key data source. +Anthem's [C19 Explorer](https://c19explorer.io/) +presents a comprehensive community picture of the pandemic, +including outpatient doctor's visit data from COVIDcast. +Aledade's [COVID-19 Interactive Map](https://covidmap.aledade.com/) +applies scan statistics algorithms to COVIDcast survey data to detect statistically significant clusters. We hope to see you join this list soon! diff --git a/content/blog/2020-08-28-api.html b/content/blog/2020-08-28-api.html index 194ac137a..8f3c6d8a4 100644 --- a/content/blog/2020-08-28-api.html +++ b/content/blog/2020-08-28-api.html @@ -1,11 +1,15 @@ --- -title: "Accessing Open COVID-19 Data via the COVIDcast Epidata API" -author: "Kathryn Mazaitis and Alex Reinhart" +title: Accessing Open COVID-19 Data via the COVIDcast Epidata API +author: Kathryn Mazaitis and Alex Reinhart date: 2020-10-07 -tags: ["COVIDcast API", "COVIDcast", "R", "Python"] +tags: + - COVIDcast API + - COVIDcast + - R + - Python authors: -- kathryn -- alex + - kathryn + - alex heroImage: /blog/images/blog-lg-img_Accessing Open COVID-19.png heroImageThumb: /blog/images/blog-thumb-img_Accessing Open COVID-19.png summary: | @@ -548,7 +552,7 @@

Accessing the API

g2 <- plot(dv, time_value = "2020-08-24", include = south, title = "% of doctor's visits due to CLI on August 24") grid.arrange(g1, g2, nrow = 1) -

+

In Python, fetching data requires the Python covidcast package, which can quickly produce a Pandas data frame. diff --git a/content/blog/2020-09-18-google-survey.Rmd b/content/blog/2020-09-18-google-survey.Rmd index 93eab0bd8..86b22e618 100644 --- a/content/blog/2020-09-18-google-survey.Rmd +++ b/content/blog/2020-09-18-google-survey.Rmd @@ -1,10 +1,13 @@ --- -title: "COVID-19 Symptom Surveys through Google" -author: "Ryan Tibshirani" +title: COVID-19 Symptom Surveys through Google +author: Ryan Tibshirani date: 2020-09-18 -tags: ["symptom surveys", "COVIDcast", "R"] +tags: + - symptom surveys + - COVIDcast + - R authors: -- ryan + - ryan heroImage: /blog/images/blog-lg-img_google-survey-post.png heroImageThumb: /blog/images/blog-thumb-img_google-survey-post.png summary: | @@ -19,7 +22,7 @@ summary: | This short post covers some key differences between our Google and Facebook surveys, explains the backstory behind the "CLI-in-community" question as it arose through our collaboration with Google, - and shares some of our thinking about next steps for the Google survey. + and shares some of our thinking about next steps for the Google survey. acknowledgements: | Ryan Tibshirani wrote the initial code for producing estimates from the aggregated survey data. Sangwon Hyun, Natalia Lombardi de @@ -38,108 +41,109 @@ output: --- Since April 2020, in addition to our [massive daily survey advertised on -Facebook](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey")`), -we've been running (even-more-massive) surveys through Google to track the -spread of COVID-19 in the United States. At its peak, our Google survey was -taken by over 1.2 million people in a single day, and over its first month in +Facebook](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey")`), +we've been running (even-more-massive) surveys through Google to track the +spread of COVID-19 in the United States. At its peak, our Google survey was +taken by over 1.2 million people in a single day, and over its first month in operation, averaged about 600,000 daily respondents. As usual, we make aggregated data from this survey available through our [COVIDcast API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`). In mid-May, we decided to pause daily dissemination of this survey in order to -focus on our (longer, more complex) survey through Facebook, -but we plan to bring back the Google survey this fall. -The two surveys are, in fact, quite different and complement each other nicely. -This short post covers some key differences between our Google and Facebook +focus on our (longer, more complex) survey through Facebook, +but we plan to bring back the Google survey this fall. +The two surveys are, in fact, quite different and complement each other nicely. +This short post covers some key differences between our Google and Facebook surveys, explains the backstory behind the "CLI-in-community" question -as it arose through our collaboration with Google's team, +as it arose through our collaboration with Google's team, and shares some of our thinking about next steps for the Google survey. ## Short Background -Back in March 2020, around the time we began discussions with Facebook about -COVID-19 symptom surveys, we pitched the same idea to Google. -Our motivation, [as we explained in our last -post](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#why-run-these-surveys")`), -has been to produce real-time, county-level data streams of self-reported COVID -symptoms that can potentially serve as **early indicators** of COVID activity in +Back in March 2020, around the time we began discussions with Facebook about +COVID-19 symptom surveys, we pitched the same idea to Google. +Our motivation, [as we explained in our last +post](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#why-run-these-surveys")`), +has been to produce real-time, county-level data streams of self-reported COVID +symptoms that can potentially serve as **early indicators** of COVID activity in the US. As we noted in that post, we weren't the only data scientists -who thought of running COVID-19 symptom surveys, and several -other groups had deployed surveys before us. -What distinguished our strategy from others' -was the pursuit of a giant like Google to achieve widespread and continuous -dissemination (well beyond what we could do ourselves). -Google's willingness to help was a *huge* win for us. -Of all the partnerships we formed to create new COVID-19 indicators, -our deal with Google was the first to come through. -This gave us an invaluable confidence boost, -and taught us the silver lining of this pandemic: +who thought of running COVID-19 symptom surveys, and several +other groups had deployed surveys before us. +What distinguished our strategy from others' +was the pursuit of a giant like Google to achieve widespread and continuous +dissemination (well beyond what we could do ourselves). +Google's willingness to help was a _huge_ win for us. +Of all the partnerships we formed to create new COVID-19 indicators, +our deal with Google was the first to come through. +This gave us an invaluable confidence boost, +and taught us the silver lining of this pandemic: that many people are truly generous and willing to help. Google's contributions didn't stop there---they have been helping us in [various ways ever since](https://blog.google/outreach-initiatives/google-org/google-supports-covid-19-ai-and-data-analytics-projects). -Our initial survey with Google launched in late March, +Our initial survey with Google launched in late March, deployed through various websites and apps (with whom Google partners -to run questionnaires). Each respondent opted-in to answering the survey and +to run questionnaires). Each respondent opted-in to answering the survey and agreed to legal disclosures about how the data would be used. The survey asked -just a single question: +just a single question: -> Do you or anyone in your household have a fever of at least 100 °F, along -with cough, shortness of breath, or difficulty breathing? +> Do you or anyone in your household have a fever of at least 100 °F, along +> with cough, shortness of breath, or difficulty breathing? -This pattern of symptoms defines a condition called -**COVID-like illness** or **CLI**. -A respondent could reply "Yes", "No", or "Prefer not to say". -We're also given the respondent's (inferred) county from IP address lookup. -At the start, this survey data allowed us to estimate the daily % CLI, -the percentage of people with COVID-like illness, in over 1,000 counties across +This pattern of symptoms defines a condition called +**COVID-like illness** or **CLI**. +A respondent could reply "Yes", "No", or "Prefer not to say". +We're also given the respondent's (inferred) county from IP address lookup. +At the start, this survey data allowed us to estimate the daily % CLI, +the percentage of people with COVID-like illness, in over 1,000 counties across the US. After about 2 weeks, we stopped the survey. Google wondered whether we could get equally useful information without asking a question of such a sensitive nature. In general, asking a person about their -health (or their family’s health) is not common practice on Google’s survey -platform. The hope was that asking a broader question might also improve -response rates, reduce costs, and increase the number of potential respondents. +health (or their family’s health) is not common practice on Google’s survey +platform. The hope was that asking a broader question might also improve +response rates, reduce costs, and increase the number of potential respondents. -## CLI-in-Community +## CLI-in-Community Working with Brett Slatkin (head of Google Surveys) -and Hal Varian (Google's Chief Economist), we looked for a new question. +and Hal Varian (Google's Chief Economist), we looked for a new question. Brett came up with a list of questions that were acceptable, and the most promising among them was: > Do you know of someone in your community who is sick with a fever, along with -cough, shortness of breath, or difficulty breathing right now? - -We decided to deploy this proxy question[^1] on April 11, 2020. -We narrowed our focus to fewer counties: -roughly the top 600 in terms of population, -and estimated the daily % CLI-in-community, -the percentage of people who *know someone in their community* with COVID-like -illness. The initial results far exceeded our expectations, -and were promising enough that within days we added -this CLI-in-community question to our survey through Facebook. - -[^1]: In the survey methodology literature, a "proxy question" is one in which -the subject is asked to report on someone else. The traditional view seems to -be that proxy questions can undermine survey data quality, but in our setting -it's critical: not only does it provide a safeguard against revealing personal -health information, it turned out to deliver [much higher -correlations](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#basic-correlation-analysis")`) -with case rates than the direct (non-proxy) question. - -To give you a feel for the data, below we plot -the daily new COVID-19 cases per 100,000 people -versus the estimated % CLI-in-community from our Google survey, -at the state level, averaged over April 11 to mid-May. -This is shown on the left, and on the right, -we reproduce this with the estimated % CLI-in-community from our Facebook +> cough, shortness of breath, or difficulty breathing right now? + +We decided to deploy this proxy question[^1] on April 11, 2020. +We narrowed our focus to fewer counties: +roughly the top 600 in terms of population, +and estimated the daily % CLI-in-community, +the percentage of people who _know someone in their community_ with COVID-like +illness. The initial results far exceeded our expectations, +and were promising enough that within days we added +this CLI-in-community question to our survey through Facebook. + +[^1]: + In the survey methodology literature, a "proxy question" is one in which + the subject is asked to report on someone else. The traditional view seems to + be that proxy questions can undermine survey data quality, but in our setting + it's critical: not only does it provide a safeguard against revealing personal + health information, it turned out to deliver [much higher + correlations](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#basic-correlation-analysis")`) + with case rates than the direct (non-proxy) question. + +To give you a feel for the data, below we plot +the daily new COVID-19 cases per 100,000 people +versus the estimated % CLI-in-community from our Google survey, +at the state level, averaged over April 11 to mid-May. +This is shown on the left, and on the right, +we reproduce this with the estimated % CLI-in-community from our Facebook survey. ```{r, include = FALSE} knitr::opts_chunk$set(cache = TRUE, autodep = TRUE, cache.comments = TRUE) ``` -```{r, message = FALSE, warning = FALSE, fig.width = 10, fig.height = 5} +```{r, message = FALSE, warning = FALSE, fig.width = 10, fig.height = 5, out.extra = 'class="wide-figure"'} library(covidcast) library(dplyr) library(ggplot2) @@ -152,18 +156,18 @@ df_go = covidcast_signal("google-survey", "smoothed_cli", geo_type = "state") start_day = min(df_go$time_value) end_day = max(df_go$time_value) -df_fb = covidcast_signal("fb-survey", "smoothed_hh_cmnty_cli", +df_fb = covidcast_signal("fb-survey", "smoothed_hh_cmnty_cli", start_day, end_day, geo_type = "state") df_in = covidcast_signal("jhu-csse", "confirmed_7dav_incidence_prop", start_day, end_day, geo_type = "state") -# Join by state, average signals, compute correlations +# Join by state, average signals, compute correlations df1 = inner_join(df_go %>% group_by(geo_value) %>% summarize(x = mean(value)), df_in %>% group_by(geo_value) %>% summarize(y = mean(value)), - by = "geo_value") + by = "geo_value") df2 = inner_join(df_fb %>% group_by(geo_value) %>% summarize(x = mean(value)), - df_in %>% group_by(geo_value) %>% summarize(y = mean(value)), - by = "geo_value") + df_in %>% group_by(geo_value) %>% summarize(y = mean(value)), + by = "geo_value") # Join again to get state populations df1 = inner_join(df1, state_census %>% mutate(ABBR = tolower(ABBR)), @@ -176,22 +180,22 @@ ggplot_colors = c("#FC4E07", "#00AFBB", "#E7B800") # Now make plots subtitle = paste("Averaged over", start_day, "to", end_day) -p1 = ggplot(df1, aes(x = x, y = y, label = toupper(geo_value))) + +p1 = ggplot(df1, aes(x = x, y = y, label = toupper(geo_value))) + geom_smooth(method = "lm", col = ggplot_colors[2], se = FALSE) + - geom_point(aes(size = POPESTIMATE2019), color = ggplot_colors[2], - alpha = 0.5) + - scale_size(name = "Population", range = c(1, 10)) + + geom_point(aes(size = POPESTIMATE2019), color = ggplot_colors[2], + alpha = 0.5) + + scale_size(name = "Population", range = c(1, 10)) + geom_text(alpha = 0.5) + - labs(x = "% CLI-in-community from Google surveys", + labs(x = "% CLI-in-community from Google surveys", y = "Daily new confirmed COVID-19 cases per 100,000 people", title = "COVID-19 case rates vs Google % CLI-in-community", subtitle = subtitle) + theme_bw() + theme(legend.position = "bottom") -p2 = ggplot(df2, aes(x = x, y = y, label = toupper(geo_value))) + +p2 = ggplot(df2, aes(x = x, y = y, label = toupper(geo_value))) + geom_smooth(method = "lm", col = ggplot_colors[1], se = FALSE) + - geom_point(aes(size = POPESTIMATE2019), color = ggplot_colors[1], - alpha = 0.5) + - scale_size(name = "Population", range = c(1, 10)) + + geom_point(aes(size = POPESTIMATE2019), color = ggplot_colors[1], + alpha = 0.5) + + scale_size(name = "Population", range = c(1, 10)) + geom_text(alpha = 0.5) + labs(x = "% CLI-in-community from Facebook surveys", y = "", title = "COVID-19 case rates vs Facebook % CLI-in-community", @@ -200,88 +204,89 @@ p2 = ggplot(df2, aes(x = x, y = y, label = toupper(geo_value))) + grid.arrange(p1, p2, nrow = 1) ``` -In both plots, we see a reassuring trend, -but the trend on the left is noticeably stronger. -Indeed, the correlation here between the Google signal and case rates is -`r round(cor(df1$x, df1$y), 2)`, -while that between the Facebook signal and case rates is +In both plots, we see a reassuring trend, +but the trend on the left is noticeably stronger. +Indeed, the correlation here between the Google signal and case rates is +`r round(cor(df1$x, df1$y), 2)`, +while that between the Facebook signal and case rates is `r round(cor(df2$x, df2$y), 2)`. To be fair, we should note that the Google signal comprises a much -larger number of survey samples (as we'll emphasize next), +larger number of survey samples (as we'll emphasize next), and the Facebook signal's correlations to case rates shot up in mid-June (as we saw last time and we'll revisit, shortly). -From April 11 through May 14, we ran Google surveys in over 600 counties -per day, with a target of at least 1,000 responses per county. +From April 11 through May 14, we ran Google surveys in over 600 counties +per day, with a target of at least 1,000 responses per county. The average number of responses per day was over 600,000, -and at its peak, over 1.2 million! -(By comparison, our survey through Facebook averages -about 74,000 responses per day.) -The actual sampling scheme behind our Google survey is more complicated, +and at its peak, over 1.2 million! +(By comparison, our survey through Facebook averages +about 74,000 responses per day.) +The actual sampling scheme behind our Google survey is more complicated, and involves two-level stratification, across both counties and states. -For details, including those on statistical estimation, -visit our [COVIDcast signals +For details, including those on statistical estimation, +visit our [COVIDcast signals documentation](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/google-survey.html")`). -On May 15, we paused our Google survey to focus on our Facebook survey, -which is both longer and more complex. -Importantly, the latter is *not* a replacement for the former, -and our two surveys have different and complementary use cases. +On May 15, we paused our Google survey to focus on our Facebook survey, +which is both longer and more complex. +Importantly, the latter is _not_ a replacement for the former, +and our two surveys have different and complementary use cases. ## Our Two Surveys -We discuss some similarities and differences +We discuss some similarities and differences between the Google and Facebook surveys. -Starting with similarities, both have been deployed at a massive scale, -reaching tens of thousands of people per day, -and covering much of the US at the county level. -To state the obvious, both ask the same question: -whether a person knows someone in their community with COVID-like illness, -and both lead to an estimate of % CLI-in-community. - -Below we assess the numerical similarity of these estimates via correlations: -we correlate them against each other, and for reference, -correlate each against COVID-19 case rates. +Starting with similarities, both have been deployed at a massive scale, +reaching tens of thousands of people per day, +and covering much of the US at the county level. +To state the obvious, both ask the same question: +whether a person knows someone in their community with COVID-like illness, +and both lead to an estimate of % CLI-in-community. + +Below we assess the numerical similarity of these estimates via correlations: +we correlate them against each other, and for reference, +correlate each against COVID-19 case rates. To be more specific, for each pair of the following: Google signal, Facebook signal, and COVID-19 case rates, -and for each day that we have data available, -we compute the Spearman correlation across all counties +and for each day that we have data available, +we compute the Spearman correlation across all counties that had at least 200 cumulative COVID-19 cases -by May 14 (the end of Google survey data). -Over the first month of data, from mid-April to mid-May, -we can see that the highest correlations clearly belong to -those between the two survey signals. -This is as expected, since in principle, -these two surveys are measuring the same underlying quantity.[^2] -The next largest correlations over the first month -belong to those between the Google signal and case rates, -which for the most part holds a substantial gap over the -correlations between the Facebook signal and case rates. +by May 14 (the end of Google survey data). +Over the first month of data, from mid-April to mid-May, +we can see that the highest correlations clearly belong to +those between the two survey signals. +This is as expected, since in principle, +these two surveys are measuring the same underlying quantity.[^2] +The next largest correlations over the first month +belong to those between the Google signal and case rates, +which for the most part holds a substantial gap over the +correlations between the Facebook signal and case rates. This is no doubt encouraging, especially because we'd hope that the Google correlations would have only improved later in -the year (as did the Facebook correlations, which we [previously +the year (as did the Facebook correlations, which we [previously suggested](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#basic-correlation-analysis")`) could have been due to the increase in the diversity of county-level case rates around mid-June). -[^2]: A closer look reveals that the relationship between the Google -% CLI-in-community and Facebook % CLI-in-community signals is not 1:1. For -example, you can check the x-axes in the first example in this blog post: the -range of the Facebook signal is over twice that of the Google signal. There -are differences in the setups we can point to: the two surveys phrase the -CLI-in-community question slightly differently; they reach different subpopulations -of the US; and the estimation procedures behind the surveys handle -missing responses differently. But as far as we can tell, none of this can really -explain why the Facebook numbers are over twice as large as the Google ones, a -trend that seems pretty consistent across location and time. We'll save rigorous -analysis for when we work on deploying these two surveys in tandem; for now, we -emphasize that this observation reiterates the importance of focusing on -*time-varying trends* in the survey signals, not the signal values themselves -(a point we [made in our last -post](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#why-run-these-surveys")`)). -Here, the self-reporting aspect must somehow be creating greatly different -levels of bias in the two surveys; in an absolute sense, the subsequent -estimates of % CLI-in-community strongly disagree, so both can't be right, and -this casts doubt on the idea that either could be bias-free. +[^2]: + A closer look reveals that the relationship between the Google + % CLI-in-community and Facebook % CLI-in-community signals is not 1:1. For + example, you can check the x-axes in the first example in this blog post: the + range of the Facebook signal is over twice that of the Google signal. There + are differences in the setups we can point to: the two surveys phrase the + CLI-in-community question slightly differently; they reach different subpopulations + of the US; and the estimation procedures behind the surveys handle + missing responses differently. But as far as we can tell, none of this can really + explain why the Facebook numbers are over twice as large as the Google ones, a + trend that seems pretty consistent across location and time. We'll save rigorous + analysis for when we work on deploying these two surveys in tandem; for now, we + emphasize that this observation reiterates the importance of focusing on + _time-varying trends_ in the survey signals, not the signal values themselves + (a point we [made in our last + post](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#why-run-these-surveys")`)). + Here, the self-reporting aspect must somehow be creating greatly different + levels of bias in the two surveys; in an absolute sense, the subsequent + estimates of % CLI-in-community strongly disagree, so both can't be right, and + this casts doubt on the idea that either could be bias-free. ```{r, message = FALSE, warning = FALSE, fig.width = 6, fig.height = 5} # Fetch county-level Google and Facebook % CLI-in-community signals, and JHU @@ -291,7 +296,7 @@ df_go = covidcast_signal("google-survey", "smoothed_cli") start_day = min(df_go$time_value) end_day = "2020-09-01" -df_fb = covidcast_signal("fb-survey", "smoothed_hh_cmnty_cli", +df_fb = covidcast_signal("fb-survey", "smoothed_hh_cmnty_cli", start_day, end_day) df_in = covidcast_signal("jhu-csse", "confirmed_7dav_incidence_prop", start_day, end_day) @@ -323,34 +328,34 @@ ggplot(df_cor, aes(x = time_value, y = value)) + scale_color_manual(values = ggplot_colors) + labs(title = "Correlation between survey signals and case rates", subtitle = sprintf("Over all counties with at least %i cumulative cases", - case_num), + case_num), x = "Date", y = "Correlation") + theme_bw() + theme(legend.pos = "bottom", legend.title = element_blank()) ``` Now let's consider the differences between the surveys. Here's a summary: -- Our Facebook survey is *advertised by Facebook* but *run by us* (on a -CMU-licensed Qualtrics platform); this means that we receive all the -individual survey responses directly (and Facebook never sees any of the data). +- Our Facebook survey is _advertised by Facebook_ but _run by us_ (on a + CMU-licensed Qualtrics platform); this means that we receive all the + individual survey responses directly (and Facebook never sees any of the data). -- On the other hand, our Google survey is *deployed directly by Google* through -partner websites and apps they use to run questionnaires; -this means that we don't see individual survey responses, -but receive aggregated survey data from Google. +- On the other hand, our Google survey is _deployed directly by Google_ through + partner websites and apps they use to run questionnaires; + this means that we don't see individual survey responses, + but receive aggregated survey data from Google. - This makes a big difference as to how much (and what questions) we can ask on -the survey: our Google survey is just a single question long, and our Facebook -survey is much longer and more detailed, currently over 35 questions. + the survey: our Google survey is just a single question long, and our Facebook + survey is much longer and more detailed, currently over 35 questions. -- Finally, there's a big difference in how much we control with respect to the -geographic distribution of the survey samples: on our Facebook survey, we have -no control over this, but on our Google survey we have full control, -in that we can pick the counties we want to sample from ahead of time. +- Finally, there's a big difference in how much we control with respect to the + geographic distribution of the survey samples: on our Facebook survey, we have + no control over this, but on our Google survey we have full control, + in that we can pick the counties we want to sample from ahead of time. ## Google Survey Redux -As we can see from the above summary, +As we can see from the above summary, the two survey schemes are complementary, and could be used synergistically. Our Facebook survey is a continuously-running, wide-reaching instrument @@ -366,4 +371,4 @@ terminology!). This could be done automatically (it would be a pretty big, nonstationary [multi-armed bandit problem](https://en.wikipedia.org/wiki/Multi-armed_bandit)) or manually (in collaboration with partners in public health and/or data -journalists). Stay tuned to the Delphi blog for updates. \ No newline at end of file +journalists). Stay tuned to the Delphi blog for updates. diff --git a/content/blog/2020-09-18-google-survey.html b/content/blog/2020-09-18-google-survey.html index a2d752821..83520de30 100644 --- a/content/blog/2020-09-18-google-survey.html +++ b/content/blog/2020-09-18-google-survey.html @@ -1,10 +1,13 @@ --- -title: "COVID-19 Symptom Surveys through Google" -author: "Ryan Tibshirani" +title: COVID-19 Symptom Surveys through Google +author: Ryan Tibshirani date: 2020-09-18 -tags: ["symptom surveys", "COVIDcast", "R"] +tags: + - symptom surveys + - COVIDcast + - R authors: -- ryan + - ryan heroImage: /blog/images/blog-lg-img_google-survey-post.png heroImageThumb: /blog/images/blog-thumb-img_google-survey-post.png summary: | @@ -19,7 +22,7 @@ This short post covers some key differences between our Google and Facebook surveys, explains the backstory behind the "CLI-in-community" question as it arose through our collaboration with Google, - and shares some of our thinking about next steps for the Google survey. + and shares some of our thinking about next steps for the Google survey. acknowledgements: | Ryan Tibshirani wrote the initial code for producing estimates from the aggregated survey data. Sangwon Hyun, Natalia Lombardi de @@ -147,18 +150,18 @@

CLI-in-Community

start_day = min(df_go$time_value) end_day = max(df_go$time_value) -df_fb = covidcast_signal("fb-survey", "smoothed_hh_cmnty_cli", +df_fb = covidcast_signal("fb-survey", "smoothed_hh_cmnty_cli", start_day, end_day, geo_type = "state") df_in = covidcast_signal("jhu-csse", "confirmed_7dav_incidence_prop", start_day, end_day, geo_type = "state") -# Join by state, average signals, compute correlations +# Join by state, average signals, compute correlations df1 = inner_join(df_go %>% group_by(geo_value) %>% summarize(x = mean(value)), df_in %>% group_by(geo_value) %>% summarize(y = mean(value)), - by = "geo_value") + by = "geo_value") df2 = inner_join(df_fb %>% group_by(geo_value) %>% summarize(x = mean(value)), - df_in %>% group_by(geo_value) %>% summarize(y = mean(value)), - by = "geo_value") + df_in %>% group_by(geo_value) %>% summarize(y = mean(value)), + by = "geo_value") # Join again to get state populations df1 = inner_join(df1, state_census %>% mutate(ABBR = tolower(ABBR)), @@ -171,29 +174,29 @@

CLI-in-Community

# Now make plots subtitle = paste("Averaged over", start_day, "to", end_day) -p1 = ggplot(df1, aes(x = x, y = y, label = toupper(geo_value))) + +p1 = ggplot(df1, aes(x = x, y = y, label = toupper(geo_value))) + geom_smooth(method = "lm", col = ggplot_colors[2], se = FALSE) + - geom_point(aes(size = POPESTIMATE2019), color = ggplot_colors[2], - alpha = 0.5) + - scale_size(name = "Population", range = c(1, 10)) + + geom_point(aes(size = POPESTIMATE2019), color = ggplot_colors[2], + alpha = 0.5) + + scale_size(name = "Population", range = c(1, 10)) + geom_text(alpha = 0.5) + - labs(x = "% CLI-in-community from Google surveys", + labs(x = "% CLI-in-community from Google surveys", y = "Daily new confirmed COVID-19 cases per 100,000 people", title = "COVID-19 case rates vs Google % CLI-in-community", subtitle = subtitle) + theme_bw() + theme(legend.position = "bottom") -p2 = ggplot(df2, aes(x = x, y = y, label = toupper(geo_value))) + +p2 = ggplot(df2, aes(x = x, y = y, label = toupper(geo_value))) + geom_smooth(method = "lm", col = ggplot_colors[1], se = FALSE) + - geom_point(aes(size = POPESTIMATE2019), color = ggplot_colors[1], - alpha = 0.5) + - scale_size(name = "Population", range = c(1, 10)) + + geom_point(aes(size = POPESTIMATE2019), color = ggplot_colors[1], + alpha = 0.5) + + scale_size(name = "Population", range = c(1, 10)) + geom_text(alpha = 0.5) + labs(x = "% CLI-in-community from Facebook surveys", y = "", title = "COVID-19 case rates vs Facebook % CLI-in-community", subtitle = subtitle) + theme_bw() + theme(legend.position = "bottom") grid.arrange(p1, p2, nrow = 1) -

+

In both plots, we see a reassuring trend, but the trend on the left is noticeably stronger. Indeed, the correlation here between the Google signal and case rates is @@ -261,7 +264,7 @@

Our Two Surveys

start_day = min(df_go$time_value) end_day = "2020-09-01" -df_fb = covidcast_signal("fb-survey", "smoothed_hh_cmnty_cli", +df_fb = covidcast_signal("fb-survey", "smoothed_hh_cmnty_cli", start_day, end_day) df_in = covidcast_signal("jhu-csse", "confirmed_7dav_incidence_prop", start_day, end_day) @@ -293,7 +296,7 @@

Our Two Surveys

scale_color_manual(values = ggplot_colors) + labs(title = "Correlation between survey signals and case rates", subtitle = sprintf("Over all counties with at least %i cumulative cases", - case_num), + case_num), x = "Date", y = "Correlation") + theme_bw() + theme(legend.pos = "bottom", legend.title = element_blank())

diff --git a/content/blog/2020-09-21-forecast-demo.Rmd b/content/blog/2020-09-21-forecast-demo.Rmd index fbc0cf695..e360aa9e3 100644 --- a/content/blog/2020-09-21-forecast-demo.Rmd +++ b/content/blog/2020-09-21-forecast-demo.Rmd @@ -1,10 +1,14 @@ --- -title: "Can Symptoms Surveys Improve COVID-19 Forecasts?" -author: "Ryan Tibshirani" +title: Can Symptoms Surveys Improve COVID-19 Forecasts? +author: Ryan Tibshirani date: 2020-09-21 -tags: ["symptom surveys", "forecasting", "COVIDcast", "R"] +tags: + - symptom surveys + - forecasting + - COVIDcast + - R authors: -- ryan + - ryan heroImage: /blog/images/blog-Lg-img_can symptoms surveys improve covid-19.png heroImageThumb: /blog/images/blog-thumbnail_can symptoms surveys improve covid-19.png summary: | @@ -14,14 +18,14 @@ summary: | % CLI-in-community indicators from our two surveys can be used to improve the accuracy of short-term forecasts of county-level COVID-19 case rates. acknowledgements: | - *Delphi's forecasting effort involves many people from our + Delphi's forecasting effort involves many people from our modeling team, from forecaster design, to implementation, to evaluation. The broader insights on forecasting shared in this post certainly cannot be attributable to Ryan's work alone, and are a reflection of the work carried out - by all these team members.* + by all these team members. related: -- 2020-09-18-google-survey -- 2020-08-26-fb-survey + - 2020-09-18-google-survey + - 2020-08-26-fb-survey output: html_document: code_folding: hide @@ -46,179 +50,189 @@ the surveys, examining whether the % CLI-in-community indicators from our two surveys can be used to improve the accuracy of short-term forecasts of county-level COVID-19 case rates. -**Forecasting** has long been a primary initiative of the Delphi research -group (in the past for flu, and currently for COVID-19). -Each week since mid-July we've been submitting forecasts -to the [COVID Forecast Hub](https://covid19forecasthub.org), -which serves as the official data source for the -[CDC's communications on COVID-19 +**Forecasting** has long been a primary initiative of the Delphi research +group (in the past for flu, and currently for COVID-19). +Each week since mid-July we've been submitting forecasts +to the [COVID Forecast Hub](https://covid19forecasthub.org), +which serves as the official data source for the +[CDC's communications on COVID-19 forecasts](https://www.cdc.gov/coronavirus/2019-ncov/covid-data/mathematical-modeling.html). -At the outset, we should state that this post is neither a report on Delphi's -current COVID-19 forecasters nor an authoritative take on cutting-edge -COVID-19 forecasting. Instead, our purpose here to study the Facebook and -Google % CLI-in-community signals, and demonstrate their value, when used as -features, to add predictive power beyond what we can achieve with (fairly -simple) time series models trained on case rates alone. In a future blog post, -we'll follow up with details on our "production" forecasters. +At the outset, we should state that this post is neither a report on Delphi's +current COVID-19 forecasters nor an authoritative take on cutting-edge +COVID-19 forecasting. Instead, our purpose here is to study the Facebook and +Google % CLI-in-community signals, and demonstrate their value, when used as +features, to add predictive power beyond what we can achieve with (fairly +simple) time series models trained on case rates alone. In a future blog post, +we'll follow up with details on our "production" forecasters. -While we focus here on forecasting, there are a number of other important +While we focus here on forecasting, there are a number of other important prediction problems that arise as part of the pandemic response. For example, we also work on **hotspot detection**, where the goal is to predict whether case rates will rise significantly, rather than to predict the future case rates directly, as in forecasting. To motivate why we might be optimistic about the utility of incorporating -our survey signals into forecasting or hotspot detection models, you can +our survey signals into forecasting or hotspot detection models, you can check out our [previous exploratory -investigations](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#some-interesting-examples")`), -which suggested that they can serve as **early indicators** of COVID-19 +investigations](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#some-interesting-examples")`), +which suggested that they can serve as **early indicators** of COVID-19 activity. Stay tuned to the Delphi blog for a post on hotspot detection soon. Next we explain the forecasting setup and results in detail. -Some parts may get a bit technical, but we've tried to make the post -accessible enough that you can catch the main points +Some parts may get a bit technical, but we've tried to make the post +accessible enough that you can catch the main points even if you skip the technical details. -## Problem Setup +## Problem Setup Formally, our goal here is to predict county-level COVID-19 case incidence rates, 1 and 2 weeks ahead. -Specifically, we wish to predict the number of new COVID-19 cases per capita, -both over the next 1-7 days and over the next 8-14 days. -One convenient (and equivalent) way to phrase this problem -is to predict the *smoothed* COVID-19 case incidence rate 7 days ahead and +Specifically, we wish to predict the number of new COVID-19 cases per capita, +both over the next 1-7 days and over the next 8-14 days. +One convenient (and equivalent) way to phrase this problem +is to predict the _smoothed_ COVID-19 case incidence rate 7 days ahead and 14 days ahead, where the smoothing is performed via a 7-day trailing average. -We restrict our attention to the 440 counties -that had at least 200 confirmed cases by May 14, 2020 -(the end of the Google survey data) and in which -both the Facebook and Google % CLI-in-community signals are available -(there were 604 counties in total with at least 200 confirmed cases by May 14, +We restrict our attention to the 440 counties +that had at least 200 confirmed cases by May 14, 2020 +(the end of the Google survey data) and in which +both the Facebook and Google % CLI-in-community signals are available +(there were 604 counties in total with at least 200 confirmed cases by May 14, and we dropped 164 of them due to a lack of Facebook or Google survey data). -To fix notation, let $Y_{\ell,t}$ denote the smoothed COVID-19 case -incidence rate for location (county) $\ell$ and time (day) $t$. -Let $F_{\ell,t}$ and $G_{\ell,t}$ denote -the Facebook and Google % CLI-in-community signals, respectively, -for location $\ell$ and time $t$. -(We rescale all these signals from their given values in our API -so that they are true proportions: between 0 and 1.) +To fix notation, let $Y_{\ell,t}$ denote the smoothed COVID-19 case +incidence rate for location (county) $\ell$ and time (day) $t$. +Let $F_{\ell,t}$ and $G_{\ell,t}$ denote +the Facebook and Google % CLI-in-community signals, respectively, +for location $\ell$ and time $t$. +(We rescale all these signals from their given values in our API +so that they are true proportions: between 0 and 1.) We evaluate the following four models: + $$ \begin{aligned} -&\text{Cases:} \quad && h(Y_{\ell,t+d}) +&\text{Cases:} \\ +& h(Y_{\ell,t+d}) \approx \alpha + \sum_{j=0}^2 \beta_j h(Y_{\ell,t-7j}) \\ -&\text{Cases + Facebook:} \quad && h(Y_{\ell,t+d}) +&\text{Cases + Facebook:} \\ +& h(Y_{\ell,t+d}) \approx \alpha + \sum_{j=0}^2 \beta_j h(Y_{\ell,t-7j}) + \sum_{j=0}^2 \gamma_j h(F_{\ell,t-7j}) \\ -&\text{Cases + Google:} \quad && h(Y_{\ell,t+d}) +&\text{Cases + Google:} \\ +& h(Y_{\ell,t+d}) \approx \alpha + \sum_{j=0}^2 \beta_j h(Y_{\ell,t-7j}) + \sum_{j=0}^2 \gamma_j h(G_{\ell,t-7j}) \\ -&\text{Cases + Facebook + Google:} \quad && h(Y_{\ell,t+d}) +&\text{Cases + Facebook + Google:} \\ +& h(Y_{\ell,t+d}) \approx \alpha + \sum_{j=0}^2 \beta_j h(Y_{\ell,t-7j}) + \sum_{j=0}^2 \gamma_j h(F_{\ell,t-7j}) + \sum_{j=0}^2 \tau_j h(G_{\ell,t-7j}). \end{aligned} $$ -Here $d=7$ or $d=14$, depending on the target value -(number of days we predict ahead), -and $h$ is a transformation to be specified later. + +Here $d=7$ or $d=14$, depending on the target value +(number of days we predict ahead), +and $h$ is a transformation to be specified later. Informally, the first model bases its predictions of future case rates on the following three features: current COVID-19 case rates, and those 1 and 2 weeks back. The second model additionally incorporates the current Facebook signal, and the Facebook signal from 1 and 2 weeks back. -The third model is exactly same but substitutes the Google signal +The third model is exactly same but substitutes the Google signal instead of the Facebook one. -Finally, the fourth model uses both Facebook and Google signals. -For each model, in order to make a forecast at time $t_0$ +Finally, the fourth model uses both Facebook and Google signals. +For each model, in order to make a forecast at time $t_0$ (to predict case rates at time $t_0+d$), -we fit a linear model using least absolute deviations (LAD) regression, -training over all locations $\ell$ (all 440 counties), -and all time $t$ that are within the most recent 14 days of data -available up to and including time $t_0$. +we fit a linear model using least absolute deviations (LAD) regression, +training over all locations $\ell$ (all 440 counties), +and all time $t$ that are within the most recent 14 days of data +available up to and including time $t_0$. -Forecasts are transformed back to the original scale -(we apply $h^{-1}$ to the predictions from the fitted LAD model), +Forecasts are transformed back to the original scale +(we apply $h^{-1}$ to the predictions from the fitted LAD model), and denoted $\hat{Y}_{\ell,t_0+d}$. -For an error metric, we consider **scaled absolute error** +For an error metric, we consider **scaled absolute error** (or just scaled error for short): + $$ \frac{|\hat{Y}_{\ell,t_0+d} - Y_{\ell,t_0+d}|} {|Y_{\ell,t_0} - Y_{\ell,t_0+d}|}, $$ + where the error in the denominator is the error of the "strawman" model, -which for any target always simply predicts the most recent available case rate. +which for any target always simply predicts the most recent available case rate. -This normalization helps for two reasons. -First, it gives us an interpretable scale, -as we can understand the scaled error as a fraction improvement -over the strawman's error (so numbers like 0.8 or 0.9 would be favorable, -and numbers like 2 or 5 or 10 would be increasingly disastrous). +This normalization helps for two reasons. +First, it gives us an interpretable scale, +as we can understand the scaled error as a fraction improvement +over the strawman's error (so numbers like 0.8 or 0.9 would be favorable, +and numbers like 2 or 5 or 10 would be increasingly disastrous). Second, in our forecasting problem, -there turns out to a considerable amount of county-to-county variability +there turns out to a considerable amount of county-to-county variability in forecasting difficulty, and normalizing by the strawman's error helps adjust for this (so that the aggregate results aren't dominated by county-to-county differences). ## Transformations -We investigated three transformations $h$: identity, log, and logit (the -latter two being common variance-stabilizing transforms for proportions). -The results in all three cases were quite similar -and the qualitative conclusions don't change at all -(the code below supports all three, so you can check this for yourself). -For brevity, we'll just show the results for the logit transform -(actually, a "padded" version $h(x) = \log\left(\frac{x+a}{1-x+a}\right)$, -where the numerator and denominator are pushed away from zero -by a small constant, which we took to be $a=0.01$). +We investigated three transformations $h$: identity, log, and logit (the +latter two being common variance-stabilizing transforms for proportions). +The results in all three cases were quite similar +and the qualitative conclusions don't change at all +(the code below supports all three, so you can check this for yourself). +For brevity, we'll just show the results for the logit transform +(actually, a "padded" version $h(x) = \log\left(\frac{x+a}{1-x+a}\right)$, +where the numerator and denominator are pushed away from zero +by a small constant, which we took to be $a=0.01$). ## Forecasting Code -The code below marches the forecast date $t_0$ forward, -one day at a time (from April 11 to September 1), fits the four models, -makes predictions 7 and 14 days ahead, and records errors. -It takes a little while to run[^1], the culprit being LAD regression: -the training sets in our forecasting problem get moderately large -(aggregating the data over 440 counties and 14 days results in over 6000 -training samples), and at this scale LAD regression is much slower than least -squares regression. We ran this R code separately and saved the results in an -RData file; you can find this in the [same GitHub -repo](https://github.com/cmu-delphi/delphi-blog/tree/main/content/post) +The code below marches the forecast date $t_0$ forward, +one day at a time (from April 11 to September 1), fits the four models, +makes predictions 7 and 14 days ahead, and records errors. +It takes a little while to run[^1], the culprit being LAD regression: +the training sets in our forecasting problem get moderately large +(aggregating the data over 440 counties and 14 days results in over 6000 +training samples), and at this scale LAD regression is much slower than least +squares regression. We ran this R code separately and saved the results in an +RData file; you can find this in the [same GitHub +repo](https://github.com/cmu-delphi/delphi-blog/tree/main/content/post) as the Rmd source for this blog post. -[^1]: The R package [quantgen](https://github.com/ryantibs/quantgen) allows you -to choose between Gurobi or GLPK as the underlying LP solver. The default is -GLPK, since it's open source; but if you can use Gurobi (which is [free for -academic use](https://www.gurobi.com/academia/academic-program-and-licenses/)), -then this forecast demo will run much faster. +[^1]: + The R package [quantgen](https://github.com/ryantibs/quantgen) allows you + to choose between Gurobi or GLPK as the underlying LP solver. The default is + GLPK, since it's open source; but if you can use Gurobi (which is [free for + academic use](https://www.gurobi.com/academia/academic-program-and-licenses/)), + then this forecast demo will run much faster. ```{r, eval = FALSE, code = readLines("forecast-demo/demo.R")} + ``` ## Results: All Four Models -We first compare the results across all four models. -For this analysis, we filter down to common forecast dates -available for the four models (to set an even footing for the comparison), -which ends up being May 6 through May 14 for 7-day-ahead forecasts, -and only May 13 through May 14 for 14-day-ahead forecasts. -(The reason for this shortened period: +We first compare the results across all four models. +For this analysis, we filter down to common forecast dates +available for the four models (to set an even footing for the comparison), +which ends up being May 6 through May 14 for 7-day-ahead forecasts, +and only May 13 through May 14 for 14-day-ahead forecasts. +(The reason for this shortened period: we paused running the Google survey on May 14 so its data ends there, but as we explained in our last post, we [plan to bring it -back](`r blogdown::shortcode("ref", "2020-09-18-google-survey#google-survey-redux")`) -later this fall.) Hence we skip studying the 14-day-ahead forecasts results +back](`r blogdown::shortcode("ref", "2020-09-18-google-survey#google-survey-redux")`) +later this fall.) Hence we skip studying the 14-day-ahead forecasts results in this four-way model discussion, as they're only based on 2 days of test data. -Below we compute and print the median scaled errors for each of the four models -over the 9-day test period (recall that the scaled error is the absolute error -of the model's forecast relative to that of the strawman; and each test day -actually comprises 440 forecasts, over the 440 counties being considered). -We can see that adding either or both of the survey signals +Below we compute and print the median scaled errors for each of the four models +over the 9-day test period (recall that the scaled error is the absolute error +of the model's forecast relative to that of the strawman; and each test day +actually comprises 440 forecasts, over the 440 counties being considered). +We can see that adding either or both of the survey signals improves on the median scaled error of the model that uses cases only, with the biggest gain achieved by the "Cases + Google" model. -We can also see that the median scaled errors are all close to 1 +We can also see that the median scaled errors are all close to 1 (with all but that from "Cases + Google" model exceeding 1), which speaks to the difficulty of the forecasting problem. @@ -231,7 +245,7 @@ library(ggplot2) model_names = c("Cases", "Cases + Facebook", "Cases + Google", "Cases + Facebook + Google") -# Restrict to common period for all 4 models, then calculate the scaled errors +# Restrict to common period for all 4 models, then calculate the scaled errors # for each model, that is, the error relative to the strawman's error res_all4 = res %>% drop_na() %>% # Restrict to common time @@ -240,48 +254,49 @@ res_all4 = res %>% mutate(dif12 = err1 - err2, dif13 = err1 - err3, # Compute differences dif14 = err1 - err4) %>% # relative to cases model ungroup() %>% - select(-err0) - + select(-err0) + # Calculate and print median errors, for all 4 models, and just 7 days ahead -res_err4 = res_all4 %>% +res_err4 = res_all4 %>% select(-starts_with("dif")) %>% pivot_longer(names_to = "model", values_to = "err", cols = -c(geo_value, time_value, lead)) %>% mutate(lead = factor(lead, labels = paste(leads, "days ahead")), model = factor(model, labels = model_names)) -knitr::kable(res_err4 %>% +knitr::kable(res_err4 %>% group_by(model, lead) %>% - summarize(err = median(err), n = length(unique(time_value))) %>% + summarize(err = median(err), n = length(unique(time_value))) %>% arrange(lead) %>% ungroup() %>% - rename("Model" = model, "Median scaled error" = err, + rename("Model" = model, "Median scaled error" = err, "Target" = lead, "Test days" = n) %>% - filter(Target == "7 days ahead"), + filter(Target == "7 days ahead"), caption = paste("Test period:", min(res_err4$time_value), "to", max(res_err4$time_value)), format = "html", table.attr = "style='width:70%;'") ``` -Are these differences in median scaled errors significant? -It's hard to say, but some basic hypothesis testing suggests -that they probably are: below we conduct a [sign -test](https://en.wikipedia.org/wiki/Sign_test)[^2] -for whether the difference in the "Cases" model's scaled error -and each other model's scaled error is centered at zero. -The sign test is run on the 9 test days x 440 counties = 3960 pairs +Are these differences in median scaled errors significant? +It's hard to say, but some basic hypothesis testing suggests +that they probably are: below we conduct a [sign +test](https://en.wikipedia.org/wiki/Sign_test)[^2] +for whether the difference in the "Cases" model's scaled error +and each other model's scaled error is centered at zero. +The sign test is run on the 9 test days x 440 counties = 3960 pairs of scaled errors. The p-values from the "Cases" versus "Cases + Facebook" and the "Cases" versus "Cases + Google" tests are tiny; -the p-value from the "Cases" versus "Cases + Facebook + Google" test -is much bigger but still below 0.01. - -[^2]: As far as nonparametric tests of medians go, [Wilcoxon's signed-rank -test](https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) -(for paired data, as we have here) is more popular, -because it tends to be more powerful than the sign test. -Applied here, it does indeed give smaller p-values pretty much across the board. -However, it assumes symmetry of the distribution in question -(in our case, the difference in scaled errors), -whereas the sign test does not, and thus we show results from the latter. +the p-value from the "Cases" versus "Cases + Facebook + Google" test +is much bigger but still below 0.01. + +[^2]: + As far as nonparametric tests of medians go, [Wilcoxon's signed-rank + test](https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) + (for paired data, as we have here) is more popular, + because it tends to be more powerful than the sign test. + Applied here, it does indeed give smaller p-values pretty much across the board. + However, it assumes symmetry of the distribution in question + (in our case, the difference in scaled errors), + whereas the sign test does not, and thus we show results from the latter. ```{r, message = FALSE, warning = FALSE} # Compute p-values using the sign test against a one-sided alternative, for @@ -291,46 +306,46 @@ res_dif4 = res_all4 %>% pivot_longer(names_to = "model", values_to = "dif", cols = -c(geo_value, time_value, lead)) %>% mutate(lead = factor(lead, labels = paste(leads, "days ahead")), - model = factor(model, + model = factor(model, labels = c("Cases vs Cases + Facebook", "Cases vs Cases + Google", - "Cases vs Cases + Facebook + Google"))) + "Cases vs Cases + Facebook + Google"))) knitr::kable(res_dif4 %>% group_by(model, lead) %>% - summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), + summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), n = n(), alt = "greater")$p.val) %>% ungroup() %>% filter(lead == "7 days ahead") %>% - rename("Comparison" = model, "Target" = lead, "P-value" = p), + rename("Comparison" = model, "Target" = lead, "P-value" = p), format = "html", table.attr = "style='width:50%;'") ``` -We should read these with a grain of salt: the sign test here assumes -independence of observations, which clearly can't be true, -given the spatiotemporal structure of our forecasting problem. -To mitigate the dependence across time -(which intuitively seems to matter more than that across space), -we recomputed these tests in a stratified way, -where for each day we run a sign test on the scaled errors -between two models over all 440 counties. -The results are plotted as histograms below; -the "Cases + Facebook" and "Cases + Google" models -appear to deliver some decently small p-values, -but the story is not as clear with the "Cases + Facebook + Google" model. - -```{r, message = FALSE, warning = FALSE, fig.width = 9, fig.height = 3.5} +We should read these with a grain of salt: the sign test here assumes +independence of observations, which clearly can't be true, +given the spatiotemporal structure of our forecasting problem. +To mitigate the dependence across time +(which intuitively seems to matter more than that across space), +we recomputed these tests in a stratified way, +where for each day we run a sign test on the scaled errors +between two models over all 440 counties. +The results are plotted as histograms below; +the "Cases + Facebook" and "Cases + Google" models +appear to deliver some decently small p-values, +but the story is not as clear with the "Cases + Facebook + Google" model. + +```{r, message = FALSE, warning = FALSE, fig.width = 9, fig.height = 3.5, out.extra = 'class="wide-figure"'} # Red, blue (similar to ggplot defaults), then yellow ggplot_colors = c("#FC4E07", "#00AFBB", "#E7B800") -ggplot(res_dif4 %>% +ggplot(res_dif4 %>% group_by(model, lead, time_value) %>% - summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), + summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), n = n(), alt = "greater")$p.val) %>% ungroup() %>% filter(lead == "7 days ahead"), aes(p)) + - geom_histogram(aes(color = model, fill = model), alpha = 0.4) + + geom_histogram(aes(color = model, fill = model), alpha = 0.4) + scale_color_manual(values = ggplot_colors) + scale_fill_manual(values = ggplot_colors) + - facet_wrap(vars(lead, model)) + + facet_wrap(vars(lead, model)) + labs(x = "P-value", y = "Count") + theme_bw() + theme(legend.pos = "none") ``` @@ -338,16 +353,16 @@ ggplot(res_dif4 %>% ## Results: First Two Models Next we focus on comparing results between the "Cases" and "Cases + Facebook" -models only. Restricting to a common available forecast dates yields a much -longer test period, May 6 through August 25 for 7-day-ahead forecasts, -and May 13 through August 18 for 14-day-ahead forecasts. -The median scaled errors over the test period are computed and reported below. -Now we see a decent improvement in median scaled error for the -"Cases + Facebook" model, and this is true for both 7-day-ahead and +models only. Restricting to a common available forecast dates yields a much +longer test period, May 6 through August 25 for 7-day-ahead forecasts, +and May 13 through August 18 for 14-day-ahead forecasts. +The median scaled errors over the test period are computed and reported below. +Now we see a decent improvement in median scaled error for the +"Cases + Facebook" model, and this is true for both 7-day-ahead and 14-day-ahead forecasts. ```{r, message = FALSE, warning = FALSE} -# Restrict to common period for just models 1 and 2, then calculate the scaled +# Restrict to common period for just models 1 and 2, then calculate the scaled # errors, that is, the error relative to the strawman's error res_all2 = res %>% select(-c(err3, err4)) %>% @@ -357,72 +372,72 @@ res_all2 = res %>% mutate(dif12 = err1 - err2) %>% # Compute differences # relative to cases model ungroup() %>% - select(-err0) - -# Calculate and print median errors, for just models 1 and 2, and both 7 and 14 + select(-err0) + +# Calculate and print median errors, for just models 1 and 2, and both 7 and 14 # days ahead -res_err2 = res_all2 %>% +res_err2 = res_all2 %>% select(-starts_with("dif")) %>% pivot_longer(names_to = "model", values_to = "err", cols = -c(geo_value, time_value, lead)) %>% mutate(lead = factor(lead, labels = paste(leads, "days ahead")), model = factor(model, labels = model_names[1:2])) - -knitr::kable(res_err2 %>% + +knitr::kable(res_err2 %>% select(-starts_with("dif")) %>% group_by(model, lead) %>% - summarize(err = median(err), n = length(unique(time_value))) %>% + summarize(err = median(err), n = length(unique(time_value))) %>% arrange(lead) %>% ungroup() %>% - rename("Model" = model, "Median scaled error" = err, + rename("Model" = model, "Median scaled error" = err, "Target" = lead, "Test days" = n), caption = paste("Test period:", min(res_err2$time_value), "to", max(res_err2$time_value)), format = "html", table.attr = "style='width:70%;'") ``` -Thanks to the extended length of the test period, -we can also "unravel" these median scaled errors +Thanks to the extended length of the test period, +we can also "unravel" these median scaled errors over time and plot their trajectories, as we do below, -with the left plot concerning 7-day-ahead forecasts, -and the right 14-day-ahead forecasts. -These plots reveal something at once interesting and bothersome: -the median scaled errors are quite volatile over time, -and for some periods in July, forecasting became much "harder", -with the scaled errors reaching above 1.25 for 7-day-ahead forecasts, -and above 1.5 for 14-day-ahead forecasts. -Furthermore, towards the positive, we can see a clear visual -difference between the median scaled errors from -the "Cases + Facebook" model in red and the "Cases" model in black. +with the left plot concerning 7-day-ahead forecasts, +and the right 14-day-ahead forecasts. +These plots reveal something at once interesting and bothersome: +the median scaled errors are quite volatile over time, +and for some periods in July, forecasting became much "harder", +with the scaled errors reaching above 1.25 for 7-day-ahead forecasts, +and above 1.5 for 14-day-ahead forecasts. +Furthermore, towards the positive, we can see a clear visual +difference between the median scaled errors from +the "Cases + Facebook" model in red and the "Cases" model in black. The former appears to be below the latter pretty consistently over time, -with the possible exception of periods where forecasting -becomes "hard" and the scaled errors shoot above 1. +with the possible exception of periods where forecasting +becomes "hard" and the scaled errors shoot above 1. -```{r, message = FALSE, warning = FALSE, fig.width = 9, fig.height = 5} +```{r, message = FALSE, warning = FALSE, fig.width = 9, fig.height = 5, out.extra = 'class="wide-figure"'} # Plot median errors as a function of time, for models 1 and 2, and both 7 and # 14 days ahead -ggplot(res_err2 %>% +ggplot(res_err2 %>% group_by(model, lead, time_value) %>% summarize(err = median(err)) %>% ungroup(), - aes(x = time_value, y = err)) + - geom_line(aes(color = model)) + + aes(x = time_value, y = err)) + + geom_line(aes(color = model)) + scale_color_manual(values = c("black", ggplot_colors)) + geom_hline(yintercept = 1, linetype = 2, color = "gray") + - facet_wrap(vars(lead)) + + facet_wrap(vars(lead)) + labs(x = "Date", y = "Median scaled error") + theme_bw() + theme(legend.pos = "bottom", legend.title = element_blank()) ``` -Again, basic hypothesis testing suggests that the results we're seeing here -are likely significant, though it's hard to say definitively -given the complicated dependence structure present in the data. -Below we perform a sign test for whether the difference in scaled errors -from the "Cases" and "Cases + Facebook" models is centered at zero. -Given the large sample size: 112 test days for 7-day-ahead forecasts -and 98 test days for 14-day-ahead forecasts -(times 440 counties for each day), the p-values are basically zero. +Again, basic hypothesis testing suggests that the results we're seeing here +are likely significant, though it's hard to say definitively +given the complicated dependence structure present in the data. +Below we perform a sign test for whether the difference in scaled errors +from the "Cases" and "Cases + Facebook" models is centered at zero. +Given the large sample size: 112 test days for 7-day-ahead forecasts +and 98 test days for 14-day-ahead forecasts +(times 440 counties for each day), the p-values are basically zero. ```{r, message = FALSE, warning = FALSE} -# Compute p-values using the sign test against a one-sided alternative, just +# Compute p-values using the sign test against a one-sided alternative, just # for models 1 and 2, and both 7 and 14 days ahead res_dif2 = res_all2 %>% select(-starts_with("err")) %>% @@ -431,75 +446,73 @@ res_dif2 = res_all2 %>% mutate(lead = factor(lead, labels = paste(leads, "days ahead")), model = factor(model, labels = "Cases > Cases + Facebook")) -knitr::kable(res_dif2 %>% +knitr::kable(res_dif2 %>% group_by(model, lead) %>% summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), - n = n(), alt = "greater")$p.val) %>% - ungroup() %>% - rename("Comparison" = model, "Target" = lead, "P-value" = p), + n = n(), alt = "greater")$p.val) %>% + ungroup() %>% + rename("Comparison" = model, "Target" = lead, "P-value" = p), format = "html", table.attr = "style='width:50%;'") ``` -Once we stratify and recompute p-values by forecast date, -as shown in the histograms below, +Once we stratify and recompute p-values by forecast date, +as shown in the histograms below, the bulk of p-values are still quite small. ```{r, message = FALSE, warning = FALSE, fig.width = 7, fig.height = 4} -ggplot(res_dif2 %>% +ggplot(res_dif2 %>% group_by(model, lead, time_value) %>% - summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), + summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), n = n(), alt = "greater")$p.val) %>% ungroup(), aes(p)) + - geom_histogram(aes(color = model, fill = model), alpha = 0.4) + + geom_histogram(aes(color = model, fill = model), alpha = 0.4) + scale_color_manual(values = ggplot_colors) + scale_fill_manual(values = ggplot_colors) + - facet_wrap(vars(lead, model)) + + facet_wrap(vars(lead, model)) + labs(x = "P-value", y = "Count") + theme_bw() + theme(legend.pos = "none") ``` -## Varying the Number of Days Ahead\* +## Varying the Number of Days Ahead -**[\*Added September 25, 2020]** - -Hypothesis tests (like the sign tests conducted above) tell us -whether the differences in errors +Hypothesis tests (like the sign tests conducted above) tell us +whether the differences in errors (between the forecasters) -are *statistically* significant, -but not about their *practical* significance. -For example, for 7-day-ahead forecasts, +are _statistically_ significant, +but not about their _practical_ significance. +For example, for 7-day-ahead forecasts, what does an improvement of 0.018 units on the scaled error scale really mean, -when comparing the "Cases + Facebook" model to the "Cases" model -(over the test period May 6 through August 25)? -Is this a meaningful gain? - -To answer questions like this, -we can look at the way that the median scaled errors -behave as a function of the number of days ahead -at which we're making the forecasts. -Previously, we considered forecasting case rates -just 7 and 14 days ahead; -now we systematically examine 5, 6, 7, etc., through 20 days ahead. -As before, we ran the code for this separately -and saved the results in an RData file, -which you can find in the [same GitHub -repo](https://github.com/cmu-delphi/delphi-blog/tree/main/content/post) -as the Rmd source for this blog post. +when comparing the "Cases + Facebook" model to the "Cases" model +(over the test period May 6 through August 25)? +Is this a meaningful gain? + +To answer questions like this, +we can look at the way that the median scaled errors +behave as a function of the number of days ahead +at which we're making the forecasts. +Previously, we considered forecasting case rates +just 7 and 14 days ahead; +now we systematically examine 5, 6, 7, etc., through 20 days ahead. +As before, we ran the code for this separately +and saved the results in an RData file, +which you can find in the [same GitHub +repo](https://github.com/cmu-delphi/delphi-blog/tree/main/content/post) +as the Rmd source for this blog post. (It's exactly the same code as that above, -but with `leads = 5:20`.) +but with `leads = 5:20`.) -Below, we compute and plot the median scaled errors -for the "Cases" and "Cases + Facebook" models +Below, we compute and plot the median scaled errors +for the "Cases" and "Cases + Facebook" models for different number of days ahead for the forecast target. -This is done over all forecast dates common to the two models -(May 6 through August 27, or earlier---the end date gets decremented -each time we increase the number of days ahead). -A first glance shows that the "Cases + Facebook" model, -in red, gives better median scaled errors at all ahead values; -and the vertical gap between the two curves -is consistently in the range of what we were seeing before -(for 7 and 14 days ahead), -around 0.02 units or more on the scaled error scale. +This is done over all forecast dates common to the two models +(May 6 through August 27, or earlier---the end date gets decremented +each time we increase the number of days ahead). +A first glance shows that the "Cases + Facebook" model, +in red, gives better median scaled errors at all ahead values; +and the vertical gap between the two curves +is consistently in the range of what we were seeing before +(for 7 and 14 days ahead), +around 0.02 units or more on the scaled error scale. ```{r, message = FALSE, warning = FALSE, fig.width = 6, fig.height = 5} load("forecast-demo/demo-extended.rda") @@ -516,14 +529,14 @@ err_by_lead = res %>% cols = -c(geo_value, time_value, lead)) %>% mutate(model = factor(model, labels = model_names[1:2])) %>% group_by(model, lead) %>% - summarize(err = median(err)) %>% + summarize(err = median(err)) %>% ungroup() -ggplot(err_by_lead, aes(x = lead, y = err)) + - geom_line(aes(color = model)) + - geom_point(aes(color = model)) + +ggplot(err_by_lead, aes(x = lead, y = err)) + + geom_line(aes(color = model)) + + geom_point(aes(color = model)) + scale_color_manual(values = c("black", ggplot_colors)) + - geom_hline(yintercept = err_by_lead %>% + geom_hline(yintercept = err_by_lead %>% filter(lead %in% 7, model == "Cases") %>% pull(err), linetype = 2, color = "gray") + labs(title = "Forecasting errors by number of days ahead", @@ -533,92 +546,96 @@ ggplot(err_by_lead, aes(x = lead, y = err)) + theme_bw() + theme(legend.pos = "bottom", legend.title = element_blank()) ``` -But if we look at it from a different angle, -and consider the *horizontal* gap between the curves, -then we can infer something quite a bit more interesting: -for 7-day-ahead forecasts, -the median scaled error of the "Cases" model -(marked by a horizontal gray line) +But if we look at it from a different angle, +and consider the _horizontal_ gap between the curves, +then we can infer something quite a bit more interesting: +for 7-day-ahead forecasts, +the median scaled error of the "Cases" model +(marked by a horizontal gray line) is comparable to that of 12-day-ahead forecasts from the "Cases + Facebook" -model. So you could say that using the % CLI-in-community signal from our -Facebook survey buys us *5 extra days of lead time* for this forecasting -problem, which seems pretty nontrivial. -Different forecast targets yield different lead times -(for 14-day-ahead forecasts, for example, it appears -to be more like 3 or 4 days of lead time), +model. So you could say that using the % CLI-in-community signal from our +Facebook survey buys us _5 extra days of lead time_ for this forecasting +problem, which seems pretty nontrivial. +Different forecast targets yield different lead times +(for 14-day-ahead forecasts, for example, it appears +to be more like 3 or 4 days of lead time), but the added value of the survey signal is clear throughout. - + ## Wrap-Up -We've seen that either of the Facebook or Google % CLI-in-community -signals can improve the accuracy of short-term forecasts -of county-level COVID-19 case incidence rates. -The significance of these improvements +We've seen that either of the Facebook or Google % CLI-in-community +signals can improve the accuracy of short-term forecasts +of county-level COVID-19 case incidence rates. +The significance of these improvements is more apparent with the Facebook signal, thanks -to the much longer test period available. -With either signal, of the magnitude of the improvement offered -seems modest but nontrivial, especially because the forecasting problem +to the much longer test period available. +With either signal, of the magnitude of the improvement offered +seems modest but nontrivial, especially because the forecasting problem is so hard in the first place. We reiterate that this was just a demo. Our analysis was fairly simple and lacks -a few qualities that we'd expect in a truly comprehensive, realistic forecasting -analysis. To name three: - -1. The models we considered are simple autoregressive structures from standard -time series, and could be improved in various ways (including, considering other -relevant dimensions like mobility measures, county health metrics, etc.). - -2. The forecasts we produced are *point* rather than *distributional* forecasts -(that is, we predict a single number, rather than an entire distribution, for -what happens 7 and 14 days ahead). Distributional forecasts portray uncertainty -in a transparent way, which is important in practice. - -3. The way we trained our forecast models does not account -for *data latency* and *revisions*, which are critical issues. -For each (retrospective) forecast date $t_0$, -we constructed forecasts by training on data -that we fetched from the API today, "as of" the day we wrote this blog post, -and not "as of" the forecast date $t_0$. -This matters because nearly all signals are subject to latency -(they are only available at some number of days lag) -and go through multiple revisions (past data values get updated as time -goes on). +a few qualities that we'd expect in a truly comprehensive, realistic forecasting +analysis. To name three: + +1. The models we considered are simple autoregressive structures from standard + time series, and could be improved in various ways (including, considering other + relevant dimensions like mobility measures, county health metrics, etc.). + +2. The forecasts we produced are _point_ rather than _distributional_ forecasts + (that is, we predict a single number, rather than an entire distribution, for + what happens 7 and 14 days ahead). Distributional forecasts portray uncertainty + in a transparent way, which is important in practice. + +3. The way we trained our forecast models does not account + for _data latency_ and _revisions_, which are critical issues. + For each (retrospective) forecast date $t_0$, + we constructed forecasts by training on data + that we fetched from the API today, "as of" the day we wrote this blog post, + and not "as of" the forecast date $t_0$. + This matters because nearly all signals are subject to latency + (they are only available at some number of days lag) + and go through multiple revisions (past data values get updated as time + goes on). On the flip side, our example here was not that "far away" from being realistic. The models we examined are actually not too different from Delphi's forecasters -"in production".[^3] Also, the way we fit LAD regression models in the code -extends immediately to multiple quantile regression +"in production".[^3] Also, the way we fit LAD regression models in the code +extends immediately to multiple quantile regression (just requires changing the parameter `tau` in the call to `quantile_lasso()`), -which would give us distributional forecasts. -And lastly, it's fairly easy to change the data acquisition step in the code +which would give us distributional forecasts. +And lastly, it's fairly easy to change the data acquisition step in the code so that data gets pulled "as of" the forecast date (requires specifying the parameter `as_of` in the call to `covidcast_signal()`). -Hopefully these preliminary findings have gotten you excited -about the possible uses of our symptom survey data. +Hopefully these preliminary findings have gotten you excited +about the possible uses of our symptom survey data. To get started playing with our data yourself, take a look at our [interactive COVIDcast map](`r blogdown::shortcode_html("ref", "covidcast")`), -or our [COVIDcast +or our [COVIDcast API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`), -through our [R client](https://cmu-delphi.github.io/covidcast/covidcastR/) +through our [R client](https://cmu-delphi.github.io/covidcast/covidcastR/) or [Python client](https://cmu-delphi.github.io/covidcast/covidcast-py/html/). -And if you're feeling adventurous, consider competing in the +And if you're feeling adventurous, consider competing in the [COVID-19 Symptom Data Challenge](https://www.symptomchallenge.org/), -and trying your hand at developing novel analytic approaches to extract +and trying your hand at developing novel analytic approaches to extract insights from our Facebook symptom survey data. We've made extensive data aggregate data from our survey (beyond CLI indicators) [available for the Challenge](https://www.symptomchallenge.org/challenge#sources), and submissions are due September 29, with finalists eligible for cash prizes. We look forward to seeing how you put our data to use! -[^3]: Delphi's "production" forecasters are still based on relatively simple -times series models, though to be clear they're distributional, -and we add a couple of extra layers of complexity on top of standard structures. -For short-term forecasts, we've found that simple statistical models can be -competitive with compartmental models (like -[SIR](https://en.wikipedia.org/wiki/Compartmental_models_in_epidemiology#The_SIR_model) -and its [many -variants](https://en.wikipedia.org/wiki/Compartmental_models_in_epidemiology#Variations_on_the_basic_SIR_model)), -even fairly complicated ones. Being statisticians and computer scientists, we -find these statistical models are easier to build, debug, and most importantly, -calibrate. More on this in a future blog post. +[^3]: + Delphi's "production" forecasters are still based on relatively simple + times series models, though to be clear they're distributional, + and we add a couple of extra layers of complexity on top of standard structures. + For short-term forecasts, we've found that simple statistical models can be + competitive with compartmental models (like + [SIR](https://en.wikipedia.org/wiki/Compartmental_models_in_epidemiology#The_SIR_model) + and its [many + variants](https://en.wikipedia.org/wiki/Compartmental_models_in_epidemiology#Variations_on_the_basic_SIR_model)), + even fairly complicated ones. Being statisticians and computer scientists, we + find these statistical models are easier to build, debug, and most importantly, + calibrate. More on this in a future blog post. + +**Note:** *This post was updated on September 25, 2020 to include the section + [Varying the Number of Days Ahead](#varying-the-number-of-days-ahead).* \ No newline at end of file diff --git a/content/blog/2020-09-21-forecast-demo.html b/content/blog/2020-09-21-forecast-demo.html index 02643db58..defcebb63 100644 --- a/content/blog/2020-09-21-forecast-demo.html +++ b/content/blog/2020-09-21-forecast-demo.html @@ -1,10 +1,14 @@ --- -title: "Can Symptoms Surveys Improve COVID-19 Forecasts?" -author: "Ryan Tibshirani" +title: Can Symptoms Surveys Improve COVID-19 Forecasts? +author: Ryan Tibshirani date: 2020-09-21 -tags: ["symptom surveys", "forecasting", "COVIDcast", "R"] +tags: + - symptom surveys + - forecasting + - COVIDcast + - R authors: -- ryan + - ryan heroImage: /blog/images/blog-Lg-img_can symptoms surveys improve covid-19.png heroImageThumb: /blog/images/blog-thumbnail_can symptoms surveys improve covid-19.png summary: | @@ -14,14 +18,14 @@ % CLI-in-community indicators from our two surveys can be used to improve the accuracy of short-term forecasts of county-level COVID-19 case rates. acknowledgements: | - *Delphi's forecasting effort involves many people from our + Delphi's forecasting effort involves many people from our modeling team, from forecaster design, to implementation, to evaluation. The broader insights on forecasting shared in this post certainly cannot be attributable to Ryan's work alone, and are a reflection of the work carried out - by all these team members.* + by all these team members. related: -- 2020-09-18-google-survey -- 2020-08-26-fb-survey + - 2020-09-18-google-survey + - 2020-08-26-fb-survey output: html_document: code_folding: hide @@ -40,7 +44,7 @@
  • Forecasting Code
  • Results: All Four Models
  • Results: First Two Models
  • -
  • Varying the Number of Days Ahead*
  • +
  • Varying the Number of Days Ahead
  • Wrap-Up
  • @@ -70,7 +74,7 @@ forecasts.

    At the outset, we should state that this post is neither a report on Delphi’s current COVID-19 forecasters nor an authoritative take on cutting-edge -COVID-19 forecasting. Instead, our purpose here to study the Facebook and +COVID-19 forecasting. Instead, our purpose here is to study the Facebook and Google % CLI-in-community signals, and demonstrate their value, when used as features, to add predictive power beyond what we can achieve with (fairly simple) time series models trained on case rates alone. In a future blog post, @@ -113,24 +117,28 @@

    Problem Setup

    for location \(\ell\) and time \(t\). (We rescale all these signals from their given values in our API so that they are true proportions: between 0 and 1.) -We evaluate the following four models: -\[ +We evaluate the following four models:

    +

    \[ \begin{aligned} -&\text{Cases:} \quad && h(Y_{\ell,t+d}) +&\text{Cases:} \\ +& h(Y_{\ell,t+d}) \approx \alpha + \sum_{j=0}^2 \beta_j h(Y_{\ell,t-7j}) \\ -&\text{Cases + Facebook:} \quad && h(Y_{\ell,t+d}) +&\text{Cases + Facebook:} \\ +& h(Y_{\ell,t+d}) \approx \alpha + \sum_{j=0}^2 \beta_j h(Y_{\ell,t-7j}) + \sum_{j=0}^2 \gamma_j h(F_{\ell,t-7j}) \\ -&\text{Cases + Google:} \quad && h(Y_{\ell,t+d}) +&\text{Cases + Google:} \\ +& h(Y_{\ell,t+d}) \approx \alpha + \sum_{j=0}^2 \beta_j h(Y_{\ell,t-7j}) + \sum_{j=0}^2 \gamma_j h(G_{\ell,t-7j}) \\ -&\text{Cases + Facebook + Google:} \quad && h(Y_{\ell,t+d}) +&\text{Cases + Facebook + Google:} \\ +& h(Y_{\ell,t+d}) \approx \alpha + \sum_{j=0}^2 \beta_j h(Y_{\ell,t-7j}) + \sum_{j=0}^2 \gamma_j h(F_{\ell,t-7j}) + \sum_{j=0}^2 \tau_j h(G_{\ell,t-7j}). \end{aligned} -\] -Here \(d=7\) or \(d=14\), depending on the target value +\]

    +

    Here \(d=7\) or \(d=14\), depending on the target value (number of days we predict ahead), and \(h\) is a transformation to be specified later.

    Informally, the first model bases its predictions of future case rates @@ -151,12 +159,12 @@

    Problem Setup

    (we apply \(h^{-1}\) to the predictions from the fitted LAD model), and denoted \(\hat{Y}_{\ell,t_0+d}\). For an error metric, we consider scaled absolute error -(or just scaled error for short): -\[ +(or just scaled error for short):

    +

    \[ \frac{|\hat{Y}_{\ell,t_0+d} - Y_{\ell,t_0+d}|} {|Y_{\ell,t_0} - Y_{\ell,t_0+d}|}, -\] -where the error in the denominator is the error of the “strawman” model, +\]

    +

    where the error in the denominator is the error of the “strawman” model, which for any target always simply predicts the most recent available case rate.

    This normalization helps for two reasons. First, it gives us an interpretable scale, @@ -428,7 +436,7 @@

    Results: All Four Models

    model_names = c("Cases", "Cases + Facebook", "Cases + Google", "Cases + Facebook + Google") -# Restrict to common period for all 4 models, then calculate the scaled errors +# Restrict to common period for all 4 models, then calculate the scaled errors # for each model, that is, the error relative to the strawman's error res_all4 = res %>% drop_na() %>% # Restrict to common time @@ -437,23 +445,23 @@

    Results: All Four Models

    mutate(dif12 = err1 - err2, dif13 = err1 - err3, # Compute differences dif14 = err1 - err4) %>% # relative to cases model ungroup() %>% - select(-err0) - + select(-err0) + # Calculate and print median errors, for all 4 models, and just 7 days ahead -res_err4 = res_all4 %>% +res_err4 = res_all4 %>% select(-starts_with("dif")) %>% pivot_longer(names_to = "model", values_to = "err", cols = -c(geo_value, time_value, lead)) %>% mutate(lead = factor(lead, labels = paste(leads, "days ahead")), model = factor(model, labels = model_names)) -knitr::kable(res_err4 %>% +knitr::kable(res_err4 %>% group_by(model, lead) %>% - summarize(err = median(err), n = length(unique(time_value))) %>% + summarize(err = median(err), n = length(unique(time_value))) %>% arrange(lead) %>% ungroup() %>% - rename("Model" = model, "Median scaled error" = err, + rename("Model" = model, "Median scaled error" = err, "Target" = lead, "Test days" = n) %>% - filter(Target == "7 days ahead"), + filter(Target == "7 days ahead"), caption = paste("Test period:", min(res_err4$time_value), "to", max(res_err4$time_value)), format = "html", table.attr = "style='width:70%;'") @@ -554,17 +562,17 @@

    Results: All Four Models

    pivot_longer(names_to = "model", values_to = "dif", cols = -c(geo_value, time_value, lead)) %>% mutate(lead = factor(lead, labels = paste(leads, "days ahead")), - model = factor(model, + model = factor(model, labels = c("Cases vs Cases + Facebook", "Cases vs Cases + Google", - "Cases vs Cases + Facebook + Google"))) + "Cases vs Cases + Facebook + Google"))) knitr::kable(res_dif4 %>% group_by(model, lead) %>% - summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), + summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), n = n(), alt = "greater")$p.val) %>% ungroup() %>% filter(lead == "7 days ahead") %>% - rename("Comparison" = model, "Target" = lead, "P-value" = p), + rename("Comparison" = model, "Target" = lead, "P-value" = p), format = "html", table.attr = "style='width:50%;'") @@ -631,18 +639,18 @@

    Results: All Four Models

    # Red, blue (similar to ggplot defaults), then yellow
     ggplot_colors = c("#FC4E07", "#00AFBB", "#E7B800")
     
    -ggplot(res_dif4 %>% 
    +ggplot(res_dif4 %>%
              group_by(model, lead, time_value) %>%
    -         summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), 
    +         summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE),
                                       n = n(), alt = "greater")$p.val) %>%
              ungroup() %>% filter(lead == "7 days ahead"), aes(p)) +
    -  geom_histogram(aes(color = model, fill = model), alpha = 0.4) + 
    +  geom_histogram(aes(color = model, fill = model), alpha = 0.4) +
       scale_color_manual(values = ggplot_colors) +
       scale_fill_manual(values = ggplot_colors) +
    -  facet_wrap(vars(lead, model)) + 
    +  facet_wrap(vars(lead, model)) +
       labs(x = "P-value", y = "Count") +
       theme_bw() + theme(legend.pos = "none")
    -

    +

    Results: First Two Models

    @@ -654,7 +662,7 @@

    Results: First Two Models

    Now we see a decent improvement in median scaled error for the “Cases + Facebook” model, and this is true for both 7-day-ahead and 14-day-ahead forecasts.

    -
    # Restrict to common period for just models 1 and 2, then calculate the scaled 
    +
    # Restrict to common period for just models 1 and 2, then calculate the scaled
     # errors, that is, the error relative to the strawman's error
     res_all2 = res %>%
       select(-c(err3, err4)) %>%
    @@ -664,23 +672,23 @@ 

    Results: First Two Models

    mutate(dif12 = err1 - err2) %>% # Compute differences # relative to cases model ungroup() %>% - select(-err0) - -# Calculate and print median errors, for just models 1 and 2, and both 7 and 14 + select(-err0) + +# Calculate and print median errors, for just models 1 and 2, and both 7 and 14 # days ahead -res_err2 = res_all2 %>% +res_err2 = res_all2 %>% select(-starts_with("dif")) %>% pivot_longer(names_to = "model", values_to = "err", cols = -c(geo_value, time_value, lead)) %>% mutate(lead = factor(lead, labels = paste(leads, "days ahead")), model = factor(model, labels = model_names[1:2])) - -knitr::kable(res_err2 %>% + +knitr::kable(res_err2 %>% select(-starts_with("dif")) %>% group_by(model, lead) %>% - summarize(err = median(err), n = length(unique(time_value))) %>% + summarize(err = median(err), n = length(unique(time_value))) %>% arrange(lead) %>% ungroup() %>% - rename("Model" = model, "Median scaled error" = err, + rename("Model" = model, "Median scaled error" = err, "Target" = lead, "Test days" = n), caption = paste("Test period:", min(res_err2$time_value), "to", max(res_err2$time_value)), @@ -782,17 +790,17 @@

    Results: First Two Models

    becomes “hard” and the scaled errors shoot above 1.

    # Plot median errors as a function of time, for models 1 and 2, and both 7 and
     # 14 days ahead
    -ggplot(res_err2 %>% 
    +ggplot(res_err2 %>%
              group_by(model, lead, time_value) %>%
              summarize(err = median(err)) %>% ungroup(),
    -       aes(x = time_value, y = err)) + 
    -  geom_line(aes(color = model)) + 
    +       aes(x = time_value, y = err)) +
    +  geom_line(aes(color = model)) +
       scale_color_manual(values = c("black", ggplot_colors)) +
       geom_hline(yintercept = 1, linetype = 2, color = "gray") +
    -  facet_wrap(vars(lead)) + 
    +  facet_wrap(vars(lead)) +
       labs(x = "Date", y = "Median scaled error") +
       theme_bw() + theme(legend.pos = "bottom", legend.title = element_blank())
    -

    +

    Again, basic hypothesis testing suggests that the results we’re seeing here are likely significant, though it’s hard to say definitively given the complicated dependence structure present in the data. @@ -801,7 +809,7 @@

    Results: First Two Models

    Given the large sample size: 112 test days for 7-day-ahead forecasts and 98 test days for 14-day-ahead forecasts (times 440 counties for each day), the p-values are basically zero.

    -
    # Compute p-values using the sign test against a one-sided alternative, just 
    +
    # Compute p-values using the sign test against a one-sided alternative, just
     # for models 1 and 2, and both 7 and 14 days ahead
     res_dif2 = res_all2 %>%
       select(-starts_with("err")) %>%
    @@ -810,12 +818,12 @@ 

    Results: First Two Models

    mutate(lead = factor(lead, labels = paste(leads, "days ahead")), model = factor(model, labels = "Cases > Cases + Facebook")) -knitr::kable(res_dif2 %>% +knitr::kable(res_dif2 %>% group_by(model, lead) %>% summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), - n = n(), alt = "greater")$p.val) %>% - ungroup() %>% - rename("Comparison" = model, "Target" = lead, "P-value" = p), + n = n(), alt = "greater")$p.val) %>% + ungroup() %>% + rename("Comparison" = model, "Target" = lead, "P-value" = p), format = "html", table.attr = "style='width:50%;'")
    @@ -859,22 +867,21 @@

    Results: First Two Models

    Once we stratify and recompute p-values by forecast date, as shown in the histograms below, the bulk of p-values are still quite small.

    -
    ggplot(res_dif2 %>% 
    +
    ggplot(res_dif2 %>%
              group_by(model, lead, time_value) %>%
    -         summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE), 
    +         summarize(p = binom.test(x = sum(dif > 0, na.rm = TRUE),
                                       n = n(), alt = "greater")$p.val) %>%
              ungroup(), aes(p)) +
    -  geom_histogram(aes(color = model, fill = model), alpha = 0.4) + 
    +  geom_histogram(aes(color = model, fill = model), alpha = 0.4) +
       scale_color_manual(values = ggplot_colors) +
       scale_fill_manual(values = ggplot_colors) +
    -  facet_wrap(vars(lead, model)) + 
    +  facet_wrap(vars(lead, model)) +
       labs(x = "P-value", y = "Count") +
       theme_bw() + theme(legend.pos = "none")

    -

    Varying the Number of Days Ahead*

    -

    [*Added September 25, 2020]

    +

    Varying the Number of Days Ahead

    Hypothesis tests (like the sign tests conducted above) tell us whether the differences in errors (between the forecasters) @@ -925,14 +932,14 @@

    Varying the Number of Days Ahead*

    cols = -c(geo_value, time_value, lead)) %>% mutate(model = factor(model, labels = model_names[1:2])) %>% group_by(model, lead) %>% - summarize(err = median(err)) %>% + summarize(err = median(err)) %>% ungroup() -ggplot(err_by_lead, aes(x = lead, y = err)) + - geom_line(aes(color = model)) + - geom_point(aes(color = model)) + +ggplot(err_by_lead, aes(x = lead, y = err)) + + geom_line(aes(color = model)) + + geom_point(aes(color = model)) + scale_color_manual(values = c("black", ggplot_colors)) + - geom_hline(yintercept = err_by_lead %>% + geom_hline(yintercept = err_by_lead %>% filter(lead %in% 7, model == "Cases") %>% pull(err), linetype = 2, color = "gray") + labs(title = "Forecasting errors by number of days ahead", @@ -1014,6 +1021,8 @@

    Wrap-Up

    the Challenge, and submissions are due September 29, with finalists eligible for cash prizes. We look forward to seeing how you put our data to use!

    +

    Note: This post was updated on September 25, 2020 to include the section +Varying the Number of Days Ahead.


    diff --git a/content/blog/2020-10-06-survey-wave-4.Rmd b/content/blog/2020-10-06-survey-wave-4.Rmd index a072db9ef..4878617ec 100644 --- a/content/blog/2020-10-06-survey-wave-4.Rmd +++ b/content/blog/2020-10-06-survey-wave-4.Rmd @@ -1,17 +1,20 @@ --- -title: "New and Improved COVID Symptom Survey Tracks Testing and Mask-Wearing" -author: "Alex Reinhart" +title: New and Improved COVID Symptom Survey Tracks Testing and Mask-Wearing +author: Alex Reinhart date: 2020-10-12 -tags: ["symptom surveys", "COVIDcast", "R"] +tags: + - symptom surveys + - COVIDcast + - R summary: | Beginning on September 8, 2020, we deployed a new version of our symptom survey. Facebook helps us recruit tens of thousands of respondents daily, and the new survey gives us unprecedented insights into the effects of COVID-19 across the United States. Today we release new public datasets and share maps revealing access to COVID testing, test results, and public use of masks. authors: -- alex + - alex heroImage: /blog/images/blog-lg-img_New and Improved COVID.png heroImageThumb: /blog/images/blog-thumb-img_New and Improved COVID.png -acknowledgments: | +acknowledgements: | Many items in Wave 4 of our survey are based on work by the team at the Joint Program in Survey Methodology at the University of Maryland led by Frauke Kreuter; Adrianne Bradford and Samantha Chiu helped @@ -31,7 +34,7 @@ output: Beginning in early April 2020, the [Delphi group](`r blogdown::shortcode("ref", "/")`) has conducted a major survey to track COVID-19 across the United States. With the support of Facebook Data for Good, we have been able to recruit tens of -thousands of active Facebook users *every day* to take our voluntary survey. +thousands of active Facebook users _every day_ to take our voluntary survey. Concurrently, a University of Maryland team has conducted a [parallel international effort](https://covidmap.umd.edu/) covering over 100 countries worldwide. Every day, we aggregate our survey results to produce estimates of @@ -133,7 +136,7 @@ such as cough or difficulty breathing). This percentage [correlates very well](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey#some-interesting-examples")`) with COVID case rates as reported by state agencies. -```{r mask-wearing, message=FALSE, fig.width=9} +```{r mask-wearing, message=FALSE, fig.width=9, out.extra = 'class="wide-figure"'} library(covidcast) library(ggplot2) library(grid) @@ -246,7 +249,7 @@ wear a mask; also, many states with high mask usage had major outbreaks earlier in the pandemic. Nonetheless, this data could be very useful to epidemiological researchers studying the public reaction to the pandemic and its spread. -Mask-wearing surveys have been done before---for example, [the *New York Times* +Mask-wearing surveys have been done before---for example, [the _New York Times_ commissioned a large survey during July 2020 and produced detailed maps](https://www.nytimes.com/interactive/2020/07/17/upshot/coronavirus-face-mask-map.html)---but because our survey runs continuously, we will be able to track how the @@ -344,7 +347,7 @@ estimate for that state.) Test positivity only indirectly answers a crucial question: Does test availability meet demand for tests? When our survey respondents say they have -*not* been tested in the past 14 days, we ask whether they *wanted* to be tested +_not_ been tested in the past 14 days, we ask whether they _wanted_ to be tested in that time. This also varies across the United States: ```{r wanted-test, message=FALSE} @@ -363,7 +366,6 @@ COVIDcast API, alongside numerous other data streams, we hope to provide researchers, public health officials, and journalists the information they need to form a more complete picture of the pandemic. - ## You Can Help Analyze This Data All of the maps and graphs above were built using data we make publicly @@ -402,12 +404,12 @@ important roles informing our national pandemic response. Armed with the right data, we can make decisions needed to protect public health and permit safe reopening. -*For more information about Delphi's symptom surveys, and for media contact +_For more information about Delphi's symptom surveys, and for media contact details, see [our surveys page](`r blogdown::shortcode_html("ref", "surveys")`). For -updates, you can follow [CmuDelphi on Twitter](https://twitter.com/cmudelphi).* +updates, you can follow [CmuDelphi on Twitter](https://twitter.com/cmudelphi)._ -**Note.** *This post was updated on October 17, 2020 to correct an error in the +**Note.** _This post was updated on October 17, 2020 to correct an error in the scatterplot of mask usage and reported case rates. An error in our data processing system meant our reported case rates were half the size they should have been. This did not affect the trend in the scatterplot, only the scale of -the X axis.* +the X axis._ diff --git a/content/blog/2020-10-06-survey-wave-4.html b/content/blog/2020-10-06-survey-wave-4.html index a8741a5d9..9dd48f166 100644 --- a/content/blog/2020-10-06-survey-wave-4.html +++ b/content/blog/2020-10-06-survey-wave-4.html @@ -1,17 +1,20 @@ --- -title: "New and Improved COVID Symptom Survey Tracks Testing and Mask-Wearing" -author: "Alex Reinhart" +title: New and Improved COVID Symptom Survey Tracks Testing and Mask-Wearing +author: Alex Reinhart date: 2020-10-12 -tags: ["symptom surveys", "COVIDcast", "R"] +tags: + - symptom surveys + - COVIDcast + - R summary: | Beginning on September 8, 2020, we deployed a new version of our symptom survey. Facebook helps us recruit tens of thousands of respondents daily, and the new survey gives us unprecedented insights into the effects of COVID-19 across the United States. Today we release new public datasets and share maps revealing access to COVID testing, test results, and public use of masks. authors: -- alex + - alex heroImage: /blog/images/blog-lg-img_New and Improved COVID.png heroImageThumb: /blog/images/blog-thumb-img_New and Improved COVID.png -acknowledgments: | +acknowledgements: | Many items in Wave 4 of our survey are based on work by the team at the Joint Program in Survey Methodology at the University of Maryland led by Frauke Kreuter; Adrianne Bradford and Samantha Chiu helped @@ -163,7 +166,7 @@

    Mask Wearing

    title = "% who know someone who is sick") + date_label grid.arrange(g1, g2, nrow = 1, bottom = grid_label)
    -

    +

    We see that in New England, which had numerous COVID cases during the first wave early in 2020, most respondents report wearing masks in public. The lowest rates of mask wearing are in the central United States, such as in North and South @@ -233,7 +236,7 @@

    Mask Wearing

    "hoverCompareCartesian", "hoverClosestCartesian"))
    - +

    The relationship is striking. (Hover over or click each point to see which state it is.) Of course, correlation is not causation, and there are many differences between these states beyond their use of masks. For example, people in more diff --git a/content/blog/2020-10-14-dv-signal.Rmd b/content/blog/2020-10-14-dv-signal.Rmd index 1e7b22162..0abe6dd81 100644 --- a/content/blog/2020-10-14-dv-signal.Rmd +++ b/content/blog/2020-10-14-dv-signal.Rmd @@ -1,19 +1,22 @@ --- -title: "A Syndromic COVID-19 Indicator Based on Insurance Claims of Outpatient Visits" -author: "Aaron Rumack and Roni Rosenfeld" +title: A Syndromic COVID-19 Indicator Based on Insurance Claims of Outpatient Visits +author: Aaron Rumack and Roni Rosenfeld date: 2020-11-05 -tags: ["medical records", "COVIDcast", "R"] +tags: + - medical records + - COVIDcast + - R authors: -- aaron -- roni + - aaron + - roni heroImage: /blog/images/blog-img_A Syndromic COVID-19.png heroImageThumb: /blog/images/blog-thumb-img_A Syndromic COVID-19.png related: -- 2020-09-18-google-survey -- 2020-08-26-fb-survey + - 2020-09-18-google-survey + - 2020-08-26-fb-survey summary: | In previous posts, we discussed our massive ongoing symptom surveys that have reached over 12 million people in the U.S. since April 2020, in partnership with Facebook and Google. Another one of our major data initiatives is based on partnerships with healthcare systems, granting us access to various aggregate statistics from hospital records and insurance claims covering 10-15% of the United States population. From these data, we can extract informative indicators that can be early indicators of COVID activity. This post focuses on one indicator in particular, based on outpatient visits, and demonstrates both the challenges and promises associated with medical records data. -acknowledgements: | +acknowledgements: | Maria Jahja contributed immensely to every stage of this project, from determining which ICD codes to use to the final implementation of the indicator. Aaron Rumack devised the weekday adjustment and analyzed the performance of the DV indicator. Roni Rosenfeld worked closely with our health systems partners to get access to the data and provided domain knowledge to ensure that the data was useful. Both Roni and Ryan Tibshirani provided helpful suggestions and insights towards the methodology and analysis. @@ -25,39 +28,39 @@ output: toc: true --- -Our COVIDcast [map](`r blogdown::shortcode_html("ref", "covidcast")`) and [API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`) feature several novel early indicators of COVID-19 activity. In past posts, we discussed our large-scale daily surveys that, as of October 2020, have reached over 12 million people throughout the US, in partnership with [Facebook](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey")`) and [Google](`r blogdown::shortcode_html("ref", "2020-09-18-google-survey")`). In another ongoing data initiative, health system partners grant us access to various aggregate statistics from hospital records and insurance claims covering 10-15% of the United States population. From these data, we can extract informative indicators that can be early indicators of COVID activity. Early indicators are important because they help policymakers make more informed decisions and can also improve epidemiological forecasts. +Our COVIDcast [map](`r blogdown::shortcode_html("ref", "covidcast")`) and [API](`r blogdown::shortcode_html("apiref", "api/covidcast.html")`) feature several novel early indicators of COVID-19 activity. In past posts, we discussed our large-scale daily surveys that, as of October 2020, have reached over 12 million people throughout the US, in partnership with [Facebook](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey")`) and [Google](`r blogdown::shortcode_html("ref", "2020-09-18-google-survey")`). In another ongoing data initiative, health system partners grant us access to various aggregate statistics from hospital records and insurance claims covering 10-15% of the United States population. From these data, we can extract informative indicators that can be early indicators of COVID activity. Early indicators are important because they help policymakers make more informed decisions and can also improve epidemiological forecasts. -One indicator that we created from the outpatient insurance claims portion of this data is what we call the **Doctor Visits** or **DV** indicator, which estimates the percentage of outpatient visits (including telemedicine, urgent care, and emergency department visits) that are due to COVID-Like Illness or CLI. We will use % CLI-in-DV to abbreviate the percentage of outpatient visits due to CLI, the units of our DV indicator. Below, we explain how we calculate the DV indicator and discuss its relation to confirmed COVID-19 cases. We also discuss our observation that the DV indicator possesses significant spatial heterogeneity (it displays systematic county-to-county differences), and we describe a simple dynamic adjustment to address this issue. +One indicator that we created from the outpatient insurance claims portion of this data is what we call the **Doctor Visits** or **DV** indicator, which estimates the percentage of outpatient visits (including telemedicine, urgent care, and emergency department visits) that are due to COVID-Like Illness or CLI. We will use % CLI-in-DV to abbreviate the percentage of outpatient visits due to CLI, the units of our DV indicator. Below, we explain how we calculate the DV indicator and discuss its relation to confirmed COVID-19 cases. We also discuss our observation that the DV indicator possesses significant spatial heterogeneity (it displays systematic county-to-county differences), and we describe a simple dynamic adjustment to address this issue. ## Motivation -Electronic medical records (EMR) are instrumental in providing epidemiological information in near real-time. Sick patients interact with the healthcare system up to several weeks before they are confirmed as cases and added to the published count (see below). Thus signals based on EMR data can be *early indicators*, preceding official reports of confirmed cases and deaths. Early knowledge of a rise in COVID-like symptoms can enable early containment efforts to manage emerging outbreaks. - +Electronic medical records (EMR) are instrumental in providing epidemiological information in near real-time. Sick patients interact with the healthcare system up to several weeks before they are confirmed as cases and added to the published count (see below). Thus signals based on EMR data can be _early indicators_, preceding official reports of confirmed cases and deaths. Early knowledge of a rise in COVID-like symptoms can enable early containment efforts to manage emerging outbreaks. + The value of EMR data becomes apparent when you compare them to official COVID-19 case counts: - + - **Limited testing capacity.** Especially prevalent in the earlier days of the pandemic, limited testing capacity means that many people saw a doctor for COVID-like symptoms but did not receive a test, even though they should have. These people would be represented in our DV indicator but absent from the confirmed counts. - + - **Reporting delays.** From the moment a patient is first examined (or remotely evaluated), it may take several days until their specimen is collected, and another few days after testing before results are available. When tests come back positive, they must (by law) be reported to the public health authorities. The health authorities typically do further verification and investigation (for example, determining age and other demographics) before adding the cases to their public website. As a result, reports of confirmed cases trail behind the medical evaluation date by several weeks. Even with the reporting delays of insurance claims (see below), a claims-based signal allows estimates of disease activity within 3-4 days of when the outpatient visits occurred. -- **Date accuracy.** Sites like [JHU CSSE](https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6) and [USAFacts](https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/) scrape and report cumulative confirmed cases based on the cases' first date of public posting. As a result, the "number of new daily counts" (derived by successive subtraction from these reports) often refers to the number of cases *published* instead of those *lab-confirmed* on that date. In comparison, insurance claims indicate a "date of service", which is typically closer to the testing date. Accurate dating of cases is critical for modeling, analysis, and forecasting. - +- **Date accuracy.** Sites like [JHU CSSE](https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6) and [USAFacts](https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/) scrape and report cumulative confirmed cases based on the cases' first date of public posting. As a result, the "number of new daily counts" (derived by successive subtraction from these reports) often refers to the number of cases _published_ instead of those _lab-confirmed_ on that date. In comparison, insurance claims indicate a "date of service", which is typically closer to the testing date. Accurate dating of cases is critical for modeling, analysis, and forecasting. + - **Retrospective revisions.** Some states have changed their definition of confirmed COVID-19 cases. This is sometimes done retroactively, adding hundreds or thousands of past cases and reporting them as "new" on the day that the definition was changed, resulting in an artificial spike on that date, with no way to assign these cases to their correct dates. This degrades the quality of the case time series. - -## The Doctor Visits Indicator - + +## The Doctor Visits Indicator + The Doctor Visits indicator is based solely on insurance claims. We count the outpatient claims for a given geographic area and day that fall into each of five categories: - -1. Total: All claims, whether or not related to COVID-19 (also known as *all-cause* claims). - -2. Flu: ICD-10 primary code starting with J09, J10, or J11, a definitive diagnosis of influenza. - + +1. Total: All claims, whether or not related to COVID-19 (also known as _all-cause_ claims). + +2. Flu: ICD-10 primary code starting with J09, J10, or J11, a definitive diagnosis of influenza. + 3. COVID-like: ICD-10 primary code in {U07.1, U07.2, B97.29, J12.81, Z03.818, B34.2, J12.89}. Some of these codes correspond to a definitive diagnosis of COVID-19, while others indicate strongly related conditions. - -4. Flu-like: ICD-10 primary code of J22 (acute lower respiratory infection) or B34.9 (viral infection, unspecified). - -5. Mixed: ICD-10 primary code of Z20.828 (suspected exposure to COVID-19) or J12.9 (viral pneumonia). -We estimate the percent of COVID-like illness in doctor visits (% CLI-in-DV) as 100 * (COVID-like + Flu-like + Mixed - Flu) / Total. We subtract the "Flu" count because the higher the presence of confirmed flu, the larger the fraction of flu-like cases that are due to flu rather than to COVID. See [our signal documentation site](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/doctor-visits.html")`) for more details. +4. Flu-like: ICD-10 primary code of J22 (acute lower respiratory infection) or B34.9 (viral infection, unspecified). + +5. Mixed: ICD-10 primary code of Z20.828 (suspected exposure to COVID-19) or J12.9 (viral pneumonia). + +We estimate the percent of COVID-like illness in doctor visits (% CLI-in-DV) as 100 \* (COVID-like + Flu-like + Mixed - Flu) / Total. We subtract the "Flu" count because the higher the presence of confirmed flu, the larger the fraction of flu-like cases that are due to flu rather than to COVID. See [our signal documentation site](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/doctor-visits.html")`) for more details. The indicator is available daily starting February 1, 2020 (although understandably, it is nearly zero in all locations until mid-March). To preserve privacy and data integrity, we do not report the indicator for a given location and date if there are fewer than 500 total visits in the seven days ending on that date. Following these restrictions, each day, we are able to produce estimates for about 2000 counties (roughly two-thirds of the counties in the US), accounting for over 90% of the country's population. @@ -67,7 +70,7 @@ Below, we plot two maps to explore the indicator. On the left is a heatmap repre knitr::opts_chunk$set(cache = TRUE, autodep = TRUE, cache.comments = TRUE) ``` -```{r, message = FALSE, warning = FALSE, fig.width = 10, fig.height = 4} +```{r, message = FALSE, warning = FALSE, fig.width = 10, fig.height = 4, out.extra = 'class="wide-figure"'} library(covidcast) library(dplyr) library(ggplot2) @@ -101,7 +104,7 @@ p1 = plot(df_dv_avg, range = c(0, 15), choro_params = list(subtitle = subtitle)) p2 = plot(df_in_avg, title = "Daily new confirmed COVID-19 cases per 100,000 people", - range = c(0, 30), choro_params = list(subtitle = subtitle)) + range = c(0, 25), choro_params = list(subtitle = subtitle)) grid.arrange(p1, p2, nrow = 1) ``` @@ -113,9 +116,9 @@ Interestingly, certain types of claims have longer latency than others. We found ## Weekday Effects -Another challenge is the influence of the day of the week on the DV indicator. On weekends, both total counts and COVID-like counts decrease, but proportionally, total counts decrease more. This is because doctor visits during the weekend tend to focus on acute care. The total counts include many visits related to non-acute issues, but almost all COVID-like counts are due to acute issues. Without adjusting for this weekday effect, the DV indicator has a "sawtooth" pattern, spiking on weekends. We derived a method to create an adjusted indicator that accounts for this weekday effect (for a precise description, see our [signal documentation](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/doctor-visits.html#day-of-week-adjustment")`)). Below, we visualize the effect of making these adjustments. When we do not adjust for the weekday effect, we see a sawtooth pattern that clearly does not represent true changes in COVID-like illness within a location. However, after making the weekday adjustment, we get a smooth curve that looks reasonable. It is important to note that this adjustment is *not* temporal smoothing! Rather, we are making an adjustment each day based on historical patterns of weekday-to-weekend differences. +Another challenge is the influence of the day of the week on the DV indicator. On weekends, both total counts and COVID-like counts decrease, but proportionally, total counts decrease more. This is because doctor visits during the weekend tend to focus on acute care. The total counts include many visits related to non-acute issues, but almost all COVID-like counts are due to acute issues. Without adjusting for this weekday effect, the DV indicator has a "sawtooth" pattern, spiking on weekends. We derived a method to create an adjusted indicator that accounts for this weekday effect (for a precise description, see our [signal documentation](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/doctor-visits.html#day-of-week-adjustment")`)). Below, we visualize the effect of making these adjustments. When we do not adjust for the weekday effect, we see a sawtooth pattern that clearly does not represent true changes in COVID-like illness within a location. However, after making the weekday adjustment, we get a smooth curve that looks reasonable. It is important to note that this adjustment is _not_ temporal smoothing! Rather, we are making an adjustment each day based on historical patterns of weekday-to-weekend differences. -```{r, message = FALSE, warning = FALSE, fig.width = 8, fig.height = 8} +```{r, message = FALSE, warning = FALSE, fig.width = 8, fig.height = 8, out.extra = 'class="wide-figure"'} start_day = "2020-05-01" end_day = "2020-08-01" @@ -147,7 +150,7 @@ ggplot(cmb_df %>% filter(geo_value %in% states_to_plot)) + facet_wrap(vars(geo_value)) + labs(x = "Date", y = "% CLI-in-DV", title = "DV indicator, with and without weekday adjustment") + - theme_bw() + + theme_bw() + theme(legend.position = "bottom", legend.title = element_blank()) ``` @@ -159,14 +162,14 @@ As a simple quantitative analysis, we can measure the correlation between the DV start_day = "2020-04-15" end_day = "2020-10-01" -df_adjusted = covidcast_signal("doctor-visits", "smoothed_adj_cli", +df_adjusted = covidcast_signal("doctor-visits", "smoothed_adj_cli", start_day, end_day) -df_cases = covidcast_signal("usa-facts", "confirmed_7dav_incidence_prop", +df_cases = covidcast_signal("usa-facts", "confirmed_7dav_incidence_prop", start_day, end_day) case_num = 500 cumulative_case_df = covidcast_signal("usa-facts", "confirmed_cumulative_num", - max(df_cases$time_value), + max(df_cases$time_value), max(df_cases$time_value)) geo_values = cumulative_case_df %>% filter(value >= case_num) %>% pull(geo_value) @@ -176,7 +179,7 @@ dv_cases_df = bind_rows(df_adjusted, df_cases) %>% select(geo_value, signal, time_value, value) %>% tidyr::pivot_wider(names_from = signal, values_from = value) %>% rename(cases = confirmed_7dav_incidence_prop, dv = smoothed_adj_cli) %>% - filter(purrr::map_lgl(geo_value, function(fips) { + filter(purrr::map_lgl(geo_value, function(fips) { substr(fips, 3, 5) != "000"})) %>% group_by(time_value) %>% ungroup() @@ -199,7 +202,7 @@ ggplot(df_cor_by_space) + geom_density(aes(x = value), fill = "gray") + labs(title = "Correlation-by-space between DV indicator and case rates", subtitle = "Over all counties with at least 500 cumulative cases", - x = "Correlation", y = "Density") + + x = "Correlation", y = "Density") + theme_bw() ``` @@ -216,7 +219,7 @@ tibble(thresholds = seq(500, 20000, by = 500)) %>% thresholds, function(t) { mean(df_cor_by_space %>% filter(cases >= t) %>% pull(value), na.rm=T) })) %>% - ggplot() + + ggplot() + geom_line(aes(x = thresholds, y = avg_corr)) + labs(x = "Cumulative cases threshold", y = "Correlation", title = "Mean correlation-by-space between DV indicator and case rates", @@ -231,7 +234,7 @@ ggplot(df_cor_by_time) + geom_line(aes(x = time_value, y = value)) + labs(title = "Correlation-by-time between DV indicator and case rates", subtitle = "Over all counties with at least 500 cumulative cases", - x = "Date", y = "Correlation") + + x = "Date", y = "Correlation") + theme_bw() ``` @@ -239,7 +242,7 @@ ggplot(df_cor_by_time) + This correlation deterioration was surprising to us, so we set out to find out the reason. After testing many hypotheses, we found one cause: some areas of the country have a higher % CLI-in-DV "baseline" than others. We illustrate this with the plots below, where we plot the average case rate and average DV indicator for each of the 10 HHS regions (each region is comprised of 2-7 states; you can find the details on the [Department of HHS website](https://www.hhs.gov/about/agencies/iea/regional-offices/index.html)). -```{r, message = FALSE, warning = FALSE, fig.width = 10, fig.height = 4} +```{r, message = FALSE, warning = FALSE, fig.width = 10, fig.height = 4, out.extra = 'class="wide-figure"'} fips_to_hhs = function(fips) { st = as.integer(substr(fips,1,2)) if (st %in% c(9,23,25,33,44,50)) { @@ -283,7 +286,7 @@ p1 = dv_cases_df %>% geom_line(aes(x = time_value, y = cases, color = as.factor(hhs))) + labs(title = "Mean case rate per HHS region", x = "Date", y = "New cases per 100,000 people", color = "HHS") + - theme_bw() + theme_bw() p2 = dv_cases_df %>% group_by(time_value, hhs) %>% @@ -303,9 +306,9 @@ Let's look more closely at the behavior of our indicator in HHS 2 (New Jersey an The answer to the first question is largely yes. The case rate curve is steadily decreasing throughout April and May, flattening out by mid-June. The DV indicator peaks a little later than case rates do, but decreases throughout May and is mostly flat by mid-June. This tells us that the correlation-by-space is good in HHS 2. However, the answer to the second question reveals an issue with the DV indicator. The case rate in HHS 2 is the highest of all HHS regions in May and into June, but by July, HHS 2 is among the lowest in case rate. This is not true with the DV indicator. HHS 2 has the highest % CLI-in-DV almost throughout the entire time period, even when its case rate is one of the lowest. So we see why the correlation-by-time began to decline starting in August: counties in HHS 2 tended to have low case rates but high % CLI-in-DV values, driving down the correlations. -We have now identified the problem: a % CLI-in-DV of, say, 5% might mean a very low case rate for a county in New York but a very high case rate for a county in Oregon. Since we have six months’ worth of history for both the DV indicator and case rates, we can correct for this problem by regressing case rates on the DV indicator in a location-specific manner. We call this *sensorization*, that is, the process of turning the DV indicator into a *sensor*. In the past, the Delphi group has done extensive work in creating sensors from multiple data sources for tracking flu, dengue, and norovirus; and developed sensor fusion methodology for combining multiple sensors into a single unified estimate. For more, see Chapter 4 of [Farrow 2016](https://delphi.cmu.edu/~dfarrow/thesis.pdf) and [Jahja et al. 2019](https://papers.nips.cc/paper/9475-kalman-filter-sensor-fusion-and-constrained-regression-equivalences-and-insights). +We have now identified the problem: a % CLI-in-DV of, say, 5% might mean a very low case rate for a county in New York but a very high case rate for a county in Oregon. Since we have six months’ worth of history for both the DV indicator and case rates, we can correct for this problem by regressing case rates on the DV indicator in a location-specific manner. We call this _sensorization_, that is, the process of turning the DV indicator into a _sensor_. In the past, the Delphi group has done extensive work in creating sensors from multiple data sources for tracking flu, dengue, and norovirus; and developed sensor fusion methodology for combining multiple sensors into a single unified estimate. For more, see Chapter 4 of [Farrow 2016](https://delphi.cmu.edu/~dfarrow/thesis.pdf) and [Jahja et al. 2019](https://papers.nips.cc/paper/9475-kalman-filter-sensor-fusion-and-constrained-regression-equivalences-and-insights). -In the present example, we sensorize by fitting a simple linear regression model of case rates on % CLI-in-DV, separately for each day and location, training on data from the past six weeks. Because we fit the regression anew each day based on the most recently available data, the method adapts to (potential) gradual changes in the underlying relationship between % CLI-in-DV and case rate. This method is mostly real-time, but for backfill in the DV indicator, as discussed above. +In the present example, we sensorize by fitting a simple linear regression model of case rates on % CLI-in-DV, separately for each day and location, training on data from the past six weeks. Because we fit the regression anew each day based on the most recently available data, the method adapts to (potential) gradual changes in the underlying relationship between % CLI-in-DV and case rate. This method is mostly real-time, but for backfill in the DV indicator, as discussed above. ```{r, message = FALSE, warning = FALSE, fig.width = 6, fig.height = 5} dv_cases_df = dv_cases_df %>% @@ -319,9 +322,9 @@ dv_cases_df = dv_cases_df %>% ungroup() dv_cases_df = dv_cases_df %>% - mutate(slope_6wk = purrr::map_dbl(coef_6wk, function(c) { + mutate(slope_6wk = purrr::map_dbl(coef_6wk, function(c) { tryCatch(c[[2]], error = function(x) {NA})})) %>% - mutate(int_6wk = purrr::map_dbl(coef_6wk, function(c) { + mutate(int_6wk = purrr::map_dbl(coef_6wk, function(c) { tryCatch(c[[1]], error = function(x) {NA})})) %>% select(-coef_6wk) @@ -340,9 +343,9 @@ df_cor_by_time_adj = covidcast_cor( method = "spearman") inner_join(df_cor_by_time %>% rename(orig_cor = value), - df_cor_by_time_adj %>% rename(adj_cor = value), + df_cor_by_time_adj %>% rename(adj_cor = value), by = "time_value") %>% - ggplot() + + ggplot() + geom_line(aes(time_value, orig_cor, color = "Original")) + geom_line(aes(time_value, adj_cor, color = "Sensorized")) + scale_color_manual(values = ggplot_colors[1:2]) + @@ -353,10 +356,10 @@ inner_join(df_cor_by_time %>% rename(orig_cor = value), theme(legend.position = "bottom", legend.title = element_blank()) ``` -From the plot above, we see that sensorizing the DV indicator greatly improves the correlations-by-time. +From the plot above, we see that sensorizing the DV indicator greatly improves the correlations-by-time. It turns out that the regression coefficients in the method described above, which are fit using a sliding window, change significantly over time. As a future direction, we plan to look into this nonstationary relationship between the DV indicator and case rates to better understand why it changes and why counties in New York and New Jersey have such a different relationship in the first place. ## Exciting New Data -We will end with exciting news: we have recently been granted access to medical insurance claims from [Change Healthcare](https://www.changehealthcare.com), a large healthcare technology company, and are in the process of creating multiple indicators from it. Their data covers approximately 45% of the population of the United States, so we expect it to enable us to substantially boost the accuracy, coverage, and resolution of our EMR-based indicators. We are also interested in comparing our new Change Healthcare indicator (a work in progress) to our current indicator in sample size, correlations, and behavior. Some insurance providers cover different populations with different rates, which could make their indicator more or less correlated with the reported case rates and other relevant indicators. We expect that by combining data sets and dramatically increasing coverage we can produce a significantly more useful indicator. \ No newline at end of file +We will end with exciting news: we have recently been granted access to medical insurance claims from [Change Healthcare](https://www.changehealthcare.com), a large healthcare technology company, and are in the process of creating multiple indicators from it. Their data covers approximately 45% of the population of the United States, so we expect it to enable us to substantially boost the accuracy, coverage, and resolution of our EMR-based indicators. We are also interested in comparing our new Change Healthcare indicator (a work in progress) to our current indicator in sample size, correlations, and behavior. Some insurance providers cover different populations with different rates, which could make their indicator more or less correlated with the reported case rates and other relevant indicators. We expect that by combining data sets and dramatically increasing coverage we can produce a significantly more useful indicator. diff --git a/content/blog/2020-10-14-dv-signal.html b/content/blog/2020-10-14-dv-signal.html index 1aa3d85fe..0eec260d0 100644 --- a/content/blog/2020-10-14-dv-signal.html +++ b/content/blog/2020-10-14-dv-signal.html @@ -1,19 +1,22 @@ --- -title: "A Syndromic COVID-19 Indicator Based on Insurance Claims of Outpatient Visits" -author: "Aaron Rumack and Roni Rosenfeld" +title: A Syndromic COVID-19 Indicator Based on Insurance Claims of Outpatient Visits +author: Aaron Rumack and Roni Rosenfeld date: 2020-11-05 -tags: ["medical records", "COVIDcast", "R"] +tags: + - medical records + - COVIDcast + - R authors: -- aaron -- roni + - aaron + - roni heroImage: /blog/images/blog-img_A Syndromic COVID-19.png heroImageThumb: /blog/images/blog-thumb-img_A Syndromic COVID-19.png related: -- 2020-09-18-google-survey -- 2020-08-26-fb-survey + - 2020-09-18-google-survey + - 2020-08-26-fb-survey summary: | In previous posts, we discussed our massive ongoing symptom surveys that have reached over 12 million people in the U.S. since April 2020, in partnership with Facebook and Google. Another one of our major data initiatives is based on partnerships with healthcare systems, granting us access to various aggregate statistics from hospital records and insurance claims covering 10-15% of the United States population. From these data, we can extract informative indicators that can be early indicators of COVID activity. This post focuses on one indicator in particular, based on outpatient visits, and demonstrates both the challenges and promises associated with medical records data. -acknowledgements: | +acknowledgements: | Maria Jahja contributed immensely to every stage of this project, from determining which ICD codes to use to the final implementation of the indicator. Aaron Rumack devised the weekday adjustment and analyzed the performance of the DV indicator. Roni Rosenfeld worked closely with our health systems partners to get access to the data and provided domain knowledge to ensure that the data was useful. Both Roni and Ryan Tibshirani provided helpful suggestions and insights towards the methodology and analysis. @@ -100,9 +103,9 @@

    The Doctor Visits Indicator

    range = c(0, 15), choro_params = list(subtitle = subtitle)) p2 = plot(df_in_avg, title = "Daily new confirmed COVID-19 cases per 100,000 people", - range = c(0, 30), choro_params = list(subtitle = subtitle)) + range = c(0, 25), choro_params = list(subtitle = subtitle)) grid.arrange(p1, p2, nrow = 1)
    -

    +

    Backfill

    @@ -143,9 +146,9 @@

    Weekday Effects

    facet_wrap(vars(geo_value)) + labs(x = "Date", y = "% CLI-in-DV", title = "DV indicator, with and without weekday adjustment") + - theme_bw() + + theme_bw() + theme(legend.position = "bottom", legend.title = element_blank()) -

    +

    Basic Correlation Analyses

    @@ -153,14 +156,14 @@

    Basic Correlation Analyses

    start_day = "2020-04-15"
     end_day = "2020-10-01"
     
    -df_adjusted = covidcast_signal("doctor-visits", "smoothed_adj_cli", 
    +df_adjusted = covidcast_signal("doctor-visits", "smoothed_adj_cli",
                                    start_day, end_day)
    -df_cases = covidcast_signal("usa-facts", "confirmed_7dav_incidence_prop", 
    +df_cases = covidcast_signal("usa-facts", "confirmed_7dav_incidence_prop",
                                 start_day, end_day)
     
     case_num = 500
     cumulative_case_df = covidcast_signal("usa-facts", "confirmed_cumulative_num",
    -                                      max(df_cases$time_value), 
    +                                      max(df_cases$time_value),
                                           max(df_cases$time_value))
     geo_values = cumulative_case_df %>%
       filter(value >= case_num) %>% pull(geo_value)
    @@ -170,7 +173,7 @@ 

    Basic Correlation Analyses

    select(geo_value, signal, time_value, value) %>% tidyr::pivot_wider(names_from = signal, values_from = value) %>% rename(cases = confirmed_7dav_incidence_prop, dv = smoothed_adj_cli) %>% - filter(purrr::map_lgl(geo_value, function(fips) { + filter(purrr::map_lgl(geo_value, function(fips) { substr(fips, 3, 5) != "000"})) %>% group_by(time_value) %>% ungroup() @@ -193,7 +196,7 @@

    Basic Correlation Analyses

    geom_density(aes(x = value), fill = "gray") + labs(title = "Correlation-by-space between DV indicator and case rates", subtitle = "Over all counties with at least 500 cumulative cases", - x = "Correlation", y = "Density") + + x = "Correlation", y = "Density") + theme_bw()

    Locations with small counts usually have a lower signal-to-noise ratio, which means that their correlations will usually be lower. In the next plot, we show that the average correlation (still sliced by space) is higher when we restrict our attention to counties with higher cumulative case counts. The average correlation increases substantially when considering only counties that have more than 2,000 cumulative COVID-19 cases, and increasing the threshold from there results in only a modest increase in correlation.

    @@ -207,7 +210,7 @@

    Basic Correlation Analyses

    thresholds, function(t) { mean(df_cor_by_space %>% filter(cases >= t) %>% pull(value), na.rm=T) })) %>% - ggplot() + + ggplot() + geom_line(aes(x = thresholds, y = avg_corr)) + labs(x = "Cumulative cases threshold", y = "Correlation", title = "Mean correlation-by-space between DV indicator and case rates", @@ -219,7 +222,7 @@

    Basic Correlation Analyses

    geom_line(aes(x = time_value, y = value)) + labs(title = "Correlation-by-time between DV indicator and case rates", subtitle = "Over all counties with at least 500 cumulative cases", - x = "Date", y = "Correlation") + + x = "Date", y = "Correlation") + theme_bw()

    @@ -269,7 +272,7 @@

    Spatial Heterogeneity

    geom_line(aes(x = time_value, y = cases, color = as.factor(hhs))) + labs(title = "Mean case rate per HHS region", x = "Date", y = "New cases per 100,000 people", color = "HHS") + - theme_bw() + theme_bw() p2 = dv_cases_df %>% group_by(time_value, hhs) %>% @@ -283,7 +286,7 @@

    Spatial Heterogeneity

    theme_bw() grid.arrange(p1, p2, nrow = 1) -

    +

    Let’s look more closely at the behavior of our indicator in HHS 2 (New Jersey and New York). We will compare the two curves in two ways: when the case rate is high (or low) in HHS 2 compared to other days, is the DV indicator also high (or low)? And when the case rate is high (or low) in HHS 2 compared to other HHS regions, is the DV indicator also high (or low) in HHS 2? The first question asks how high the correlation-by-space is, and the second asks how high the correlation-by-time is.

    The answer to the first question is largely yes. The case rate curve is steadily decreasing throughout April and May, flattening out by mid-June. The DV indicator peaks a little later than case rates do, but decreases throughout May and is mostly flat by mid-June. This tells us that the correlation-by-space is good in HHS 2. However, the answer to the second question reveals an issue with the DV indicator. The case rate in HHS 2 is the highest of all HHS regions in May and into June, but by July, HHS 2 is among the lowest in case rate. This is not true with the DV indicator. HHS 2 has the highest % CLI-in-DV almost throughout the entire time period, even when its case rate is one of the lowest. So we see why the correlation-by-time began to decline starting in August: counties in HHS 2 tended to have low case rates but high % CLI-in-DV values, driving down the correlations.

    We have now identified the problem: a % CLI-in-DV of, say, 5% might mean a very low case rate for a county in New York but a very high case rate for a county in Oregon. Since we have six months’ worth of history for both the DV indicator and case rates, we can correct for this problem by regressing case rates on the DV indicator in a location-specific manner. We call this sensorization, that is, the process of turning the DV indicator into a sensor. In the past, the Delphi group has done extensive work in creating sensors from multiple data sources for tracking flu, dengue, and norovirus; and developed sensor fusion methodology for combining multiple sensors into a single unified estimate. For more, see Chapter 4 of Farrow 2016 and Jahja et al. 2019.

    @@ -299,9 +302,9 @@

    Spatial Heterogeneity

    ungroup() dv_cases_df = dv_cases_df %>% - mutate(slope_6wk = purrr::map_dbl(coef_6wk, function(c) { + mutate(slope_6wk = purrr::map_dbl(coef_6wk, function(c) { tryCatch(c[[2]], error = function(x) {NA})})) %>% - mutate(int_6wk = purrr::map_dbl(coef_6wk, function(c) { + mutate(int_6wk = purrr::map_dbl(coef_6wk, function(c) { tryCatch(c[[1]], error = function(x) {NA})})) %>% select(-coef_6wk) @@ -320,9 +323,9 @@

    Spatial Heterogeneity

    method = "spearman") inner_join(df_cor_by_time %>% rename(orig_cor = value), - df_cor_by_time_adj %>% rename(adj_cor = value), + df_cor_by_time_adj %>% rename(adj_cor = value), by = "time_value") %>% - ggplot() + + ggplot() + geom_line(aes(time_value, orig_cor, color = "Original")) + geom_line(aes(time_value, adj_cor, color = "Sensorized")) + scale_color_manual(values = ggplot_colors[1:2]) + diff --git a/content/blog/2020-12-10-masks-public.Rmd b/content/blog/2020-12-10-masks-public.Rmd new file mode 100644 index 000000000..6c24838bf --- /dev/null +++ b/content/blog/2020-12-10-masks-public.Rmd @@ -0,0 +1,430 @@ +--- +title: "Are Masks Widely Used in Public?" +author: "Alex Reinhart" +date: 2020-12-13 +tags: + - symptom surveys + - COVIDcast + - R +authors: +- alex +heroImage: /blog/images/masks-public-full-size.jpg +heroImageThumb: /blog/images/masks-public-thumb.jpg +related: +- 2020-10-06-survey-wave-4 +summary: | + Delphi's symptom surveys reveal rates of mask use across the country. But do they really show that the vast majority of people wear masks? +acknowledgements: | + Wichada La Motte-Kerr drafted numerous survey revisions, collected input from experts, and managed the process of deploying the new survey questions. Sarah LaRocca and Katherine Morris at Facebook gave important input and helped deploy the survey. Kathryn Mazaitis assisted in producing the new aggregate survey data. +output: + blogdown::html_page: + toc: true +--- + +As COVID cases and deaths continue to rise in the United States, we are +repeatedly reminded that unless we take the appropriate precautions---by wearing +masks when around other people, working from home whenever possible, and +avoiding travel and crowded places---there will be a high rate of COVID deaths. +Vaccines are on their way, but until they arrive, we must continue social +distancing. + +But after all the precautions we've taken and the sacrifices we have made in our +lives during 2020, we have seen many people ask: Why haven't these precautions +prevented the current COVID spike? Some have even argued that this is proof that +masks and social distancing do not work. Can this claim be justified? + +To answer this question, we must first ask: *Is* everyone wearing masks? And are +they also socially distancing in other ways? In this post, we'll show how +Delphi's COVID symptom surveys can help answer these questions and how they can +enable important research about the pandemic and its spread. + +```{r setup, include=FALSE} +knitr::opts_chunk$set(collapse = TRUE) +``` + +## Studying Mask Use with Surveys + +Since April, and in partnership with Facebook Data for Good and the [University +of Maryland](https://covidmap.umd.edu/), Delphi has [conducted daily surveys of +Facebook users](`r blogdown::shortcode_html("ref", "2020-08-26-fb-survey")`) +throughout the United States. These surveys ask respondents about their +experiences during the pandemic, and ask whether they're experiencing symptoms, +whether they are isolating or following precautions, and how they have been +affected by the pandemic. The survey has been completed over 14 million times +since April, allowing us an unprecedented level of insight into COVID and +people's experiences, down to individual counties around the country. + +[Since early +September](`r blogdown::shortcode_html("ref", "2020-10-06-survey-wave-4")`) +we have asked all respondents a question about mask use: + +> In the past 5 days, how often did you wear a mask when in public? +> +> 1. All the time +> 2. Most of the time +> 3. Some of the time +> 4. A little of the time +> 5. None of the time +> 6. I have not been in public during the past 5 days + +Early analysis suggests that mask usage is high in most states, and in those +where it was lower, it has been gradually increasing. For example, the graph +below shows the percentage of respondents who answer "Most of the time" or "All +of the time" in five states and the District of Columbia. In three of these (the +District of Columbia, Massachusetts, and New York), mask usage is among the +highest in the country; in the other three (South Dakota, Idaho, and Wyoming), +it's among the lowest. + +```{r state_masks_time, message=FALSE} +library(covidcast) +library(dplyr) +library(ggplot2) +library(directlabels) + +states_of_interest <- c("dc", "ma", "ny", "wy", "sd", "id") + +state_masks <- covidcast_signal( + "fb-survey", "smoothed_wwearing_mask", + start_day = "2020-09-15", end_day = "2020-12-05", + geo_type = "state", geo_values = states_of_interest +) + +ggplot(state_masks, aes(x = time_value, y = value, color = geo_value)) + + geom_line() + + geom_dl(aes(label = toupper(geo_value)), method = "last.bumpup") + + scale_x_date(date_breaks = "1 month", + date_labels = "%b %Y", + date_minor_breaks = "1 week") + + labs(x = "Date", y = "% wearing masks in public most/all the time", + title = "Self-reported public mask usage", + subtitle = "From Delphi's surveys, conducted through Facebook", + caption = "Data from Delphi COVIDcast, delphi.cmu.edu") + + theme_bw() + + guides(color = FALSE) +``` + +Despite the gap between states, it also seems clear that self-reported mask use +has been on the rise in states whose mask use started low. This is quite +encouraging. + +(Note that, as with most of Delphi's blog posts, all the code and data used to +make these plots is available---simply click the Code button to see how our [API +clients](`r blogdown::shortcode_html("apiref", "api/covidcast_clients.html")`) +make it easy to access aggregated data.) + +Seeing these numbers---particularly the very high reported mask usage in many +states---might make you wonder: If mask usage is over 80% in most states and +over 90% in many, why does the rate of new COVID cases in the United States +currently look like this? + +```{r national_cases_time, message=FALSE} +cases <- covidcast_signal( + "indicator-combination", "confirmed_7dav_incidence_num", + start_day = "2020-09-15", end_day = "2020-12-05", + geo_type = "state") + +cases %>% + group_by(time_value) %>% + summarize(cases = sum(value)) %>% + ggplot(aes(x = time_value, y = cases)) + + geom_line() + + scale_x_date(date_breaks = "1 month", + date_labels = "%b %Y", + date_minor_breaks = "1 week") + + labs(x = "Date", y = "Reported new cases", + title = "Number of reported new cases per day", + subtitle = "7-day rolling average", + caption = "Data from Delphi COVIDcast, delphi.cmu.edu") + + theme_bw() +``` + +While we can't explain all of COVID in one blog post---nor do we have the data +and science needed to do so---we *can* address two key questions: + +1. Do the surveys reliably measure mask use in public? If they are biased in + some way, perhaps mask use is not as common as they suggest. +2. Are people adopting other social distancing behaviors alongside masks? If + some people do not wear masks and interact with each other, they may spread + COVID. Also, masks *reduce* risk; [they do not eliminate + it](https://www.preprints.org/manuscript/202004.0203/v4). If people are + working indoors around others, hosting social events, dining indoors, and so + on, but wearing masks, they are nonetheless at greater risk than people who + do none of those things. + +## Addressing Potential Survey Biases + +To answer the first question, we must consider what kinds of biases could affect +the surveys: + +* **Sampling bias.** Survey respondents are sampled from Facebook users, but + Facebook users may not be representative of the United States population. + Facebook [produces survey weights](https://arxiv.org/abs/2009.14675) designed + to help us adjust the survey to match the population's age and gender + distribution, but there could be other factors besides age and gender that + differ between Facebook users and the United States population generally. +* **Non-response bias.** The survey is voluntary---recruited users are shown an + invitation in their News Feed but can opt not to click on it---and so people + who take the survey might be different in some way. For example, perhaps the + people who take the survey are more concerned about COVID than those who + choose not to, and hence are more likely to wear masks than the general + population. Facebook's weights try to account for this by estimating the + probability that each person will respond, but it's difficult to verify that + this probability is estimated correctly. +* **Social desirability bias.** It's well-known that survey respondents can + prefer answers that seem socially desirable. If mask usage is widely accepted + and there is immense social pressure to comply, someone who does not usually + wear a mask may feel pressure to say they do on a survey. This effect is + likely smaller on an anonymous online survey than it would be in person, but + it could still be present. +* **Incorrect responses.** Some survey respondents may deliberately give + incorrect answers because when you post something on the Internet, inevitably + someone will try to mess with it. Sometimes this is easy to detect (e.g., + people indicating that they are experiencing *every* symptom of a list of 16 + or that they have -20 family members), but not always. + +These biases are hard to measure directly. There's another problem too: If 90% +of people say they wear masks when they're in public, that doesn't mean that 90% +of people in public places are wearing masks! For example, if people who wear +masks also tend to limit the amount of time they spend in public places, while +people who do not wear masks spend more time in public, people in public may be +more likely to also be people who don't wear masks. + +We don't have a way to tell if a respondent is truthful, and since there's no +objective national data on the exact percentage of people wearing masks in +public, we have no way to check exactly how biased results could be. We have +seen hints, however: when researchers in Philadelphia [studied surveillance +camera footage to count how many people in public places wear masks +correctly](https://bloombergcities.medium.com/how-philadelphia-is-cracking-the-code-for-measuring-mask-compliance-7ace18daa9a9), +**only 43% did**, despite over 90% of Philadelphia respondents to our survey +saying they wear masks most or all of the time. Unfortunately this is only one +study in one city, and doesn't give us a picture of mask usage nationally. + +After consulting with survey experts, we chose a different way to check our mask +use estimates. In late November, we added a new mask question to the survey: + +> In the past 7 days, when out in public places where social distancing is not +> possible, about how many people would you estimate wore masks? +> +> 1. All of the people were wearing masks +> 2. Most of the people were wearing masks +> 3. Some of the people were wearing masks +> 4. A few of the people were wearing masks +> 5. None of the people were wearing masks +> 6. I have not been out in public places in the past 7 days + +Because this question asks about *other* people, it bypasses social desirability +bias. And even if the survey sample is not representative, as long as the +respondents visit representative public places (like grocery stores or public +transit) and see *other* people there, we may get a better estimate of public +mask use. + +Let's see how the data looks. We'll plot the percentage of people answering +"all" or "most" to each mask question in each state: + +```{r mask_questions_compared, message=FALSE} +masked <- covidcast_signal( + "fb-survey", "smoothed_wwearing_mask", + start_day = "2020-12-01", end_day = "2020-12-01", + geo_type = "state") + +other_mask <- covidcast_signal( + "fb-survey", "smoothed_wothers_masked", + start_day = "2020-12-01", end_day = "2020-12-01", + geo_type = "state") + +joined <- masked %>% + inner_join(other_mask, by = "geo_value", + suffix = c(".self", ".other")) + +ggplot(joined, aes(x = value.self, y = value.other, + label = toupper(geo_value))) + + geom_text() + + geom_abline(slope = 1, intercept = 0, linetype = "dashed", + colour = "#888888") + + geom_text(aes(x = 83, y = 85, angle = 15, label = "equal percentages"), + colour = "#888888") + + labs(x = "% who report wearing masks most/all the time", + y = "% who report most/all others wear masks", + title = "Mask use reported in symptom survey", + subtitle = "December 1st, 2020", + caption = "Data from Delphi COVIDcast, delphi.cmu.edu") + + theme_bw() +``` + +There are a few things worthy of note. There is clearly a strong relationship +here---but notice that in South Dakota and Wyoming, where nearly 80% report they +wear masks most or all of the time, **fewer than half** of respondents agree that +most or all *other* people wear masks in public places. Only in a few states do +over 90% of respondents agree that most other people wear masks: + +```{r} +joined %>% + filter(value.other >= 90) %>% + arrange(desc(value.other)) %>% + select(geo_value, value.other) %>% + mutate(geo_value = abbr_to_name(geo_value, ignore.case = TRUE)) %>% + knitr::kable(col.names = c("State", "% agree that most/all others are masked"), + digits = 1) +``` + +But we should also be careful in interpreting this. In South Dakota and Wyoming, +fewer than half of respondents agree that most or all other people wear masks. +We can conclude that it's clearly untrue that "everyone wears masks", but this +is not the same thing as saying that fewer than half of people wear masks. For +example, if people interpret "most people wear masks" to mean "I only see one or +two people not wearing masks when I'm in public", "most" could correspond to 80 +or 90% mask use, rather than just 50%. It's not obvious how to translate the +survey question into an estimate of the percent of people wearing masks. So what +can we learn from this? + +## A Probabilistic Argument for Mask Use + +Permit me to discuss some probability theory for a moment. It's fine if you +don't follow the math---the key point will be the probability it allows me to +calculate two paragraphs from now. + +Suppose that the true proportion of people who wear masks in public in a certain +state is $p$. Suppose those people are uniformly distributed throughout the +state. If you go out in a public place and see 20 people, the number of those +people who are wearing masks is a random variable $X$ with distribution +$\text{Binomial}(20, p)$. + +Suppose $p = 0.8$, meaning 80% of people wear masks. With a bit of math, we +find that on a typical trip into public, the chance of seeing **at least 4 +people** not wearing masks is $\Pr(X \leq 16)$, or +**`r round(pbinom(3, size=20, prob=0.2, lower.tail = FALSE) * 100)`%.** To +reduce that chance to 10%, we'd need 91% mask compliance, showing how small +changes in mask usage can cause big changes in risk. + +This means that the apparent contradiction we saw in the graph above---with +respondents claiming that they wear masks but disputing that most others +do---may not be a contradiction. Depending on how respondents interpret "most", +it might be expected. After all, if you wear a mask yourself but then run into +four different people who do not while getting groceries, you could be quite +justified in denying that "most" people wear masks. + +But more importantly, this shows **why a high rate of mask use is so +important.** If 80% of people wear masks, you are still likely to run into +several unmasked people on a trip to any public place, placing you at higher +risk. The problem only gets worse if our assumption that mask use is uniformly +distributed is false, and if people without masks tend to visit the same +locations or events, or gather together for social events, or go out in public +more often than people who do wear masks. + +In short, there are numerous opportunities for COVID transmission even when +over three-quarters of people wear masks. Only a very high rate of mask usage +can dramatically reduce these opportunities. + +## Public Activities, Social Distancing, and Masks + +Earlier, I pointed out that mask use *reduces* the risk of COVID transmission +but does not eliminate it. This is why authorities such as the Centers for +Disease Control and most state health departments [recommend social distancing +together with mask +use](https://www.cdc.gov/coronavirus/2019-ncov/prevent-getting-sick/prevention.html). +This means we can't simply compare states by their level of mask use to see if +masks are working; we must also compare their level of social distancing. + +Our survey asks respondents a series of questions about activities, by asking, +"In the last 24 hours, have you done any of the following?" One possible choice +is "Spent time with someone who isn't currently staying with you"; whether this +is done with a mask or not, it represents a higher risk. And the data shows that +it's done more often in states where fewer people report wearing masks: + +```{r social_distancing, message=FALSE} +spent_time <- covidcast_signal( + "fb-survey", "smoothed_wspent_time_1d", + start_day = "2020-12-01", end_day = "2020-12-01", + geo_type = "state") + +mask_time <- masked %>% + inner_join(spent_time, by = "geo_value", + suffix = c(".mask", ".others")) + +ggplot(mask_time, + aes(x = value.mask, y = value.others, label = toupper(geo_value))) + + geom_text() + + labs(x = "% who report wearing masks most/all the time", + y = "% who spent time with others in past 24 hours", + title = "Social distancing reported in symptom survey", + subtitle = "December 1st, 2020", + caption = "Data from Delphi COVIDcast, delphi.cmu.edu") + + theme_bw() +``` + +Similarly, SafeGraph collects anonymous data on visits to restaurants by using +cell phone location data. Using [state-level aggregates from our +API](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/safegraph.html#safegraph-weekly-patterns), +we can compare mask use to the proportion of people visiting restaurants in each state: + +```{r restaurants, message=FALSE} +# 2020-11-29 was most recent data available at time of writing +restaurants <- covidcast_signal( + "safegraph", "restaurants_visit_prop", + "2020-11-29", "2020-11-29", + geo_type = "state") + +mask_rest <- masked %>% + inner_join(restaurants, by = "geo_value", + suffix = c(".mask", ".restaurant")) + +ggplot(mask_rest, + aes(x = value.mask, y = value.restaurant, label = toupper(geo_value))) + + geom_text() + + labs(x = "% who report wearing masks most/all the time", + y = "Visits by SafeGraph panel, per 100,000 population", + title = "Restaurant visits and mask use", + subtitle = "December 1st, 2020", + caption = "Data from Delphi COVIDcast, delphi.cmu.edu") + + theme_bw() +``` + +These plots suggest that lower mask use is correlated with other risky +behaviors, which combine to produce more opportunities to spread the virus. +While these graphs only show two possible activities, our survey asks about +others---including working outside the home and attending large events---and our +API allows researchers to quickly combine this data with [SafeGraph's other +mobility data](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/safegraph.html")`) +and other data sources that give a clearer picture of how people react to the +pandemic. By studying this aggregate data and the individual survey +responses, it will be possible to examine how mask use is associated with other +social distancing behavior. + +## More Opportunities in Survey Data + +Above, we've seen how our survey data can shed light on mask use in the United +States. Mask use is not as universal as it might seem, and there's substantial +variation between states on mask use and other social distancing behaviors. +Insights like these are important: Using this information about mask use +and activity, authorities can target their emergency orders and provide more +specific advice to the public. + +While a short blog post can't hope to offer a thorough analysis proving which +behaviors reduce spread the most, we make all our data publicly available so +that the public health researchers building detailed models of COVID's spread +can combine it with other data to study how the pandemic spreads and what +interventions are most effective to stop it. + +If you're one of those researchers, or you think this data could be useful for +your reporting or decision-making, see our [COVIDcast Epidata +API](https://cmu-delphi.github.io/delphi-epidata/api/covidcast.html) for details +on how to get it. Numerous aggregates from the survey data, including more +measures of public activity, are [available through the +API](`r blogdown::shortcode_html("apiref", "api/covidcast-signals/fb-survey.html")`), +and can be easily downloaded using [our R and Python +packages](`r blogdown::shortcode_html("apiref", "api/covidcast_clients.html")`). +All aggregates are de-identified to protect the privacy of survey respondents. + +We also make the raw response data available to academic and nonprofit +researchers, and we look forward to seeing more detailed analyses of this data. +For example, it would be important to know if people who do not wear masks are +more likely to do activities near other people, such as attending public events +or spending time with friends who do not live with them, than those who wear +masks regularly. Our survey asks respondents about these types of activities, +allowing us to understand how behavior varies. If you're an academic or +nonprofit researcher and want to do this kind of research, check out our [survey +documentation to get +started](https://cmu-delphi.github.io/delphi-epidata/symptom-survey/). And if +you're interested in similar data in numerous other countries around the world, +check out [the University of Maryland's survey](https://covidmap.umd.edu/), +which runs in over 50 languages worldwide. diff --git a/content/blog/2020-12-10-masks-public.html b/content/blog/2020-12-10-masks-public.html new file mode 100644 index 000000000..8867b97a8 --- /dev/null +++ b/content/blog/2020-12-10-masks-public.html @@ -0,0 +1,457 @@ +--- +title: "Are Masks Widely Used in Public?" +author: "Alex Reinhart" +date: 2020-12-13 +tags: + - symptom surveys + - COVIDcast + - R +authors: +- alex +heroImage: /blog/images/masks-public-full-size.jpg +heroImageThumb: /blog/images/masks-public-thumb.jpg +related: +- 2020-10-06-survey-wave-4 +summary: | + Delphi's symptom surveys reveal rates of mask use across the country. But do they really show that the vast majority of people wear masks? +acknowledgements: | + Wichada La Motte-Kerr drafted numerous survey revisions, collected input from experts, and managed the process of deploying the new survey questions. Sarah LaRocca and Katherine Morris at Facebook gave important input and helped deploy the survey. Kathryn Mazaitis assisted in producing the new aggregate survey data. +output: + blogdown::html_page: + toc: true +--- + + + + + + + +

    As COVID cases and deaths continue to rise in the United States, we are +repeatedly reminded that unless we take the appropriate precautions—by wearing +masks when around other people, working from home whenever possible, and +avoiding travel and crowded places—there will be a high rate of COVID deaths. +Vaccines are on their way, but until they arrive, we must continue social +distancing.

    +

    But after all the precautions we’ve taken and the sacrifices we have made in our +lives during 2020, we have seen many people ask: Why haven’t these precautions +prevented the current COVID spike? Some have even argued that this is proof that +masks and social distancing do not work. Can this claim be justified?

    +

    To answer this question, we must first ask: Is everyone wearing masks? And are +they also socially distancing in other ways? In this post, we’ll show how +Delphi’s COVID symptom surveys can help answer these questions and how they can +enable important research about the pandemic and its spread.

    +
    +

    Studying Mask Use with Surveys

    +

    Since April, and in partnership with Facebook Data for Good and the University +of Maryland, Delphi has }}">conducted daily surveys of +Facebook users +throughout the United States. These surveys ask respondents about their +experiences during the pandemic, and ask whether they’re experiencing symptoms, +whether they are isolating or following precautions, and how they have been +affected by the pandemic. The survey has been completed over 14 million times +since April, allowing us an unprecedented level of insight into COVID and +people’s experiences, down to individual counties around the country.

    +

    }}">Since early +September +we have asked all respondents a question about mask use:

    +
    +

    In the past 5 days, how often did you wear a mask when in public?

    +
      +
    1. All the time
    2. +
    3. Most of the time
    4. +
    5. Some of the time
    6. +
    7. A little of the time
    8. +
    9. None of the time
    10. +
    11. I have not been in public during the past 5 days
    12. +
    +
    +

    Early analysis suggests that mask usage is high in most states, and in those +where it was lower, it has been gradually increasing. For example, the graph +below shows the percentage of respondents who answer “Most of the time” or “All +of the time” in five states and the District of Columbia. In three of these (the +District of Columbia, Massachusetts, and New York), mask usage is among the +highest in the country; in the other three (South Dakota, Idaho, and Wyoming), +it’s among the lowest.

    +
    library(covidcast)
    +library(dplyr)
    +library(ggplot2)
    +library(directlabels)
    +
    +states_of_interest <- c("dc", "ma", "ny", "wy", "sd", "id")
    +
    +state_masks <- covidcast_signal(
    +  "fb-survey", "smoothed_wwearing_mask",
    +  start_day = "2020-09-15", end_day = "2020-12-05",
    +  geo_type = "state", geo_values = states_of_interest
    +)
    +
    +ggplot(state_masks, aes(x = time_value, y = value, color = geo_value)) +
    +  geom_line() +
    +  geom_dl(aes(label = toupper(geo_value)), method = "last.bumpup") +
    +  scale_x_date(date_breaks = "1 month",
    +               date_labels = "%b %Y",
    +               date_minor_breaks = "1 week") +
    +  labs(x = "Date", y = "% wearing masks in public most/all the time",
    +       title = "Self-reported public mask usage",
    +       subtitle = "From Delphi's surveys, conducted through Facebook",
    +       caption = "Data from Delphi COVIDcast, delphi.cmu.edu") +
    +  theme_bw() +
    +  guides(color = FALSE)
    +

    +

    Despite the gap between states, it also seems clear that self-reported mask use +has been on the rise in states whose mask use started low. This is quite +encouraging.

    +

    (Note that, as with most of Delphi’s blog posts, all the code and data used to +make these plots is available—simply click the Code button to see how our }}">API +clients +make it easy to access aggregated data.)

    +

    Seeing these numbers—particularly the very high reported mask usage in many +states—might make you wonder: If mask usage is over 80% in most states and +over 90% in many, why does the rate of new COVID cases in the United States +currently look like this?

    +
    cases <- covidcast_signal(
    +  "indicator-combination", "confirmed_7dav_incidence_num",
    +  start_day = "2020-09-15", end_day = "2020-12-05",
    +  geo_type = "state")
    +
    +cases %>%
    +  group_by(time_value) %>%
    +  summarize(cases = sum(value)) %>%
    +  ggplot(aes(x = time_value, y = cases)) +
    +  geom_line() +
    +  scale_x_date(date_breaks = "1 month",
    +               date_labels = "%b %Y",
    +               date_minor_breaks = "1 week") +
    +  labs(x = "Date", y = "Reported new cases",
    +       title = "Number of reported new cases per day",
    +       subtitle = "7-day rolling average",
    +       caption = "Data from Delphi COVIDcast, delphi.cmu.edu") +
    +  theme_bw()
    +

    +

    While we can’t explain all of COVID in one blog post—nor do we have the data +and science needed to do so—we can address two key questions:

    +
      +
    1. Do the surveys reliably measure mask use in public? If they are biased in +some way, perhaps mask use is not as common as they suggest.
    2. +
    3. Are people adopting other social distancing behaviors alongside masks? If +some people do not wear masks and interact with each other, they may spread +COVID. Also, masks reduce risk; they do not eliminate +it. If people are +working indoors around others, hosting social events, dining indoors, and so +on, but wearing masks, they are nonetheless at greater risk than people who +do none of those things.
    4. +
    +
    +
    +

    Addressing Potential Survey Biases

    +

    To answer the first question, we must consider what kinds of biases could affect +the surveys:

    +
      +
    • Sampling bias. Survey respondents are sampled from Facebook users, but +Facebook users may not be representative of the United States population. +Facebook produces survey weights designed +to help us adjust the survey to match the population’s age and gender +distribution, but there could be other factors besides age and gender that +differ between Facebook users and the United States population generally.
    • +
    • Non-response bias. The survey is voluntary—recruited users are shown an +invitation in their News Feed but can opt not to click on it—and so people +who take the survey might be different in some way. For example, perhaps the +people who take the survey are more concerned about COVID than those who +choose not to, and hence are more likely to wear masks than the general +population. Facebook’s weights try to account for this by estimating the +probability that each person will respond, but it’s difficult to verify that +this probability is estimated correctly.
    • +
    • Social desirability bias. It’s well-known that survey respondents can +prefer answers that seem socially desirable. If mask usage is widely accepted +and there is immense social pressure to comply, someone who does not usually +wear a mask may feel pressure to say they do on a survey. This effect is +likely smaller on an anonymous online survey than it would be in person, but +it could still be present.
    • +
    • Incorrect responses. Some survey respondents may deliberately give +incorrect answers because when you post something on the Internet, inevitably +someone will try to mess with it. Sometimes this is easy to detect (e.g., +people indicating that they are experiencing every symptom of a list of 16 +or that they have -20 family members), but not always.
    • +
    +

    These biases are hard to measure directly. There’s another problem too: If 90% +of people say they wear masks when they’re in public, that doesn’t mean that 90% +of people in public places are wearing masks! For example, if people who wear +masks also tend to limit the amount of time they spend in public places, while +people who do not wear masks spend more time in public, people in public may be +more likely to also be people who don’t wear masks.

    +

    We don’t have a way to tell if a respondent is truthful, and since there’s no +objective national data on the exact percentage of people wearing masks in +public, we have no way to check exactly how biased results could be. We have +seen hints, however: when researchers in Philadelphia studied surveillance +camera footage to count how many people in public places wear masks +correctly, +only 43% did, despite over 90% of Philadelphia respondents to our survey +saying they wear masks most or all of the time. Unfortunately this is only one +study in one city, and doesn’t give us a picture of mask usage nationally.

    +

    After consulting with survey experts, we chose a different way to check our mask +use estimates. In late November, we added a new mask question to the survey:

    +
    +

    In the past 7 days, when out in public places where social distancing is not +possible, about how many people would you estimate wore masks?

    +
      +
    1. All of the people were wearing masks
    2. +
    3. Most of the people were wearing masks
    4. +
    5. Some of the people were wearing masks
    6. +
    7. A few of the people were wearing masks
    8. +
    9. None of the people were wearing masks
    10. +
    11. I have not been out in public places in the past 7 days
    12. +
    +
    +

    Because this question asks about other people, it bypasses social desirability +bias. And even if the survey sample is not representative, as long as the +respondents visit representative public places (like grocery stores or public +transit) and see other people there, we may get a better estimate of public +mask use.

    +

    Let’s see how the data looks. We’ll plot the percentage of people answering +“all” or “most” to each mask question in each state:

    +
    masked <- covidcast_signal(
    +  "fb-survey", "smoothed_wwearing_mask",
    +  start_day = "2020-12-01", end_day = "2020-12-01",
    +  geo_type = "state")
    +
    +other_mask <- covidcast_signal(
    +  "fb-survey", "smoothed_wothers_masked",
    +  start_day = "2020-12-01", end_day = "2020-12-01",
    +  geo_type = "state")
    +
    +joined <- masked %>%
    +  inner_join(other_mask, by = "geo_value",
    +             suffix = c(".self", ".other"))
    +
    +ggplot(joined, aes(x = value.self, y = value.other,
    +                   label = toupper(geo_value))) +
    +  geom_text() +
    +  geom_abline(slope = 1, intercept = 0, linetype = "dashed",
    +              colour = "#888888") +
    +  geom_text(aes(x = 83, y = 85, angle = 15, label = "equal percentages"),
    +            colour = "#888888") +
    +  labs(x = "% who report wearing masks most/all the time",
    +       y = "% who report most/all others wear masks",
    +       title = "Mask use reported in symptom survey",
    +       subtitle = "December 1st, 2020",
    +       caption = "Data from Delphi COVIDcast, delphi.cmu.edu") +
    +  theme_bw()
    +

    +

    There are a few things worthy of note. There is clearly a strong relationship +here—but notice that in South Dakota and Wyoming, where nearly 80% report they +wear masks most or all of the time, fewer than half of respondents agree that +most or all other people wear masks in public places. Only in a few states do +over 90% of respondents agree that most other people wear masks:

    +
    joined %>%
    +  filter(value.other >= 90) %>%
    +  arrange(desc(value.other)) %>%
    +  select(geo_value, value.other) %>%
    +  mutate(geo_value = abbr_to_name(geo_value, ignore.case = TRUE)) %>%
    +  knitr::kable(col.names = c("State", "% agree that most/all others are masked"),
    +               digits = 1)
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    State% agree that most/all others are masked
    Connecticut93.3
    Massachusetts93.3
    District of Columbia92.8
    Vermont92.4
    Maryland91.6
    Rhode Island91.3
    Hawaii91.1
    Delaware90.5
    New Jersey90.3
    New York90.2
    +

    But we should also be careful in interpreting this. In South Dakota and Wyoming, +fewer than half of respondents agree that most or all other people wear masks. +We can conclude that it’s clearly untrue that “everyone wears masks”, but this +is not the same thing as saying that fewer than half of people wear masks. For +example, if people interpret “most people wear masks” to mean “I only see one or +two people not wearing masks when I’m in public”, “most” could correspond to 80 +or 90% mask use, rather than just 50%. It’s not obvious how to translate the +survey question into an estimate of the percent of people wearing masks. So what +can we learn from this?

    + +
    +

    A Probabilistic Argument for Mask Use

    +

    Permit me to discuss some probability theory for a moment. It’s fine if you +don’t follow the math—the key point will be the probability it allows me to +calculate two paragraphs from now.

    +

    Suppose that the true proportion of people who wear masks in public in a certain +state is \(p\). Suppose those people are uniformly distributed throughout the +state. If you go out in a public place and see 20 people, the number of those +people who are wearing masks is a random variable \(X\) with distribution +\(\text{Binomial}(20, p)\).

    +

    Suppose \(p = 0.8\), meaning 80% of people wear masks. With a bit of math, we +find that on a typical trip into public, the chance of seeing at least 4 +people not wearing masks is \(\Pr(X \leq 16)\), or +59%. To +reduce that chance to 10%, we’d need 91% mask compliance, showing how small +changes in mask usage can cause big changes in risk.

    +

    This means that the apparent contradiction we saw in the graph above—with +respondents claiming that they wear masks but disputing that most others +do—may not be a contradiction. Depending on how respondents interpret “most”, +it might be expected. After all, if you wear a mask yourself but then run into +four different people who do not while getting groceries, you could be quite +justified in denying that “most” people wear masks.

    +

    But more importantly, this shows why a high rate of mask use is so +important. If 80% of people wear masks, you are still likely to run into +several unmasked people on a trip to any public place, placing you at higher +risk. The problem only gets worse if our assumption that mask use is uniformly +distributed is false, and if people without masks tend to visit the same +locations or events, or gather together for social events, or go out in public +more often than people who do wear masks.

    +

    In short, there are numerous opportunities for COVID transmission even when +over three-quarters of people wear masks. Only a very high rate of mask usage +can dramatically reduce these opportunities.

    +
    +
    +

    Public Activities, Social Distancing, and Masks

    +

    Earlier, I pointed out that mask use reduces the risk of COVID transmission +but does not eliminate it. This is why authorities such as the Centers for +Disease Control and most state health departments recommend social distancing +together with mask +use. +This means we can’t simply compare states by their level of mask use to see if +masks are working; we must also compare their level of social distancing.

    +

    Our survey asks respondents a series of questions about activities, by asking, +“In the last 24 hours, have you done any of the following?” One possible choice +is “Spent time with someone who isn’t currently staying with you”; whether this +is done with a mask or not, it represents a higher risk. And the data shows that +it’s done more often in states where fewer people report wearing masks:

    +
    spent_time <- covidcast_signal(
    +  "fb-survey", "smoothed_wspent_time_1d",
    +  start_day = "2020-12-01", end_day = "2020-12-01",
    +  geo_type = "state")
    +
    +mask_time <- masked %>%
    +  inner_join(spent_time, by = "geo_value",
    +             suffix = c(".mask", ".others"))
    +
    +ggplot(mask_time,
    +       aes(x = value.mask, y = value.others, label = toupper(geo_value))) +
    +  geom_text() +
    +  labs(x = "% who report wearing masks most/all the time",
    +       y = "% who spent time with others in past 24 hours",
    +       title = "Social distancing reported in symptom survey",
    +       subtitle = "December 1st, 2020",
    +       caption = "Data from Delphi COVIDcast, delphi.cmu.edu") +
    +  theme_bw()
    +

    +

    Similarly, SafeGraph collects anonymous data on visits to restaurants by using +cell phone location data. Using state-level aggregates from our +API, +we can compare mask use to the proportion of people visiting restaurants in each state:

    +
    # 2020-11-29 was most recent data available at time of writing
    +restaurants <- covidcast_signal(
    +  "safegraph", "restaurants_visit_prop",
    +  "2020-11-29", "2020-11-29",
    +  geo_type = "state")
    +
    +mask_rest <- masked %>%
    +  inner_join(restaurants, by = "geo_value",
    +             suffix = c(".mask", ".restaurant"))
    +
    +ggplot(mask_rest,
    +       aes(x = value.mask, y = value.restaurant, label = toupper(geo_value))) +
    +  geom_text() +
    +  labs(x = "% who report wearing masks most/all the time",
    +       y = "Visits by SafeGraph panel, per 100,000 population",
    +       title = "Restaurant visits and mask use",
    +       subtitle = "December 1st, 2020",
    +       caption = "Data from Delphi COVIDcast, delphi.cmu.edu") +
    +  theme_bw()
    +

    +

    These plots suggest that lower mask use is correlated with other risky +behaviors, which combine to produce more opportunities to spread the virus. +While these graphs only show two possible activities, our survey asks about +others—including working outside the home and attending large events—and our +API allows researchers to quickly combine this data with }}">SafeGraph’s other +mobility data +and other data sources that give a clearer picture of how people react to the +pandemic. By studying this aggregate data and the individual survey +responses, it will be possible to examine how mask use is associated with other +social distancing behavior.

    +
    +
    +

    More Opportunities in Survey Data

    +

    Above, we’ve seen how our survey data can shed light on mask use in the United +States. Mask use is not as universal as it might seem, and there’s substantial +variation between states on mask use and other social distancing behaviors. +Insights like these are important: Using this information about mask use +and activity, authorities can target their emergency orders and provide more +specific advice to the public.

    +

    While a short blog post can’t hope to offer a thorough analysis proving which +behaviors reduce spread the most, we make all our data publicly available so +that the public health researchers building detailed models of COVID’s spread +can combine it with other data to study how the pandemic spreads and what +interventions are most effective to stop it.

    +

    If you’re one of those researchers, or you think this data could be useful for +your reporting or decision-making, see our COVIDcast Epidata +API for details +on how to get it. Numerous aggregates from the survey data, including more +measures of public activity, are }}">available through the +API, +and can be easily downloaded using }}">our R and Python +packages. +All aggregates are de-identified to protect the privacy of survey respondents.

    +

    We also make the raw response data available to academic and nonprofit +researchers, and we look forward to seeing more detailed analyses of this data. +For example, it would be important to know if people who do not wear masks are +more likely to do activities near other people, such as attending public events +or spending time with friends who do not live with them, than those who wear +masks regularly. Our survey asks respondents about these types of activities, +allowing us to understand how behavior varies. If you’re an academic or +nonprofit researcher and want to do this kind of research, check out our survey +documentation to get +started. And if +you’re interested in similar data in numerous other countries around the world, +check out the University of Maryland’s survey, +which runs in over 50 languages worldwide.

    +
    diff --git a/content/covidcast/_index.md b/content/covidcast/_index.md index b8bffa322..d0e3e71b2 100644 --- a/content/covidcast/_index.md +++ b/content/covidcast/_index.md @@ -1,14 +1,4 @@ --- title: COVIDCast -type: covidcast_app -scripts: - - ./covidcast/vendors.js - - ./covidcast/styles.js - - ./covidcast/bundle.js -styles: - - ./covidcast/vendors.css - - ./covidcast/styles.css +layout: covidcast_app --- - - -{{}} diff --git a/content/covidcast/indicators/cases.md b/content/covidcast/indicators/cases.md deleted file mode 100644 index 77ecd3fea..000000000 --- a/content/covidcast/indicators/cases.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Cases -category: official -order: 10 ---- - -These indicators show the number of new confirmed COVID-19 cases per day. The maps reflect only cases confirmed by state and local health authorities. They are based on confirmed case counts compiled and made public by [a team at Johns Hopkins University](https://systems.jhu.edu/research/public-health/ncov/) and by [USAFacts](https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/). We use Johns Hopkins data for Puerto Rico and report USAFacts data in all other locations. \ No newline at end of file diff --git a/content/covidcast/indicators/combined.md b/content/covidcast/indicators/combined.md deleted file mode 100644 index fb8ee55fa..000000000 --- a/content/covidcast/indicators/combined.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Combined -category: active -order: 80 ---- - -The “Combined” map represents a combination of all the indicators currently featured on the public map. As of this writing, this includes Doctor Visits, Symptoms (Facebook), Symptoms in Community (Facebook), and Search Trends. It does not include official reports (cases and deaths), hospital admissions, or SafeGraph signals. We use a rank-1 approximation, from a nonnegative matrix factorization approach, to identify an underlying signal that best reconstructs the indicators. Higher values of the combined signal correspond to higher values of the other indicators, but the scale (units) of the combination is arbitrary. \ No newline at end of file diff --git a/content/covidcast/indicators/deaths.md b/content/covidcast/indicators/deaths.md deleted file mode 100644 index 5e2c52da9..000000000 --- a/content/covidcast/indicators/deaths.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Deaths -category: official -order: 20 ---- - -These indicators shows the number of COVID-19 related deaths per day. The maps reflect official figures by state and local health authorities, and may not include excess deaths not confirmed as due to COVID-19 by health authorities. They are based on confirmed death counts compiled and made public by [a team at Johns Hopkins University](https://systems.jhu.edu/research/public-health/ncov/) and by [USAFacts](https://usafacts.org/visualizations/coronavirus-covid-19-spread-map/). We use Johns Hopkins data for Puerto Rico and report USAFacts data in all other locations. \ No newline at end of file diff --git a/content/covidcast/indicators/doctor-visits.md b/content/covidcast/indicators/doctor-visits.md deleted file mode 100644 index 780550e3a..000000000 --- a/content/covidcast/indicators/doctor-visits.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Doctor Visits -category: active -order: 10 ---- - -This indicator estimates the percentage of outpatient doctor’s visits that are due to COVID-like symptoms, based on data provided to us by health system partners. Tele-medicine visits are included in these estimates. \ No newline at end of file diff --git a/content/covidcast/indicators/google-trends.md b/content/covidcast/indicators/google-trends.md deleted file mode 100644 index ff0d04b28..000000000 --- a/content/covidcast/indicators/google-trends.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Search Trends (Google) -category: active -order: 70 ---- - -This indicator is based on the number of Google searches for COVID-related topics, relative to each area’s population, based on Google search statistics provided to us by Google’s Health Trends group. A larger number corresponds to more COVID-related searching. \ No newline at end of file diff --git a/content/covidcast/indicators/hospital-admissions.md b/content/covidcast/indicators/hospital-admissions.md deleted file mode 100644 index 1cbd96039..000000000 --- a/content/covidcast/indicators/hospital-admissions.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Hospital Admissions -category: active -order: 20 ---- - -This indicator estimates the percentage of daily hospital admissions that have diagnostic codes related to COVID-19, based on medical claims summaries provided to us by health system partners. \ No newline at end of file diff --git a/content/covidcast/indicators/index.md b/content/covidcast/indicators/index.md deleted file mode 100644 index 3d65eaa0f..000000000 --- a/content/covidcast/indicators/index.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -headless: true ---- \ No newline at end of file diff --git a/content/covidcast/indicators/quidel-flu.md b/content/covidcast/indicators/quidel-flu.md deleted file mode 100644 index ba706c2d0..000000000 --- a/content/covidcast/indicators/quidel-flu.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Flu Tests (Quidel) -category: archived -order: 20 ---- - -(Archived) This indicator is based on data about influenza lab tests provided to us by Quidel, Inc., a company that makes equipment and kits for medical tests. When a patient (whether at a doctor’s office, clinic, or hospital) has COVID-like symptoms, standard practice currently is to perform a conventional influenza test to rule out seasonal influenza (flu), because these two diseases have similar symptoms. While the number of COVID tests performed depends on local capacity and testing policy, influenza testing is not influenced by these factors. Because a different number of labs may report on different days, we track the average number of flu tests performed per flu testing device (in a given location and on a given day). \ No newline at end of file diff --git a/content/covidcast/indicators/quidel.md b/content/covidcast/indicators/quidel.md deleted file mode 100644 index 2a1777e56..000000000 --- a/content/covidcast/indicators/quidel.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: COVID-19 Antigen Tests (Quidel) -category: active -order: 60 ---- - -This indicator estimates the percentage of COVID-19 antigen tests that come back positive, based on testing data provided to us by Quidel, Inc., a company that makes equipment and kits for medical tests. When a patient (whether at a doctor’s office, clinic, or hospital) has COVID-like symptoms, doctors may order an antigen test. An antigen test can detect parts of the virus that are present during an active infection. Note that this data may differ from testing figures reported by state and local health authorities, as it only includes Quidel’s COVID-19 antigen tests, not those from other testing providers. \ No newline at end of file diff --git a/content/covidcast/indicators/safegraph.md b/content/covidcast/indicators/safegraph.md deleted file mode 100644 index b6315e2a2..000000000 --- a/content/covidcast/indicators/safegraph.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Hours Away from Home (SafeGraph) -category: active -order: 50 ---- - -These indicators estimate the proportion of people who spend time outside their homes during daytime hours, using mobile device location data provided by SafeGraph. “Away from Home 6hr+” is the proportion spending more than 6 hours outside their home, while “Away from Home 3-6hr” is the proportion spending between 3 and 6 hours outside their home. These estimates may be related to the spread of COVID-19, since they are related to the number of people interacting with others outside their homes, and also reveal the impact of the pandemic and movement restrictions. \ No newline at end of file diff --git a/content/covidcast/indicators/survey-google.md b/content/covidcast/indicators/survey-google.md deleted file mode 100644 index 63536b734..000000000 --- a/content/covidcast/indicators/survey-google.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Surveys (Google) -category: archived -order: 10 ---- - -(Paused) This indicator estimates the percentage of people who *know someone in their community* with a COVID-like illness (fever, along with cough, or shortness of breath, or difficulty breathing). The data is based on Google-run symptom surveys, through publisher websites, Google's Opinions Reward app, and similar applications. These surveys are voluntary. As of mid April, about 600,000 people answered the survey daily throughout the U.S. Note that these Google surveys are estimating a different quantity than the surveys given to Facebook users (percentage of people who *know someone in their community* who is sick, rather than percentage of people who are sick), so the estimates from the Google surveys tend to be larger. \ No newline at end of file diff --git a/content/covidcast/indicators/symptoms-community-fb.md b/content/covidcast/indicators/symptoms-community-fb.md deleted file mode 100644 index 26e789fe3..000000000 --- a/content/covidcast/indicators/symptoms-community-fb.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Symptoms in Community (Facebook) -category: active -order: 40 ---- - -This indicator estimates the percentage of people who *know someone in their community* with a COVID-like illness (fever, along with cough, or shortness of breath, or difficulty breathing). The data is based on the same [CMU-run survey]({{}}), advertised by Facebook, as is used for the Symptoms indicator. Note that more people tend to report knowing someone in their community with a COVID-like illness than having someone in their own household with a COVID-like illness, so these numbers are higher than the household symptoms survey. \ No newline at end of file diff --git a/content/covidcast/indicators/symptoms-fb.md b/content/covidcast/indicators/symptoms-fb.md deleted file mode 100644 index d6092a4d7..000000000 --- a/content/covidcast/indicators/symptoms-fb.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Symptoms (Facebook) -category: active -order: 30 ---- - -This indicator estimates the percentage of people who have a COVID-like illness (fever, along with cough, or shortness of breath, or difficulty breathing), based on [symptom surveys run by Carnegie Mellon]({{}}). The surveys ask respondents how many people in their household are experiencing COVID-like symptoms, among other questions. Facebook directs a random sample of its users to these surveys, which are voluntary. Individual survey responses are held by CMU and are shareable with other health researchers under a data use agreement. No individual survey responses are shared back to Facebook. As of mid-June, about 70,000 such surveys were completed daily throughout the U.S. \ No newline at end of file diff --git a/content/covidcast/methodology.md b/content/covidcast/methodology.md deleted file mode 100644 index 7fcbd3916..000000000 --- a/content/covidcast/methodology.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: About Our Data and Methodology ---- - -The COVID-19 indicators visualized on our map are derived from the data sources described below. These are all publicly available on the [COVIDcast endpoint]({{< apiref "api/covidcast.html">}}) of our public [Epidata API]({{< apiref "api/README.html">}}). The API documentation includes [full technical detail]({{< apiref "api/covidcast_signals.html">}}) on how these indicators are calculated. - - -## Active Indicators - -{{}} - -## Official Reports - -{{}} - -## Paused and Retired Indicators - -{{}} - -## About Our Methodology - -Full technical documentation on the sources of our data, and how our estimates are constructed, is available in the [COVIDcast API data source documentation]({{< apiref "api/covidcast_signals.html">}}). - -### Live Estimates - -The real-time COVID-19 indicators presented on the COVIDcast site represent our *best estimates given all data that we have available up until now*. For example, the estimates on our site for April 24, 2020 represent our current best estimate of the indicator values for that day. The first estimates for the indicator values for April 24 would typically be available on April 25 (one day later), but estimates for these April 24 values may be updated on later days as new data becomes available. This phenomenon is particularly prominent with the Doctor Visits indicator, which is based on doctor’s visits that do or do not involve COVID-like illnesses: there is generally a lag in how some of the data is made available to us, and a large fraction of doctor’s visits on any day is only reported to us several days later. For that reason, our Doctor Visits estimates that are just a few days old may be less reliable. When we deem them too unreliable, we do not post them, which is why this indicator is often available only up until a few days before the current day. - -### Smoothing - -For each indicator, our estimates are formed using data smoothing techniques. The individual smoothing technique differs based on the indicator, but in all cases, we perform some kind of data smoothing (akin to averaging, or weighted averaging) across an approximately one week window. - - -### Missing Estimates - -Generally, we do not report estimates at locations with insufficient data (or insufficiently recent data). The Search Trends indicator is not available at the county level, as data is only available at a coarser geographic resolution in the first place. For the Doctor Visits and Facebook Surveys indicators, we lump together all counties in a given state that do not have sufficient data for their own individual estimate, and create a “rest of state” estimate that includes all of them. - - -### Intensity Heat map - -The “Intensity” view presents a heat map of these estimates. For each indicator, we use a fixed range of values, from a “low” value to a “high” value, and assign a color to each value in between, as shown to the left of the map. These “low” and “high” values are different for each indicator, but for a given indicator, they are constant across time and geographic hierarchy, meaning that the heat maps are comparable across days. At the county level, the “rest of state” estimates are plotted in semi-transparent colors, to make the individual counties where estimates are made more easily visually distinguishable. diff --git a/content/covidcast/release-log/_index.md b/content/covidcast/release-log/_index.md index 07688c1f7..49bc629bc 100644 --- a/content/covidcast/release-log/_index.md +++ b/content/covidcast/release-log/_index.md @@ -3,4 +3,4 @@ title: Release Log layout: single --- -{{}} \ No newline at end of file +{{}} diff --git a/content/covidcast/release-log/headless/index.md b/content/covidcast/release-log/headless/index.md index 46ca3e791..441ef3a5a 100644 --- a/content/covidcast/release-log/headless/index.md +++ b/content/covidcast/release-log/headless/index.md @@ -1,4 +1,4 @@ --- # flag to disable rendering individual pages headless: true ---- \ No newline at end of file +--- diff --git a/content/covidcast/release-log/headless/v1.1.md b/content/covidcast/release-log/headless/v1.1.md index 20d14ba7c..bab731ab5 100644 --- a/content/covidcast/release-log/headless/v1.1.md +++ b/content/covidcast/release-log/headless/v1.1.md @@ -8,4 +8,3 @@ date: 2020-05-07 - New map: The “Confirmed Cases (JHU)” map shows confirmed case ratios (cases per 100,000 population) of COVID-19 per day. This reflects official figures reporting cases confirmed by testing to be COVID-19, [as compiled by a team at Johns Hopkins University](https://systems.jhu.edu/research/public-health/ncov/). - The “Flu Testing (Quidel)” map is no longer shown. During flu season, rates of flu tests may have correlated with rates of COVID-like illnesses, as many doctors who suspected COVID-19 conducted flu tests to rule out influenza. However, the end of flu season means few flu tests are currently conducted. - Previously, the “Search Trends (Google)” signal reported search volume on each day on the map for the following day; for example, search volume on April 16 would be mapped as occurring on April 17. This is no longer done. - diff --git a/content/covidcast/release-log/headless/v1.11.0.md b/content/covidcast/release-log/headless/v1.11.0.md index a18ad52b7..3a6b27827 100644 --- a/content/covidcast/release-log/headless/v1.11.0.md +++ b/content/covidcast/release-log/headless/v1.11.0.md @@ -1,51 +1,51 @@ ---- -title: v1.11.0 -date: 2020-12-02 ---- - -This release changes COVIDcast from a complete site to an embedded component, primarily to the [www-main](https://github.com/cmu-delphi/www-covidcast) repository, which serves the Delphi homepage. This means that instead of having both covidcast.cmu.edu and delphi.cmu.edu separately, we will now have delphi.cmu.edu and covidcast will live at delphi.cmu.edu/covidcast. - -The are only minor changes to the COVIDcast visualization itself, which was why this is marked as 1.11.0 instead of 2.0. - -#### Signal Changes - -- "COVID Searches on Google" is now "COVID Symptom Searches on Google". For more details see: [`google-symptoms` `sum_anosmia_ageusia_smoothed_search`](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/google-symptoms.html) signal. -- New "Bar Visits" signal from Safegraph. For more details see: [`safegraph` `bars_visit_num` and `bars_visit_prop`](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/safegraph.html#safegraph-weekly-patterns). -- New "Restaurant Visits" signal from Safegraph. For more details see: [`safegraph` `restaurants_visit_num` and `restaurants_visit_prop`](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/safegraph.html#safegraph-weekly-patterns) -- "Away from home" signals replaced by smoothed versions to remove the weekend effect. For more details see: [`safegraph` `full_time_work_prop_7dav` and `part_time_work_prop_7dav`](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/safegraph.html#safegraph-social-distancing-metrics) - -#### New features - -- [#610](https://github.com/cmu-delphi/www-covidcast/pull/610) (re: [#593](https://github.com/cmu-delphi/www-covidcast/issues/593)) Hospital referal regions now available as a geo type -- [#636](https://github.com/cmu-delphi/www-covidcast/pull/636) (re: [#631](https://github.com/cmu-delphi/www-covidcast/issues/631)) Change to embedded version - -#### Improvements - -- [#629](https://github.com/cmu-delphi/www-covidcast/pull/629) (re: [#599](https://github.com/cmu-delphi/www-covidcast/issues/599)) Additional export infos -- [#650](https://github.com/cmu-delphi/www-covidcast/pull/650) (re: [#649](https://github.com/cmu-delphi/www-covidcast/issues/649)) Research disclaimer -- [#628](https://github.com/cmu-delphi/www-covidcast/pull/628) (re: [#624](https://github.com/cmu-delphi/www-covidcast/issues/624)) Limit add another to same geo level -- [#630](https://github.com/cmu-delphi/www-covidcast/pull/630) (re: [#598](https://github.com/cmu-delphi/www-covidcast/issues/598)) Restore focus upon dialog close -- [#587](https://github.com/cmu-delphi/www-covidcast/pull/587) (re: [#460](https://github.com/cmu-delphi/www-covidcast/issues/460), and others) Generate changelog from PRs -- [#653](https://github.com/cmu-delphi/www-covidcast/pull/653) More robust missing meta data handling -- [#633](https://github.com/cmu-delphi/www-covidcast/pull/633) (re: [#625](https://github.com/cmu-delphi/www-covidcast/issues/625)) Improve detail view (axis) labels -- [#641](https://github.com/cmu-delphi/www-covidcast/pull/641) (re: [#623](https://github.com/cmu-delphi/www-covidcast/issues/623)) Preserve modified date range while DetailView is displayed. -- [#575](https://github.com/cmu-delphi/www-covidcast/pull/575) (re: [#569](https://github.com/cmu-delphi/www-covidcast/issues/569)) Improve whitespace for small multiples -- [#588](https://github.com/cmu-delphi/www-covidcast/pull/588) (re: [#586](https://github.com/cmu-delphi/www-covidcast/issues/586)) Improve hover behavior on charts -- [#614](https://github.com/cmu-delphi/www-covidcast/pull/614) (re: [#589](https://github.com/cmu-delphi/www-covidcast/issues/589)) Render line chart with clipped regions. -- [#454](https://github.com/cmu-delphi/www-covidcast/pull/454) Create staging environment setup -- [#604](https://github.com/cmu-delphi/www-covidcast/pull/604) Add testing environment -- [#591](https://github.com/cmu-delphi/www-covidcast/pull/591) Improve vega tooltip styling -- [#585](https://github.com/cmu-delphi/www-covidcast/pull/585) (re: [#582](https://github.com/cmu-delphi/www-covidcast/issues/582)) Possible fix for single region vega -- [#573](https://github.com/cmu-delphi/www-covidcast/pull/573) (re: [#484](https://github.com/cmu-delphi/www-covidcast/issues/484)) Improve chart headers and layout - -#### Bug-fixes - -- [#635](https://github.com/cmu-delphi/www-covidcast/pull/635) Date range initial selection was lost -- [#605](https://github.com/cmu-delphi/www-covidcast/pull/605) (re: [#602](https://github.com/cmu-delphi/www-covidcast/issues/602), [#603](https://github.com/cmu-delphi/www-covidcast/issues/603)) County name generation -- [#652](https://github.com/cmu-delphi/www-covidcast/pull/652) (re: [#637](https://github.com/cmu-delphi/www-covidcast/issues/637)) Reduce layout flicker on Region Details -- [#654](https://github.com/cmu-delphi/www-covidcast/pull/654) Style: fix some of the most obvious uikit bugs -- [#643](https://github.com/cmu-delphi/www-covidcast/pull/643) (re: [#586](https://github.com/cmu-delphi/www-covidcast/issues/586)) Avoid flickering tooltips on small multiples -- [#638](https://github.com/cmu-delphi/www-covidcast/pull/638) Bugfix: detecting proper death signal -- [#617](https://github.com/cmu-delphi/www-covidcast/pull/617) (re: [#615](https://github.com/cmu-delphi/www-covidcast/issues/615)) Use correct field when computing max of values. -- [#613](https://github.com/cmu-delphi/www-covidcast/pull/613) (re: [#611](https://github.com/cmu-delphi/www-covidcast/issues/611)) Fix tooltip for calendar option -- [#608](https://github.com/cmu-delphi/www-covidcast/pull/608) (re: [#607](https://github.com/cmu-delphi/www-covidcast/issues/607)) Fix mouseout and mouseover flickers \ No newline at end of file +--- +title: v1.11.0 +date: 2020-12-02 +--- + +This release changes COVIDcast from a complete site to an embedded component, primarily to the [www-main](https://github.com/cmu-delphi/www-covidcast) repository, which serves the Delphi homepage. This means that instead of having both covidcast.cmu.edu and delphi.cmu.edu separately, we will now have delphi.cmu.edu and covidcast will live at delphi.cmu.edu/covidcast. + +The are only minor changes to the COVIDcast visualization itself, which was why this is marked as 1.11.0 instead of 2.0. + +#### Signal Changes + +- "COVID Searches on Google" is now "COVID Symptom Searches on Google". For more details see: [`google-symptoms` `sum_anosmia_ageusia_smoothed_search`](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/google-symptoms.html) signal. +- New "Bar Visits" signal from Safegraph. For more details see: [`safegraph` `bars_visit_num` and `bars_visit_prop`](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/safegraph.html#safegraph-weekly-patterns). +- New "Restaurant Visits" signal from Safegraph. For more details see: [`safegraph` `restaurants_visit_num` and `restaurants_visit_prop`](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/safegraph.html#safegraph-weekly-patterns) +- "Away from home" signals replaced by smoothed versions to remove the weekend effect. For more details see: [`safegraph` `full_time_work_prop_7dav` and `part_time_work_prop_7dav`](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/safegraph.html#safegraph-social-distancing-metrics) + +#### New features + +- [#610](https://github.com/cmu-delphi/www-covidcast/pull/610) (re: [#593](https://github.com/cmu-delphi/www-covidcast/issues/593)) Hospital referal regions now available as a geo type +- [#636](https://github.com/cmu-delphi/www-covidcast/pull/636) (re: [#631](https://github.com/cmu-delphi/www-covidcast/issues/631)) Change to embedded version + +#### Improvements + +- [#629](https://github.com/cmu-delphi/www-covidcast/pull/629) (re: [#599](https://github.com/cmu-delphi/www-covidcast/issues/599)) Additional export infos +- [#650](https://github.com/cmu-delphi/www-covidcast/pull/650) (re: [#649](https://github.com/cmu-delphi/www-covidcast/issues/649)) Research disclaimer +- [#628](https://github.com/cmu-delphi/www-covidcast/pull/628) (re: [#624](https://github.com/cmu-delphi/www-covidcast/issues/624)) Limit add another to same geo level +- [#630](https://github.com/cmu-delphi/www-covidcast/pull/630) (re: [#598](https://github.com/cmu-delphi/www-covidcast/issues/598)) Restore focus upon dialog close +- [#587](https://github.com/cmu-delphi/www-covidcast/pull/587) (re: [#460](https://github.com/cmu-delphi/www-covidcast/issues/460), and others) Generate changelog from PRs +- [#653](https://github.com/cmu-delphi/www-covidcast/pull/653) More robust missing meta data handling +- [#633](https://github.com/cmu-delphi/www-covidcast/pull/633) (re: [#625](https://github.com/cmu-delphi/www-covidcast/issues/625)) Improve detail view (axis) labels +- [#641](https://github.com/cmu-delphi/www-covidcast/pull/641) (re: [#623](https://github.com/cmu-delphi/www-covidcast/issues/623)) Preserve modified date range while DetailView is displayed. +- [#575](https://github.com/cmu-delphi/www-covidcast/pull/575) (re: [#569](https://github.com/cmu-delphi/www-covidcast/issues/569)) Improve whitespace for small multiples +- [#588](https://github.com/cmu-delphi/www-covidcast/pull/588) (re: [#586](https://github.com/cmu-delphi/www-covidcast/issues/586)) Improve hover behavior on charts +- [#614](https://github.com/cmu-delphi/www-covidcast/pull/614) (re: [#589](https://github.com/cmu-delphi/www-covidcast/issues/589)) Render line chart with clipped regions. +- [#454](https://github.com/cmu-delphi/www-covidcast/pull/454) Create staging environment setup +- [#604](https://github.com/cmu-delphi/www-covidcast/pull/604) Add testing environment +- [#591](https://github.com/cmu-delphi/www-covidcast/pull/591) Improve vega tooltip styling +- [#585](https://github.com/cmu-delphi/www-covidcast/pull/585) (re: [#582](https://github.com/cmu-delphi/www-covidcast/issues/582)) Possible fix for single region vega +- [#573](https://github.com/cmu-delphi/www-covidcast/pull/573) (re: [#484](https://github.com/cmu-delphi/www-covidcast/issues/484)) Improve chart headers and layout + +#### Bug-fixes + +- [#635](https://github.com/cmu-delphi/www-covidcast/pull/635) Date range initial selection was lost +- [#605](https://github.com/cmu-delphi/www-covidcast/pull/605) (re: [#602](https://github.com/cmu-delphi/www-covidcast/issues/602), [#603](https://github.com/cmu-delphi/www-covidcast/issues/603)) County name generation +- [#652](https://github.com/cmu-delphi/www-covidcast/pull/652) (re: [#637](https://github.com/cmu-delphi/www-covidcast/issues/637)) Reduce layout flicker on Region Details +- [#654](https://github.com/cmu-delphi/www-covidcast/pull/654) Style: fix some of the most obvious uikit bugs +- [#643](https://github.com/cmu-delphi/www-covidcast/pull/643) (re: [#586](https://github.com/cmu-delphi/www-covidcast/issues/586)) Avoid flickering tooltips on small multiples +- [#638](https://github.com/cmu-delphi/www-covidcast/pull/638) Bugfix: detecting proper death signal +- [#617](https://github.com/cmu-delphi/www-covidcast/pull/617) (re: [#615](https://github.com/cmu-delphi/www-covidcast/issues/615)) Use correct field when computing max of values. +- [#613](https://github.com/cmu-delphi/www-covidcast/pull/613) (re: [#611](https://github.com/cmu-delphi/www-covidcast/issues/611)) Fix tooltip for calendar option +- [#608](https://github.com/cmu-delphi/www-covidcast/pull/608) (re: [#607](https://github.com/cmu-delphi/www-covidcast/issues/607)) Fix mouseout and mouseover flickers diff --git a/content/covidcast/release-log/headless/v1.11.1.md b/content/covidcast/release-log/headless/v1.11.1.md new file mode 100644 index 000000000..e5e1dc00a --- /dev/null +++ b/content/covidcast/release-log/headless/v1.11.1.md @@ -0,0 +1,9 @@ +--- +title: v1.11.1 +date: 2020-12-11 +--- + +#### Signal Changes + +* Removed "COVID Symptom Searches on Google" signal. +* Replaced "COVID-Related Doctor Visits" with new signal from Change Healthcare. For more details see: [`chng`:`smoothed_outpatient_cli`](https://cmu-delphi.github.io/delphi-epidata/api/covidcast-signals/chng.html) diff --git a/content/covidcast/release-log/headless/v1.2.md b/content/covidcast/release-log/headless/v1.2.md index 4693ff7f1..4d2259fbb 100644 --- a/content/covidcast/release-log/headless/v1.2.md +++ b/content/covidcast/release-log/headless/v1.2.md @@ -4,6 +4,6 @@ date: 2020-05-20 --- - New map: The “Combined” signal represents a statistical combination of the other indicators, not including the official reports (cases and deaths). For more information how this indicator is calculated, see the details above in the list of indicators. -- New map: The “Symptoms in Community (Facebook)” map shows the estimated fraction of people who know someone with a COVID-like illness in their local community. +- New map: The “Symptoms in Community (Facebook)” map shows the estimated fraction of people who know someone with a COVID-like illness in their local community. - The “Surveys (Facebook)” map has been renamed “Symptoms (Facebook)”, to reflect that it asks respondents whether people in their household have COVID-like symptoms. - The “Surveys (Google)” map has been removed. This data is still available in the public Epidata API, but new data will not be collected. diff --git a/content/covidcast/release-log/headless/v1.3.md b/content/covidcast/release-log/headless/v1.3.md index 0f1ee8fb1..4b1e6c68f 100644 --- a/content/covidcast/release-log/headless/v1.3.md +++ b/content/covidcast/release-log/headless/v1.3.md @@ -4,7 +4,7 @@ date: 2020-06-10 --- - The COVIDcast map now includes Puerto Rico. Not all data sources are available for Puerto Rico, but data will be displayed when available. -- The “Combined” signal now includes standard error bands when viewing the time series plot for a specific geographical area, representing the estimated uncertainty in this signal. This uncertainty comes because the signal is a combination of the other signals which are based on survey estimates or other estimates with margins of error. Details on how the standard error bands are calculated will be made available in the detailed methodology document [linked above]({{}}). +- The “Combined” signal now includes standard error bands when viewing the time series plot for a specific geographical area, representing the estimated uncertainty in this signal. This uncertainty comes because the signal is a combination of the other signals which are based on survey estimates or other estimates with margins of error. - Tooltips for the official Cases and Deaths signals have been updated to contain the population, raw count, and count per 100,000 people, to help distinguish sparsely-populated areas with one or two cases from dense urban areas with more total cases but an apparently lower rate per 100,000 people. - Fixed a bug that inflated the color value for per capita Cases and Deaths relative to the legend. - Other small bug fixes and improvements in the COVIDcast map. diff --git a/content/covidcast/surveys.md b/content/covidcast/surveys.md index 3eaf55776..832ab7616 100644 --- a/content/covidcast/surveys.md +++ b/content/covidcast/surveys.md @@ -2,14 +2,13 @@ title: Delphi's COVID-19 Surveys --- -In collaboration with Facebook, along with a consortium of universities and public health officials, the [Delphi group]({{< relref "/" >}}) at [Carnegie Mellon University](https://www.cmu.edu/) conducts research surveys to monitor the spread and impact of the COVID-19 pandemic in the United States. This survey is advertised through Facebook. It has run continuously since early April 2020, and about 70,000 people in the United States participate **every day**. Survey results are publicly available on our [COVIDcast map]({{< relref "covidcast" >}}) and in our [COVIDcast API]({{< apiref "api/covidcast.html" >}}). +In collaboration with Facebook, along with a consortium of universities and public health officials, the [Delphi group]({{< relref "/" >}}) at [Carnegie Mellon University](https://www.cmu.edu/) conducts research surveys to monitor the spread and impact of the COVID-19 pandemic in the United States. This survey is advertised through Facebook. It has run continuously since early April 2020, and about 50,000 people in the United States participate **every day**. Survey results are publicly available on our [COVIDcast map]({{< relref "covidcast" >}}) and in our [COVIDcast API]({{< apiref "api/covidcast.html" >}}). Such detailed data has never before been available during a public health emergency, and it will help public health officials understand how to save lives and how to safely reopen public life. The data will also help researchers understand the social, economic, and health effects of the COVID-19 pandemic. An international version of the survey is conducted by the University of Maryland in collaboration with Facebook. Its data [is available separately](https://covidmap.umd.edu/). MIT also conducts a global [Beliefs, Behaviors and Norms survey](https://covidsurvey.mit.edu/), also through Facebook, whose data is available for research. -**New!** The [Symptom Data Challenge](https://www.symptomchallenge.org/) challenges participants to enable earlier detection and improved situational awareness of the COVID-19 outbreak by using data from these symptom surveys. Submissions are due by Tuesday, October 6th, 2020, and finalists are eligible to win cash prizes. See [the challenge website](https://www.symptomchallenge.org/) for more details. - +The [Symptom Data Challenge](https://www.symptomchallenge.org/) challenged participants to enable earlier detection and improved situational awareness of the COVID-19 outbreak by using data from these symptom surveys. Check out the [the challenge website](https://www.symptomchallenge.org/) for more details about the Challenge and the finalists. ## What are the surveys for? @@ -19,14 +18,12 @@ Delphi uses information from the survey as part of its public [COVIDcast map]({{ Because the survey can reach thousands of respondents every day, its questions focus on what the respondents are experiencing right now. This allows us to track how conditions change across the country every day. - ## Who is running these surveys? The surveys are a collaboration between [Delphi]({{< relref "/" >}}) at Carnegie Mellon University, numerous universities, and Facebook. Researchers at many institutions are analyzing the survey data and assisting in the survey’s development. The survey protocol has been reviewed by the Carnegie Mellon University Institutional Review Board. Delphi only publicly releases aggregate data; de-identified individual data is made available to research partners. Our partners are bound by data use agreements to maintain the confidentiality of individual survey responses. Facebook refers its users to the survey, but it does not receive any individual survey data. - ## How are the surveys distributed? Participants are recruited for the surveys through an advertisement placed in their Facebook news feed. Facebook automatically selects a random sample of its users to see the advertisement; users who click on the ad are taken to a survey administered by Carnegie Mellon University, and Facebook does not see their survey responses. The survey is available in English, Spanish, Brazilian Portuguese, Vietnamese, French, and simplified Chinese. @@ -35,14 +32,13 @@ The survey participants are sampled from Facebook users, rather than being a ran To account for the differences between Facebook users and the United States population, Facebook includes a unique identifier when it links users to the survey. Carnegie Mellon collects these identifiers and provides Facebook with a list of identifiers that completed the survey; Facebook then calculates statistical weights indicating how representative each person is of the United States population, based on demographic data known to Facebook. Crucially, Carnegie Mellon cannot use these identifiers to identify specific Facebook users, and Facebook never receives individual survey responses and cannot link them to specific users. - ## Where can I see the results? -Our [COVIDcast map]({{< relref "covidcast" >}}) shows basic aggregate survey results, revealing the rate of COVID-like symptoms across the United States, and this data is also freely available for download through the [COVIDcast API]({{< apiref "api/covidcast.html">}}). Facebook also publishes [a map](https://covid-survey.dataforgood.fb.com/) based on the United States and international aggregate data. - +Our [COVIDcast map]({{< relref "covidcast" >}}) shows basic aggregate survey results, revealing the rates of mask usage and COVID-like symptoms across the United States, and this data is also freely available for download through the [COVIDcast API]({{< apiref "api/covidcast.html">}}). Facebook also publishes [a map](https://covid-survey.dataforgood.fb.com/) based on the United States and international aggregate data. ### Blog posts and presentations +- Alex Reinhart, October 12, 2020. [New and Improved COVID Symptom Survey Tracks Testing and Mask-Wearing]({{< relref "2020-10-06-survey-wave-4" >}}). Delphi blog. - Ryan Tibshirani, September 21, 2020. [Can Symptom Surveys Improve COVID-19 Forecasts?]({{< relref "2020-09-21-forecast-demo" >}}) Delphi blog. - Alex Reinhart and Ryan Tibshirani, August 26, 2020. [COVID-19 Symptom Surveys through Facebook]({{< relref "2020-08-26-fb-survey" >}}). Delphi blog. @@ -50,7 +46,8 @@ Our [COVIDcast map]({{< relref "covidcast" >}}) shows basic aggregate survey res Research results from universities studying the survey data will be listed here as soon as they are available. -- Kreuter, F., Barkay, N., Bilinski, A., Bradford, A., Chiu, S., Eliat, R., Fan, J., Galili, T., Haimovich, D., Kim, B., LaRocca, S., Li, Y., Morris, K., Presser, S., Sarig, T., Salomon, J. A., Stewart, K., Stuart, E. A., & Tibshirani, R. J. (2020). [Partnering with a global platform to inform research and public policy making](https://doi.org/10.18148/srm/2020.v14i2.7761). Survey Research Methods, 14(2), 159-163. +- Flaxman AD, Henning DJ and Duber HC. [The relative incidence of COVID-19 in healthcare workers versus non-healthcare workers: evidence from a web-based survey of Facebook users in the United States](https://doi.org/10.12688/gatesopenres.13202.1). *Gates Open Research* 2020, 4:174. +- Kreuter, F., Barkay, N., Bilinski, A., Bradford, A., Chiu, S., Eliat, R., Fan, J., Galili, T., Haimovich, D., Kim, B., LaRocca, S., Li, Y., Morris, K., Presser, S., Sarig, T., Salomon, J. A., Stewart, K., Stuart, E. A., & Tibshirani, R. J. (2020). [Partnering with a global platform to inform research and public policy making](https://doi.org/10.18148/srm/2020.v14i2.7761). *Survey Research Methods*, 14(2), 159-163. If you have used the survey data, or the aggregate data available in the COVIDcast API, to publish research results, please [contact us](#who-can-i-contact) so we can include your work here. @@ -73,10 +70,6 @@ Director, Media Relations School of Computer Science Carnegie Mellon University -[Jason Maderer](mailto:maderer@cmu.edu) -Senior Director, Media Relations -Carnegie Mellon University - ### All other questions: [Alex Reinhart](mailto:areinhar@stat.cmu.edu) diff --git a/content/flu.md b/content/flu/_index.md similarity index 92% rename from content/flu.md rename to content/flu/_index.md index 247996a16..d6fb87618 100644 --- a/content/flu.md +++ b/content/flu/_index.md @@ -1,8 +1,8 @@ --- title: Flu and Other Diseases +layout: single --- - ## Operational Systems {{}} @@ -16,15 +16,18 @@ We have participated, and [have done very well](http://www.cs.cmu.edu/~roni/CDC% , 2016--2017 (winner) 2017--2018 (winner)--> + ### [Forecasting Seasonal Influenza in the US](https://www.cdc.gov/flu/weekly/flusight/) + by [CDC](https://www.cdc.gov) 2013 -- current -### [Forecasting Dengue in Puerto Rico and Peru](https://predict.cdc.gov/post/5a4fcc3e2c1b1669c22aa261) +### [Forecasting Dengue in Puerto Rico and Peru](https://predict.cdc.gov/post/5a4fcc3e2c1b1669c22aa261) + by the [White House](https://www.whitehouse.gov/) [OSTP](https://www.whitehouse.gov/administration/eop/ostp) -### [Forecasting the Chikungunya invasion of the Americas](https://www.innocentive.com/ar/challenge/9933617") -by [DARPA](http://www.darpa.mil/) +### [Forecasting the Chikungunya invasion of the Americas](https://www.innocentive.com/ar/challenge/9933617") +by [DARPA](http://www.darpa.mil/) ## Publicly Available Tools @@ -36,4 +39,4 @@ All source code is freely available on [GitHub](https://github.com/cmu-delphi/). Delphi’s notable achievements -{{}} \ No newline at end of file +{{}} diff --git a/content/news/2016_12.md b/content/news/2016_12.md index 420a37c10..2626c126d 100644 --- a/content/news/2016_12.md +++ b/content/news/2016_12.md @@ -4,4 +4,4 @@ title: Top category: accomplishment --- -[system took the top stop in the 2015-2016 flu forecasting challenge](https://www.cdc.gov/flu/spotlights/flu-activity-forecasts-2016-2017.htm). ([Results summary](http://www.cs.cmu.edu/~roni/CDC%20Flu%20Challenge%202015-2016%20Results.pdf).) \ No newline at end of file +[system took the top spot in the 2015-2016 flu forecasting challenge](https://www.cdc.gov/flu/spotlights/flu-activity-forecasts-2016-2017.htm). ([Results summary](http://www.cs.cmu.edu/~roni/CDC%20Flu%20Challenge%202015-2016%20Results.pdf).) diff --git a/content/news/2017_10.md b/content/news/2017_10.md index 47498d4b5..3cf0dc063 100644 --- a/content/news/2017_10.md +++ b/content/news/2017_10.md @@ -7,4 +7,4 @@ category: accomplishment We did it again! [Our two systems took the top two spots in the 2016-2017 flu forecasting challenge (out of 28 submissions).](https://www.cmu.edu/news/stories/archives/2017/september/flu-forecasts.html) -([Results summary](http://www.cs.cmu.edu/~roni/CDC%20Flu%20Challenge%202016-2017%20Results.pdf).) \ No newline at end of file +([Results summary](http://www.cs.cmu.edu/~roni/CDC%20Flu%20Challenge%202016-2017%20Results.pdf).) diff --git a/content/news/2018_11.md b/content/news/2018_11.md index 8a651fe2c..45b6b9051 100644 --- a/content/news/2018_11.md +++ b/content/news/2018_11.md @@ -7,4 +7,4 @@ category: accomplishment and yet again! Our forecasting systems took the top spot each of the three separate flu forecasting challenges of 2017-2018 (out of up to 30 submissions). -([Results summary](http://www.cs.cmu.edu/~roni/CDC%20Flu%20Challenge%202017-2018%20Results.pdf).) \ No newline at end of file +([Results summary](http://www.cs.cmu.edu/~roni/CDC%20Flu%20Challenge%202017-2018%20Results.pdf).) diff --git a/content/news/2019_10_CenterOfExcellence.md b/content/news/2019_10_CenterOfExcellence.md index 2460e2af3..906acd0a9 100644 --- a/content/news/2019_10_CenterOfExcellence.md +++ b/content/news/2019_10_CenterOfExcellence.md @@ -4,4 +4,4 @@ title: Center of Excellence category: accomplishment --- -[CDC has just named us "National Center of Excellence for Influenza Forecasting"](https://www.ml.cmu.edu/news/news-archive/2019/october/machine-learning-delphi-research-group-funded-by-centers-for-disease-control-cdc.html) (one of two nationally.) \ No newline at end of file +[CDC has just named us "National Center of Excellence for Influenza Forecasting"](https://www.ml.cmu.edu/news/news-archive/2019/october/machine-learning-delphi-research-group-funded-by-centers-for-disease-control-cdc.html) (one of two nationally.) diff --git a/content/news/2020_03_covid.md b/content/news/2020_03_covid.md index 2c11c18c3..272121389 100644 --- a/content/news/2020_03_covid.md +++ b/content/news/2020_03_covid.md @@ -7,4 +7,4 @@ category: update We are focusing our efforts at this point on COVID-19 nowcasting and forecasting. We are adapting our existing systems, and developing new ones. Some of our regular activities may be halted as a -result. \ No newline at end of file +result. diff --git a/content/news/2020_04_covidcast.md b/content/news/2020_04_covidcast.md index 6e111afed..5a48f4195 100644 --- a/content/news/2020_04_covidcast.md +++ b/content/news/2020_04_covidcast.md @@ -4,9 +4,8 @@ title: COVIDCast category: update --- - We launched our [COVIDcast system]({{< relref "covidcast">}}), which displays -indicators related to COVID-19 activity level across the U.S. These +indicators related to COVID-19 activity level across the U.S. These indicators are derived from a variety of anonymized, aggregated data sources made available by multiple partners, and are publicly available at the [COVIDcast endpoint]({{< apiref "api/covidcast.html">}}) of our [Epidata API]({{< apiref "api/README.html">}}). @@ -16,4 +15,3 @@ Related news articles: - [Carnegie Mellon Unveils Five Interactive COVID-19 Maps](https://www.cmu.edu/news/stories/archives/2020/april/cmu-unveils-covidcast-maps.html) - [Self-reported COVID-19 Symptoms Show Promise for Disease Forecasts](https://www.cmu.edu/news/stories/archives/2020/april/self-reported-covid-19-symptoms-disease-forecasts.html) - [Facebook and Carnegie Mellon Team Up to Gather COVID-19 Symptom Data](https://www.cmu.edu/news/stories/archives/2020/april/facebook-survey-covid.html) - diff --git a/content/news/2020_10_fellows.md b/content/news/2020_10_fellows.md index 6cc7cb485..67b990600 100644 --- a/content/news/2020_10_fellows.md +++ b/content/news/2020_10_fellows.md @@ -4,4 +4,4 @@ title: Welcome Fellows category: update --- -We've welcomed [13 Google Fellows](https://www.cmu.edu/news/stories/archives/2020/september/covidcast-google.html) to Delphi and are excited to have them on board. \ No newline at end of file +We've welcomed [13 Google Fellows](https://www.cmu.edu/news/stories/archives/2020/september/covidcast-google.html) to Delphi and are excited to have them on board. diff --git a/content/news/index.md b/content/news/index.md index 46ca3e791..441ef3a5a 100644 --- a/content/news/index.md +++ b/content/news/index.md @@ -1,4 +1,4 @@ --- # flag to disable rendering individual pages headless: true ---- \ No newline at end of file +--- diff --git a/content/systems/crowdcast.md b/content/systems/crowdcast.md index 43f24cb4c..eac1f1a55 100644 --- a/content/systems/crowdcast.md +++ b/content/systems/crowdcast.md @@ -6,4 +6,4 @@ order: 20 Delphi's “Wisdom of crowds” forecasting system: Used for Chikungunya, flu and most recently Covid. -**Note:** This system is has been repurposed to forecast ILI during the COVID-19 pandemic. \ No newline at end of file +**Note:** This system is has been repurposed to forecast ILI during the COVID-19 pandemic. diff --git a/content/systems/forecast.md b/content/systems/forecast.md index 375b65fbd..09cbad3b8 100644 --- a/content/systems/forecast.md +++ b/content/systems/forecast.md @@ -7,4 +7,4 @@ State-level weekly forecasts of ILI (influenza-like illness) **Note:** This system is designed to forecast ILI driven by seasonal influenza and is NOT designed to forecast ILI during the COVID-19 pandemic. We -have temporarily shut it down to focus on COVID-19. \ No newline at end of file +have temporarily shut it down to focus on COVID-19. diff --git a/content/systems/index.md b/content/systems/index.md index 46ca3e791..441ef3a5a 100644 --- a/content/systems/index.md +++ b/content/systems/index.md @@ -1,4 +1,4 @@ --- # flag to disable rendering individual pages headless: true ---- \ No newline at end of file +--- diff --git a/content/systems/nowcast.md b/content/systems/nowcast.md index 6f226af09..ec5ed6e15 100644 --- a/content/systems/nowcast.md +++ b/content/systems/nowcast.md @@ -7,4 +7,4 @@ order: 1 Flu nowcasting system. **Note:** This system is designed to nowcast ILI driven by seasonal -influenza and is NOT designed to nowcast ILI during the COVID-19 pandemic. \ No newline at end of file +influenza and is NOT designed to nowcast ILI during the COVID-19 pandemic. diff --git a/content/tools/epidata.md b/content/tools/epidata.md index 4e20c6c6e..990016e9a 100644 --- a/content/tools/epidata.md +++ b/content/tools/epidata.md @@ -4,4 +4,4 @@ link: https://github.com/cmu-delphi/delphi-epidata order: 2 --- -API for getting up-to-date epidemiological data (also available via a web interface through [EpiVis](https://delphi.cmu.edu/epivis/epivis.html)) \ No newline at end of file +API for getting up-to-date epidemiological data (also available via a web interface through [EpiVis](https://delphi.cmu.edu/epivis/epivis.html)) diff --git a/content/tools/epiforecast.md b/content/tools/epiforecast.md index 33b9b5fa3..b683ff657 100644 --- a/content/tools/epiforecast.md +++ b/content/tools/epiforecast.md @@ -4,4 +4,4 @@ link: https://github.com/cmu-delphi/epiforecast-R order: 10 --- -Epidemiological forecasting R package \ No newline at end of file +Epidemiological forecasting R package diff --git a/content/tools/epivis.md b/content/tools/epivis.md index 25f4f0204..c62bc3e62 100644 --- a/content/tools/epivis.md +++ b/content/tools/epivis.md @@ -4,4 +4,4 @@ link: https://delphi.cmu.edu/epivis/epivis.html order: 1 --- -Epidemiological time series visualizer \ No newline at end of file +Epidemiological time series visualizer diff --git a/content/tools/fluscores.md b/content/tools/fluscores.md index d06d52195..88cc773fe 100644 --- a/content/tools/fluscores.md +++ b/content/tools/fluscores.md @@ -4,4 +4,4 @@ link: https://delphi.cmu.edu/misc/fluscores/ order: 50 --- -Visual comparison of scored submissions to CDC Flu Forecasting Challenge (provide your own score files) \ No newline at end of file +Visual comparison of scored submissions to CDC Flu Forecasting Challenge (provide your own score files) diff --git a/content/tools/index.md b/content/tools/index.md index 46ca3e791..441ef3a5a 100644 --- a/content/tools/index.md +++ b/content/tools/index.md @@ -1,4 +1,4 @@ --- # flag to disable rendering individual pages headless: true ---- \ No newline at end of file +--- diff --git a/content/tools/utils.md b/content/tools/utils.md index bdf372829..f7942e016 100644 --- a/content/tools/utils.md +++ b/content/tools/utils.md @@ -4,4 +4,4 @@ link: https://github.com/cmu-delphi/utils order: 60 --- -Epidemiological modeling utilities (e.g., date/epi-weeks conversions) \ No newline at end of file +Epidemiological modeling utilities (e.g., date/epi-weeks conversions) diff --git a/data/authors.yaml b/data/authors.yaml index dce0867aa..efbbdac39 100644 --- a/data/authors.yaml +++ b/data/authors.yaml @@ -20,4 +20,4 @@ - key: kathryn name: Kathryn Mazaitis link: https://cs.cmu.edu/~krivard - description: manages Delphi's engineering team, and is a Senior Research Programmer in the Machine Learning Department at CMU. \ No newline at end of file + description: manages Delphi's engineering team, and is a Senior Research Programmer in the Machine Learning Department at CMU. diff --git a/data/bibliography.yaml b/data/bibliography.yaml deleted file mode 100644 index f3f84f7c9..000000000 --- a/data/bibliography.yaml +++ /dev/null @@ -1,355 +0,0 @@ -- key: "2015 [Farrow ]" - link: /~dfarrow/thesis.pdf - title: "Modeling the Past, Present, and Future of Influenza." - authors: David C. Farrow - PhD Thesis - journal: Carnegie Mellon University - year: 2016 - -- key: "2015 [Brooks, ]" - link: http://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1004382 - title: "Flexible Modeling of Epidemics with an Empirical Bayes Framework." - authors: Logan C. Brooks, David C. Farrow, Sangwon Hyun, Ryan J. Tibshirani, and Roni Rosenfeld. - journal: PLoS Computational Biology - issue: "11(8): e1004382" - doi: 10.1371/journal.pcbi.1004382 - year: 2015 - -- key: "2015 [Farrow, ]" - link: http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0125047 - title: "Computational Characterization of Transient Strain-Transcending Immunity against Influenza A." - authors: David C. Farrow, Donald S. Burke, and Roni Rosenfeld. - journal: PLoS ONE - issue: "10(5): e0125047" - doi: 10.1371/journal.pone.0125047 - year: 2015 - -- key: "2014 [Santilla]" - link: http://www.sciencedirect.com/science/article/pii/S0749379714002384 - title: "What Can Digital Disease Detection Learn from (an External Revision to) Google Flu Trends?" - authors: Santillana, Mauricio, D. Wendong Zhang, Benjamin M. Althouse, and John W. Ayers. - journal: American Journal of Preventive Medicine - year: 2014 - -- key: "2014 [Panhuis,]" - link: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC4120682/ - title: "Risk of Dengue for Tourists and Teams during the World Cup 2014 in Brazil." - authors: Willem G. van Panhuis, Sangwon Hyun, Kayleigh Blaney, Ernesto T. A. Marques, Jr, Giovanini E. Coelho, João Bosco Siqueira, Jr, Ryan Tibshirani, Jarbas B. da Silva, Jr, Roni Rosenfeld. - journal: PLoS Neglected Tropical Diseases - issue: "July; 8(7): e3063." - doi: 10.1371/journal.pntd.0003063. - PMCID: PMC4120682 - year: 2014 - -- key: "2014 [Łuksza, ]" - link: http://www.nature.com/nature/journal/v507/n7490/abs/nature13087.html - title: "A predictive fitness model for influenza." - authors: Łuksza, Marta, and Michael Lässig. - journal: Nature - issue: "507, no. 7490 (2014): 57-61." - -- key: "2014 [Lowe, Ra]" - link: http://www.sciencedirect.com/science/article/pii/S1473309914707819 - title: "Dengue outlook for the World Cup in Brazil: an early warning model framework driven by real-time seasonal climate forecasts." - authors: Lowe, Rachel, Christovam Barcellos, Caio AS Coelho, Trevor C. Bailey, Giovanini Evelim Coelho, Richard Graham, Tim Jupp et al. - journal: The Lancet infectious diseases - year: "2014" - -- key: "2014 [Lazer, D]" - link: http://dash.harvard.edu/handle/1/12016836 - title: "The parable of Google Flu: Traps in big data analysis." - authors: Lazer, David M., Ryan Kennedy, Gary King, and Alessandro Vespignani. - year: "2014" - -- key: "2014 [Koelle, ]" - link: http://www.nature.com/nature/journal/vaop/ncurrent/full/nature13054.html - title: "Influenza: Prediction is worth a shot." - authors: Koelle, Katia, and David A. Rasmussen. - journal: Nature - year: "2014" - -- key: "2014 [Nsoesie,]" - link: http://onlinelibrary.wiley.com/doi/10.1111/irv.12226/full - title: "A systematic review of studies on forecasting the dynamics of influenza outbreaks." - authors: Nsoesie, Elaine O., John S. Brownstein, Naren Ramakrishnan, and Madhav V. Marathe. - journal: Influenza and other respiratory viruses - year: "2014" - -- key: "2013 [Sitepu, ]" - link: http://www.tm.mahidol.ac.th/seameo/2013-44-2-full/10-5657-16.pdf - title: "Temporal Patterns and a Disease Forecasting Model of Dengue Hemorrhagic Fever in Jakarta Based on 10 Years of Surveillance Data." - authors: Sitepu, Monika S., Jaranit Kaewkungwal, Nathanej Luplerdlop, Ngamphol Soonthornworasiri, Tassanee Silawan, Supawadee Poungsombat, and Saranath Lawpoolsri. - journal: The Southeast Asian journal of tropical medicine and public health - issue: "44, no. 2 (2013): 206-217." - -- key: "2013 [Nsoesie,]" - link: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3712489/ - title: "Forecasting peaks of seasonal influenza epidemics." - authors: Nsoesie, Elaine, Madhav Mararthe, and John Brownstein. - journal: PLoS currents - issue: "5" - year: 2013 - -- key: "2013 [Levinson]" - link: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3649003/ - title: "Targeting surveillance for zoonotic virus discovery." - authors: Levinson, Jordan, Tiffany L. Bogich, Kevin J. Olival, Jonathan H. Epstein, Christine K. Johnson, William Karesh, and Peter Daszak. - journal: Emerging infectious diseases - issue: "19, no. 5 (2013): 743." - -- key: "2013 [Fuller, ]" - link: http://www.eomf.ou.edu/media/docs/upload/Reassortment__EID_2013.pdf - title: "Predicting hotspots for influenza virus reassortment." - authors: Fuller, Trevon L., Marius Gilbert, Vincent Martin, Julien Cappelle, Parviez Hosseini, Kevin Y. Njabo, Soad Abdel Aziz, Xiangming Xiao, Peter Daszak, and Thomas B. Smith. - journal: On the Cover - issue: "(2013): 581." - -- key: "2013 [Dugas, A]" - link: http://dx.plos.org/10.1371/journal.pone.0056176.g003 - title: "Influenza forecasting with Google flu trends." - authors: Dugas, Andrea Freyer, Mehdi Jalalpour, Yulia Gel, Scott Levin, Fred Torcaso, Takeru Igusa, and Richard E. Rothman. - journal: PloS one - issue: "8, no. 2 (2013): e56176." - -- key: "2013 [Bogich, ]" - link: http://rsif.royalsocietypublishing.org/content/10/81/20120904.short - title: "Using network theory to identify the causes of disease outbreaks of unknown origin." - authors: Bogich, Tiffany L., Sebastian Funk, Trent R. Malcolm, Nok Chhun, Jonathan H. Epstein, Aleksei A. Chmura, A. Marm Kilpatrick et al. - journal: Journal of The Royal Society Interface - issue: "10, no. 81 (2013): 20120904." - -- key: "2012 [Shaman, ]" - link: http://www.pnas.org/content/109/50/20425.short - title: "Forecasting seasonal outbreaks of influenza." - authors: Shaman, Jeffrey, and Alicia Karspeck. - journal: Proceedings of the National Academy of Sciences - issue: "109, no. 50 (2012): 20425-20430." - -- key: "2012 [Morse, S]" - link: http://www.sciencedirect.com/science/article/pii/S0140673612616845 - title: "Prediction and prevention of the next pandemic zoonosis." - authors: Morse, Stephen S., Jonna AK Mazet, Mark Woolhouse, Colin R. Parrish, Dennis Carroll, William B. Karesh, Carlos Zambrana-Torrelio, W. Ian Lipkin, and Peter Daszak. - journal: The Lancet - issue: "380, no. 9857 (2012): 1956-1965." - -- key: "2012 [Hii, Yie]" - link: http://dx.plos.org/10.1371/journal.pntd.0001908 - title: "Forecast of dengue incidence using temperature and rainfall." - authors: Hii, Yien Ling, Huaiping Zhu, Nawi Ng, Lee Ching Ng, and Joacim Rocklöv. - journal: PLoS neglected tropical diseases - issue: "6, no. 11 (2012): e1908." - -- key: "2012 [Descloux]" - link: http://dx.plos.org/10.1371/journal.pntd.0001470.g009 - title: "Climate-based models for understanding and forecasting dengue epidemics." - authors: Descloux, Elodie, Morgan Mangeas, Christophe Eugène Menkes, Matthieu Lengaigne, Anne Leroy, Temaui Tehei, Laurent Guillaumot et al. - journal: PLoS neglected tropical diseases - issue: "6, no. 2 (2012): e1470." - -- key: "2012 [Bhatnaga]" - link: http://ijph.in/article.asp?issn=0019-557X;year=2012;volume=56;issue=4;spage=281;epage=285;aulast=Bhatnagar - title: "Forecasting incidence of dengue in Rajasthan, using time series analyses." - authors: Bhatnagar, Sunil, Vivek Lal, Shiv D. Gupta, and Om P. Gupta. - journal: Indian journal of public health - issue: "56, no. 4 (2012): 281." - -- key: "2011 [Martinez]" - link: http://www.scielo.br/scielo.php?pid=S0037-86822011000400007&script=sci_arttext - title: "A SARIMA forecasting model to predict the number of cases of dengue in Campinas, State of São Paulo, Brazil." - authors: Martinez, Edson Zangiacomi, Elisângela Aparecida Soares da Silva, and Amaury Lelis Dal Fabbro. - journal: Revista da Sociedade Brasileira de Medicina Tropical - issue: "44, no. 4 (2011): 436-440." - -- key: "2011 [Lowe, Ra]" - link: http://www.sciencedirect.com/science/article/pii/S0098300410001445 - title: "Spatio-temporal modelling of climate-sensitive disease risk: Towards an early warning system for dengue in Brazil." - authors: Lowe, Rachel, Trevor C. Bailey, David B. Stephenson, Richard J. Graham, Caio AS Coelho, Marilia Sá Carvalho, and Christovam Barcellos. - journal: Computers & Geosciences - issue: "37, no. 3 (2011): 371-381." - -- key: "2011 [Lipsitch]" - link: http://online.liebertpub.com/doi/abs/10.1089/bsp.2011.0007 - title: "Improving the evidence base for decision making during a pandemic: the example of 2009 influenza A/H1N1." - authors: Lipsitch, Marc, Lyn Finelli, Richard T. Heffernan, Gabriel M. Leung, and Stephen C. Redd; for the 2009 H1N1 Surveillance Group. - journal: "Biosecurity and bioterrorism: biodefense strategy, practice, and science" - issue: "9, no. 2 (2011): 89-115." - -- key: "2011 [Goldstei]" - link: http://dx.plos.org/10.1371/journal.pmed.1001051 - title: "Predicting the epidemic sizes of influenza A/H1N1, A/H3N2, and B: a statistical method." - authors: Goldstein, Edward, Sarah Cobey, Saki Takahashi, Joel C. Miller, and Marc Lipsitch. - journal: PLoS medicine - issue: "8, no. 7 (2011): e1001051." - -- key: "2010 [Shaman, ]" - link: http://dx.plos.org/10.1371/journal.pbio.1000316.g004 - title: "Absolute humidity and the seasonal onset of influenza in the continental United States." - authors: Shaman, Jeffrey, Virginia E. Pitzer, Cécile Viboud, Bryan T. Grenfell, and Marc Lipsitch. - journal: PLoS biology - issue: "8, no. 2 (2010): e1000316." - -- key: "2010 [Ong, Jim]" - link: http://dx.plos.org/10.1371/journal.pone.0010036.g005 - title: "Real-time epidemic monitoring and forecasting of H1N1-2009 using influenza-like illness from general practice and family doctor clinics in Singapore." - authors: Ong, Jimmy Boon Som, I. Mark, Cheng Chen, Alex R. Cook, Huey Chyi Lee, Vernon J. Lee, Raymond Tzer Pin Lin, Paul Ananth Tambyah, and Lee Gan Goh. - journal: PloS one - issue: "5, no. 4 (2010): e10036." - -- key: "2010 [Miller, ]" - link: http://www.sciencedirect.com/science/article/pii/S0140673609621267 - title: "Incidence of 2009 pandemic influenza A H1N1 infection in England: a cross-sectional serological study." - authors: Miller, Elizabeth, Katja Hoschler, Pia Hardelid, Elaine Stanford, Nick Andrews, and Maria Zambon. - journal: The Lancet - issue: "375, no. 9720 (2010): 1100-1108." - -- key: "2010 [Baguelin]" - link: http://www.sciencedirect.com/science/article/pii/S0264410X10000320 - title: "Vaccination against pandemic influenza A/H1N1v in England: a real-time economic evaluation." - authors: Baguelin, Marc, Albert Jan Van Hoek, Mark Jit, Stefan Flasche, Peter J. White, and W. John Edmunds. - journal: Vaccine - issue: "28, no. 12 (2010): 2370-2384." - -- key: "2009 [Shaman, ]" - link: http://www.pnas.org/content/106/9/3243.short - title: "Absolute humidity modulates influenza survival, transmission, and seasonality." - authors: Shaman, Jeffrey, and Melvin Kohn. - journal: Proceedings of the National Academy of Sciences - issue: "106, no. 9 (2009): 3243-3248." - -- key: "2009 [Ginsberg]" - link: http://www.nature.com/nature/journal/v457/n7232/abs/nature07634.html - title: "Detecting influenza epidemics using search engine query data." - authors: Ginsberg, Jeremy, Matthew H. Mohebbi, Rajan S. Patel, Lynnette Brammer, Mark S. Smolinski, and Larry Brilliant. - journal: Nature - issue: "457, no. 7232 (2009): 1012-1014." - -- key: "2009 [Flahault]" - link: http://www.biomedcentral.com/1471-2334/9/129/ - title: "Potential for a global dynamic of Influenza A (H1N1)." - authors: Flahault, Antoine, Elisabeta Vergu, and Pierre-Yves Boëlle. - journal: BMC infectious diseases - issue: "9, no. 1 (2009): 129." - -- key: "2008 [Silawan,]" - link: http://europepmc.org/abstract/MED/18567447 - title: "Temporal patterns and forecast of dengue infection in Northeastern Thailand." - authors: Silawan, Tassanee, Pratap Singhasivanon, Jaranit Kaewkungwal, Suchitra Nimmanitya, and Wanapa Suwonkerd. - year: 2008 - -- key: "2008 [Jones, K]" - link: http://www.nature.com/nature/journal/v451/n7181/abs/nature06536.html - title: "Global trends in emerging infectious diseases." - authors: Jones, Kate E., Nikkita G. Patel, Marc A. Levy, Adam Storeygard, Deborah Balk, John L. Gittleman, and Peter Daszak. - journal: Nature - issue: "451, no. 7181 (2008): 990-993." - -- key: "2008 [Boëlle, ]" - link: http://online.liebertpub.com/doi/abs/10.1089/vbz.2006.0620 - title: "Investigating transmission in a two-wave epidemic of Chikungunya fever, Reunion Island." - authors: Boëlle, P-Y., Guy Thomas, Elisa Vergu, Philippe Renault, A-J. Valleron, and Antoine Flahault. - journal: Vector-Borne and Zoonotic Diseases - issue: "8, no. 2 (2008): 207-218." - -- key: "2007 [Polgreen]" - link: http://cid.oxfordjournals.org/content/44/2/272.short - title: "Use of prediction markets to forecast infectious disease activity." - authors: Polgreen, Philip M., Forrest D. Nelson, George R. Neumann, and Robert A. Weinstein. - journal: Clinical Infectious Diseases - issue: "44, no. 2 (2007): 272-279." - -- key: "2007 [Pelat, C]" - link: http://www.biomedcentral.com/1472-6947/7/29?utm_source=twitterfeed&utm_medium=twitter - title: "Online detection and quantification of epidemics." - authors: Pelat, Camille, Pierre-Yves Boëlle, Benjamin J. Cowling, Fabrice Carrat, Antoine Flahault, Séverine Ansart, and Alain-Jacques Valleron. - journal: BMC medical informatics and decision making - issue: "7, no. 1 (2007): 29." - -- key: "2007 [Hall, I.]" - link: http://journals.cambridge.org/abstract_S0950268806007084 - title: "Real-time epidemic forecasting for pandemic influenza." - authors: Hall, I. M., R. Gani, H. E. Hughes, and S. Leach. - journal: Epidemiology and Infection - issue: "135, no. 03 (2007): 372-385." - -- key: "2006 [Viboud, ]" - link: http://www.sciencemag.org/content/312/5772/447.short - title: "Synchrony, waves, and spatial hierarchies in the spread of influenza." - authors: Viboud, Cécile, Ottar N. Bjørnstad, David L. Smith, Lone Simonsen, Mark A. Miller, and Bryan T. Grenfell. - journal: science - issue: "312, no. 5772 (2006): 447-451." - -- key: "2006 [Vergu, E]" - link: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3291431/ - title: "Medication sales and syndromic surveillance, France." - authors: Vergu, Elisabeta, Rebecca F. Grais, Hélène Sarter, Jean-Paul Fagot, Bruno Lambert, Alain-Jacques Valleron, and Antoine Flahault. - journal: Emerging infectious diseases - issue: "12, no. 3 (2006): 416." - -- key: "2006 [Smith, D]" - link: http://www.sciencemag.org/content/312/5772/392.short - title: "Predictability and preparedness in influenza control." - authors: Smith, Derek J. - journal: science - issue: "312, no. 5772 (2006): 392-394." - -- key: "2006 [Le Menac]" - link: http://rspb.royalsocietypublishing.org/content/273/1600/2467.short - title: "Key strategies for reducing spread of avian influenza among commercial poultry holdings: lessons for transmission to humans." - authors: Le Menach, Arnaud, Elisabeta Vergu, Rebecca F. Grais, David L. Smith, and Antoine Flahault. - journal: "Proceedings of the Royal Society B: Biological Sciences" - issue: "273, no. 1600 (2006): 2467-2475." - -- key: "2006 [Flahault]" - link: http://smm.sagepub.com/content/15/5/413.short - title: "Virtual surveillance of communicable diseases: a 20-year experience in France." - authors: Flahault, A., T. Blanchon, Y. Dorleans, L. Toubiana, J. F. Vibert, and A. J. Valleron. - journal: Statistical methods in medical research - issue: "15, no. 5 (2006): 413-421." - -- key: "2004 [Legrand,]" - link: http://journals.cambridge.org/abstract_S0950268803001390 - title: "Modelling responses to a smallpox epidemic taking into account uncertainty." - authors: Legrand, J., C. Viboud, P. Y. Boelle, A. J. Valleron, and A. Flahault. - journal: Epidemiology and infection - issue: "132, no. 01 (2004): 19-25." - -- key: "2003 [Viboud, ]" - link: http://aje.oxfordjournals.org/content/158/10/996.short - title: "Prediction of the spread of influenza epidemics by the method of analogues." - authors: Viboud, Cécile, Pierre-Yves Boëlle, Fabrice Carrat, Alain-Jacques Valleron, and Antoine Flahault. - journal: American Journal of Epidemiology - issue: "158, no. 10 (2003): 996-1006." - -- key: "2002 [Barbazan]" - link: http://www.sciencedirect.com/science/article/pii/S1286457902015897 - title: "Dengue hemorrhagic fever epidemiology in Thailand: description and forecasting of epidemics." - authors: Barbazan, Philippe, Sutee Yoksan, and Jean-Paul Gonzalez. - journal: Microbes and infection - issue: "4, no. 7 (2002): 699-705." - -- key: "2000 [Wernley,]" - link: http://books.google.com/books?id=HG5NAQAAIAAJ - title: "Storms, Chapter 6: Storms Forecasting for Emergency Response." - authors: Wernley, Donald, and Louis W. Uccellini. - issue: "Chapter 6 in \"Storms\"; 1999, pp. 70-97" - journal: "Publisher: Routledge, 2000, ISBN: 0415212863, 9780415212861." - -- key: "2000 [Myers, M]" - link: http://www.sciencedirect.com/science/article/pii/S0065308X00470132 - title: "Forecasting disease risk for increased epidemic preparedness in public health." - authors: Myers, M. F., D. J. Rogers, J. Cox, A. Flahault, and S. I. Hay. - journal: Advances in Parasitology - issue: "47 (2000): 309-330." - -- key: "1998 [Krzyszto]" - link: http://journals.ametsoc.org/doi/abs/10.1175/1520-0477(1998)079%3C0243:PHFTAN%3E2.0.CO%3B2 - title: "Probabilistic hydrometeorological forecasts: Toward a new era in operational forecasting." - authors: Krzysztofowicz, Roman. - journal: Bulletin of the American Meteorological Society - issue: "79, no. 2 (1998): 243-251." - -- key: "1993 [Krzyszto]" - link: http://journals.ametsoc.org/doi/abs/10.1175/1520-0434(1993)008%3C0424:PQPFFR%3E2.0.CO%3B2 - title: "Probabilistic quantitative precipitation forecasts for river basins." - authors: Krzysztofowicz, Roman, William J. Drzal, Theresa Rossi Drake, James C. Weyman, and Louis A. Giordano. - journal: Weather and forecasting - issue: "8, no. 4 (1993): 424-439." diff --git a/data/landing.yaml b/data/landing.yaml deleted file mode 100644 index 4b7f46286..000000000 --- a/data/landing.yaml +++ /dev/null @@ -1,15 +0,0 @@ -- pre: Our Tools - title: Real-time Indicators of COVID-19 Activity - ref: covidcast - alt: Explore COVIDCast - image: covidcast_withfill.png -- pre: OUR BLOG POST - title: New and improved COVID Symptom Survey Tracks Testing and Mask-Wearing - ref: 2020-10-06-survey-wave-4 - alt: Learn more - image: landing-pg_hero-img-2_New and Improved COVID Symptom Survey Tracks Testing and Mask-Wearing.png -- pre: Our Research and White Papers - title: "Pancasting: forecasting epidemics from provisional data" - link: https://delphi.cmu.edu/~lcbrooks/brooks2020pancasting.pdf - alt: View Paper - image: landing-pg_hero-img-2_Pancasting_ forecasting epidemics from provisional data.png diff --git a/data/supporter.yaml b/data/supporter.yaml index 00d5a57bf..4a57dc485 100644 --- a/data/supporter.yaml +++ b/data/supporter.yaml @@ -14,4 +14,3 @@ group: collaborator - name: Google.org group: sponsor - diff --git a/docker-compose.yml b/docker-compose.yml index ec82db67a..ad2448947 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,17 @@ -version: '3.1' +version: "3.1" # docker services for R environment and Hugo runner services: r: - build: '.' - working_dir: '/app' + build: "." + working_dir: "/app" command: tail -F anything volumes: - - './:/app' + - "./:/app" # run: docker-compose exec r bash # conda activate www-main # Rscript -e 'blogdown::build_site(run_hugo=FALSE, build_rmd=TRUE)' - + # see https://github.com/peaceiris/hugo-extended-docker # hugo: # image: peaceiris/hugo:v0.78.1-full @@ -20,4 +20,4 @@ services: # command: # - server # - --bind=0.0.0.0 - # - --buildDrafts \ No newline at end of file + # - --buildDrafts diff --git a/environment.yml b/environment.yml index b01d064da..1edbddeba 100644 --- a/environment.yml +++ b/environment.yml @@ -4,13 +4,14 @@ channels: - defaults dependencies: - gdal=3.0.2 - - python=3.7.9 + - python=3.7.9 - pip=20.2.4 - r-base=3.6.3 - glib - - fonts-conda-forge + - mscorefonts - r-cairo - r-devtools + - r-directlabels - r-gridextra - r-reticulate - r-blogdown @@ -40,4 +41,4 @@ dependencies: - pyproj - matplotlib - pip: - - covidcast==0.1.0 \ No newline at end of file + - covidcast==0.1.2 diff --git a/no-deploy.json b/no-deploy.json index d79df4c40..1933a58b9 100644 --- a/no-deploy.json +++ b/no-deploy.json @@ -2,7 +2,6 @@ "type": "delphi deploy config", "version": 1, "actions": [ - "// site-wide favicon", { "type": "move", @@ -11,7 +10,7 @@ }, "// web sources", - { + { "type": "move", "src": "site/", "dst": "/var/www/html/", @@ -27,7 +26,6 @@ "match": "^.+\\.(jpg|png)$" }, - "// team images", { "type": "move", @@ -44,6 +42,5 @@ "match": "^.*\\.html$", "add-header-comment": true } - ] } diff --git a/package-lock.json b/package-lock.json index 47f767c1e..6cc9ddb3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,32 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, "@fortawesome/fontawesome-free": { "version": "5.15.1", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.1.tgz", @@ -15,6 +41,51 @@ "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", "dev": true }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -47,6 +118,12 @@ } } }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -163,6 +240,15 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -224,6 +310,12 @@ } } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "caw": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", @@ -247,6 +339,37 @@ "supports-color": "^5.3.0" } }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -276,6 +399,12 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -315,6 +444,33 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "dependencies": { + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + } + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -326,6 +482,15 @@ "which": "^1.2.9" } }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -460,6 +625,12 @@ } } }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, "download": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", @@ -494,6 +665,12 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -503,6 +680,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -610,6 +796,15 @@ "trim-repeated": "^1.0.0" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -650,6 +845,12 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, "get-proxy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", @@ -740,9 +941,9 @@ } }, "highlight.js": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.4.1.tgz", - "integrity": "sha512-yR5lWvNz7c85OhVAEAeFhVCc/GV4C30Fjzc/rCP0aCWzc1UUOPUk55dK/qdwTZHBvMZo+eZ2jpk62ndX/xMFlg==" + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.3.2.tgz", + "integrity": "sha512-3jRT7OUYsVsKvukNKZCtnvRcFyCJqSEIuIMsEybAXRiFSwpt65qjPd/Pr+UOdYt7WJlt+lj3+ypUsHiySBp/Jw==" }, "http-cache-semantics": { "version": "3.8.1", @@ -762,18 +963,109 @@ "signale": "^1.4.0" } }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "husky": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz", + "integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^7.0.0", + "find-versions": "^3.2.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, + "import-fresh": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "import-lazy": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", "dev": true }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -791,9 +1083,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "into-stream": { @@ -812,12 +1104,30 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "is-natural-number": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, "is-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", @@ -830,6 +1140,12 @@ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, "is-retry-allowed": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", @@ -864,6 +1180,12 @@ "is-object": "^1.0.1" } }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", @@ -876,6 +1198,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "katex": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/katex/-/katex-0.12.0.tgz", @@ -893,6 +1221,250 @@ "json-buffer": "3.0.0" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.2.tgz", + "integrity": "sha512-e8AYR1TDlzwB8VVd38Xu2lXDZf6BcshVqKVuBQThDJRaJLobqKnpbm4dkwJ2puypQNbLr9KF/9mfA649mAGvjA==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "commander": "^6.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.2.0", + "dedent": "^0.7.0", + "enquirer": "^2.3.6", + "execa": "^4.1.0", + "listr2": "^3.2.2", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "listr2": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.3.tgz", + "integrity": "sha512-vUb80S2dSUi8YxXahO8/I/s29GqnOL8ozgHVLjfWQXa03BNEeS1TpBLjh2ruaqq5ufx46BRGvfymdBSuoXET5w==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "figures": "^3.2.0", + "indent-string": "^4.0.0", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.3", + "through": "^2.3.8" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", @@ -916,6 +1488,115 @@ "path-exists": "^3.0.0" } }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -949,12 +1630,34 @@ } } }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "mime-db": { "version": "1.45.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", "dev": true }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -970,6 +1673,12 @@ "brace-expansion": "^1.1.7" } }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", @@ -982,6 +1691,12 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "normalize-url": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", @@ -1046,6 +1761,21 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "dev": true + }, "os-filter-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", @@ -1100,6 +1830,15 @@ "p-limit": "^2.0.0" } }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-timeout": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", @@ -1115,6 +1854,15 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -1143,12 +1891,24 @@ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -1180,12 +1940,78 @@ "load-json-file": "^5.2.0" } }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, + "prettier": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.0.tgz", + "integrity": "sha512-yYerpkvseM4iKD/BXLYUkQV5aKt4tQPqaGW6EsZjzyu0r7sVZZNPJW4Y8MyKmicp6t42XUPcBVA+H6sB3gqndw==", + "dev": true + }, + "prettier-plugin-go-template": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/prettier-plugin-go-template/-/prettier-plugin-go-template-0.0.10.tgz", + "integrity": "sha512-TaHPqiMK/zfk+YhvKRf/1WZDgQ6ffnlxJZX5rwphqfxBOVEezZQtYistTB348MKrKnnwKpyXZWpMRo0/KCVB+A==", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -1248,6 +2074,12 @@ } } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", @@ -1257,6 +2089,16 @@ "lowercase-keys": "^1.0.0" } }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -1266,6 +2108,15 @@ "glob": "^7.1.3" } }, + "rxjs": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", + "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1287,6 +2138,12 @@ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, "semver-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", @@ -1407,6 +2264,49 @@ } } }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "sort-keys": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", @@ -1431,6 +2331,23 @@ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", "dev": true }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -1448,6 +2365,26 @@ } } }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -1469,6 +2406,12 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", @@ -1520,6 +2463,15 @@ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", "dev": true }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", @@ -1529,6 +2481,12 @@ "escape-string-regexp": "^1.0.2" } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -1589,6 +2547,49 @@ "isexe": "^2.0.0" } }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -1596,8 +2597,8 @@ "dev": true }, "www-covidcast": { - "version": "https://github.com/cmu-delphi/www-covidcast/releases/download/v1.11.0/www-covidcast-1.11.0.tgz", - "integrity": "sha512-buaSlC+IqFtXpq1FBG55QZb4j6gWWaOwtuPUYJRSb+6TlMlMG65/q0+ibjtdXgwRKG1No4MTJXdUqhHgFnG8lA==", + "version": "https://github.com/cmu-delphi/www-covidcast/releases/download/v1.11.1/www-covidcast-1.11.1.tgz", + "integrity": "sha512-KHtaZtur4r+O371oHk2f1g72PkueB6EIybdS6eRYonX41ryLr1I97MgVTwCU5O3r2srf0PqioNOc64NZN6KH+w==", "requires": { "uikit": "^3.5.9" } @@ -1614,6 +2615,12 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + }, "yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", diff --git a/package.json b/package.json index efff3f14e..63a8a1f38 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,21 @@ { + "name": "www-main", + "version": "0.1.0", + "private": true, "dependencies": { "@fortawesome/fontawesome-free": "^5.15.1", - "highlight.js": "^10.4.1", + "highlight.js": "^10.3.2", "katex": "^0.12.0", "uikit": "^3.5.9", - "www-covidcast": "https://github.com/cmu-delphi/www-covidcast/releases/download/v1.11.0/www-covidcast-1.11.0.tgz" + "www-covidcast": "https://github.com/cmu-delphi/www-covidcast/releases/download/v1.11.1/www-covidcast-1.11.1.tgz" }, "devDependencies": { "hugo-bin": "^0.66.2", - "ncp": "^2.0.0" - }, - "hugo-bin": { - "buildTags": "extended" + "husky": "^4.3.0", + "lint-staged": "^10.5.2", + "ncp": "^2.0.0", + "prettier": "^2.2.0", + "prettier-plugin-go-template": "0.0.10" }, "scripts": { "copy_fonts": "ncp node_modules/katex/dist/fonts themes/delphi/static/css/fonts/", @@ -20,8 +24,19 @@ "build:blog": "Rscript -e \"blogdown::build_site(local=FALSE, run_hugo=FALSE, build_rmd=TRUE)\"", "build": "hugo --gc --minify", "start": "hugo server -D", - "start:blog": "Rscript -e \"blogdown::serve_site()\"" + "start:blog": "Rscript -e \"blogdown::serve_site()\"", + "format": "prettier *.* \"(.vscode|content|data|themes)/**\" --write", + "lint": "prettier *.* \"(.vscode|content|data|themes)/**\" --check" }, - "name": "www-main", - "version": "0.1.0" + "hugo-bin": { + "buildTags": "extended" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{js,scss,css,yaml,md,html,json,yml}": "prettier --write" + } } diff --git a/static/apple-touch-icon.png b/static/apple-touch-icon.png deleted file mode 100644 index b25c047be..000000000 Binary files a/static/apple-touch-icon.png and /dev/null differ diff --git a/static/blog/2015-07-23-template-post_files/figure-html/pie-1.svg b/static/blog/2015-07-23-template-post_files/figure-html/pie-1.svg index 799caa892..8d3933c4b 100644 --- a/static/blog/2015-07-23-template-post_files/figure-html/pie-1.svg +++ b/static/blog/2015-07-23-template-post_files/figure-html/pie-1.svg @@ -24,7 +24,7 @@ -Sky +Sky @@ -37,7 +37,7 @@ -Sunny side of pyramid +Sunny side of pyramid @@ -50,5 +50,5 @@ -Shady side of pyramid +Shady side of pyramid diff --git a/static/blog/2015-07-23-template-post_files/figure-html/wide-pie-1.svg b/static/blog/2015-07-23-template-post_files/figure-html/wide-pie-1.svg new file mode 100644 index 000000000..8d3933c4b --- /dev/null +++ b/static/blog/2015-07-23-template-post_files/figure-html/wide-pie-1.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + +Sky + + + + + + + + + + + + +Sunny side of pyramid + + + + + + + + + + + + +Shady side of pyramid + diff --git a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-2-1.svg b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-2-1.svg index 197d18158..833102353 100644 --- a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-2-1.svg +++ b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-2-1.svg @@ -13,100 +13,100 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -0 -0.14 -0.29 -0.43 -0.57 -0.71 -0.86 -1 +0 +0.14 +0.29 +0.43 +0.57 +0.71 +0.86 +1 @@ -123,103 +123,103 @@ -Averaged over 2020-06-15 to 2020-07-15 -% of people with COVID symptoms, based on Facebook surveys +Averaged over 2020-06-15 to 2020-07-15 +% of people with COVID symptoms, based on Facebook surveys - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -0 -4.29 -8.57 -12.86 -17.14 -21.43 -25.71 -30 +0 +4.29 +8.57 +12.86 +17.14 +21.43 +25.71 +30 @@ -236,6 +236,6 @@ -Averaged over 2020-06-15 to 2020-07-15 -Daily new confirmed COVID-19 cases per 100,000 people +Averaged over 2020-06-15 to 2020-07-15 +Daily new confirmed COVID-19 cases per 100,000 people diff --git a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-3-1.svg b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-3-1.svg index 5076ec6ed..91cf6902c 100644 --- a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-3-1.svg +++ b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-3-1.svg @@ -14,58 +14,58 @@ - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + -1000 -2000 - - - - -20 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Date -Daily new confirmed COVID-19 cases -% of people who know someone with CLI - - - - - -% CLI-in-community -New COVID-19 cases -Miami-Dade County, FL +1000 +2000 + + + + +20 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Date +Daily new confirmed COVID-19 cases +% of people who know someone with CLI + + + + + +% CLI-in-community +New COVID-19 cases +Miami-Dade County, FL diff --git a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-4-1.svg b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-4-1.svg index 55945566c..2a8450a92 100644 --- a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-4-1.svg +++ b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-4-1.svg @@ -24,48 +24,48 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + -1000 -2000 - - - - -20 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Miami-Dade County, FL +1000 +2000 + + + + +20 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Miami-Dade County, FL @@ -78,48 +78,48 @@ - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + -1000 -2000 - - - - -20 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Maricopa County, AZ +1000 +2000 + + + + +20 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Maricopa County, AZ @@ -132,60 +132,60 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + -1500 -2000 -2500 -3000 - - - - - - - - -14 -16 -18 -20 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Los Angeles County, CA +1500 +2000 +2500 +3000 + + + + + + + + +14 +16 +18 +20 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Los Angeles County, CA @@ -198,60 +198,60 @@ - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + -0 -500 -1000 -1500 - - - - - - - - - -10 -15 -20 -25 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Broward County, FL +0 +500 +1000 +1500 + + + + + + + + + +10 +15 +20 +25 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Broward County, FL @@ -264,53 +264,53 @@ - - + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + -500 -1000 -1500 - - - - - - -20 -30 -40 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Harris County, TX +500 +1000 +1500 + + + + + + +20 +30 +40 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Harris County, TX @@ -323,55 +323,55 @@ - - + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + -300 -600 -900 - - - - - - - -15 -20 -25 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Dallas County, TX +300 +600 +900 + + + + + + + +15 +20 +25 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Dallas County, TX @@ -384,56 +384,56 @@ - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + -300 -600 -900 - - - - - - - -10 -15 -20 -25 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Orange County, CA +300 +600 +900 + + + + + + + +10 +15 +20 +25 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Orange County, CA @@ -446,121 +446,121 @@ - - + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + -200 -400 -600 -800 - - - - - - - -15 -20 -25 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Clark County, NV +200 +400 +600 +800 + + + + + + + +15 +20 +25 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Clark County, NV - + - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + -200 -400 -600 - - - - - - - - -10 -15 -20 -25 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Hillsborough County, FL +200 +400 +600 + + + + + + + + +10 +15 +20 +25 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Hillsborough County, FL @@ -573,61 +573,61 @@ - - + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + -0 -200 -400 -600 - - - - - - - - - -10 -15 -20 -25 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Orange County, FL +0 +200 +400 +600 + + + + + + + + + +10 +15 +20 +25 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Orange County, FL @@ -640,56 +640,56 @@ - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + -200 -400 -600 -800 - - - - - - - -15 -20 -25 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Riverside County, CA +200 +400 +600 +800 + + + + + + + +15 +20 +25 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Riverside County, CA @@ -702,119 +702,119 @@ - - + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + -200 -400 -600 -800 - - - - - - - -20 -30 -40 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Bexar County, TX +200 +400 +600 +800 + + + + + + + +20 +30 +40 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Bexar County, TX - + - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + -200 -400 -600 - - - - - - - -12 -16 -20 -24 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -San Bernardino County, CA +200 +400 +600 + + + + + + + +12 +16 +20 +24 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +San Bernardino County, CA @@ -827,69 +827,69 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + -100 -200 -300 -400 -500 -600 - - - - - - - - - - - -12 -16 -20 -24 -28 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Palm Beach County, FL +100 +200 +300 +400 +500 +600 + + + + + + + + + + + +12 +16 +20 +24 +28 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Palm Beach County, FL @@ -902,69 +902,69 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + -0 -100 -200 -300 -400 -500 - - - - - - - - - - - -10 -15 -20 -25 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Duval County, FL +0 +100 +200 +300 +400 +500 + + + + + + + + + + + +10 +15 +20 +25 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Duval County, FL @@ -977,126 +977,126 @@ - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + -0 -200 -400 - - - - - - - -20 -25 -30 -35 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Georgia, GA +0 +200 +400 + + + + + + + +20 +25 +30 +35 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Georgia, GA - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + -100 -200 -300 -400 -500 - - - - - - - - - -15 -20 -25 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Travis County, TX +100 +200 +300 +400 +500 + + + + + + + + + +15 +20 +25 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Travis County, TX @@ -1109,55 +1109,55 @@ - - + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + -200 -400 -600 - - - - - - - -15 -20 -25 -30 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Tarrant County, TX +200 +400 +600 + + + + + + + +15 +20 +25 +30 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Tarrant County, TX @@ -1170,62 +1170,62 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + -100 -200 -300 -400 -500 - - - - - - - - - -10.0 -12.5 -15.0 -17.5 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -San Diego County, CA +100 +200 +300 +400 +500 + + + + + + + + + +10.0 +12.5 +15.0 +17.5 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +San Diego County, CA @@ -1238,63 +1238,63 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + -0 -100 -200 -300 -400 - - - - - - - - - - -20 -30 -40 -50 -60 - - - - -Jun 01 -Jun 15 -Jul 01 -Jul 15 -Hidalgo County, TX +0 +100 +200 +300 +400 + + + + + + + + + + +20 +30 +40 +50 +60 + + + + +Jun 01 +Jun 15 +Jul 01 +Jul 15 +Hidalgo County, TX diff --git a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-5-1.svg b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-5-1.svg index 2c8574892..318097c7b 100644 --- a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-5-1.svg +++ b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-5-1.svg @@ -12,63 +12,63 @@ ]]> - + - - + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + -0.2 -0.4 -0.6 -0.8 - - - - - - - - -May -Jun -Jul -Aug -Date -Correlation - - - - - -% CLI -% CLI-in-community -Over all counties with at least 500 cumulative cases -Correlation between CLI signals and case rates +0.2 +0.4 +0.6 +0.8 + + + + + + + + +May +Jun +Jul +Aug +Date +Correlation + + + + + +% CLI +% CLI-in-community +Over all counties with at least 500 cumulative cases +Correlation between CLI signals and case rates diff --git a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-6-1.svg b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-6-1.svg index 96650ab37..82e218ad2 100644 --- a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-6-1.svg +++ b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-6-1.svg @@ -14,50 +14,50 @@ - - + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + -5 -10 -15 - - - - - - - -May -Jun -Jul -Aug -Date -Median abs deviation -Over all counties with at least 500 cumulative cases -Median absolute deviation in COVID-19 case rates +5 +10 +15 + + + + + + + +May +Jun +Jul +Aug +Date +Median abs deviation +Over all counties with at least 500 cumulative cases +Median absolute deviation in COVID-19 case rates diff --git a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-7-1.svg b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-7-1.svg index a74477ae7..2a35640bf 100644 --- a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-7-1.svg +++ b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-7-1.svg @@ -12,71 +12,71 @@ ]]> - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + -0.0 -0.5 -1.0 -1.5 -2.0 - - - - - - - - - - --1.0 --0.5 -0.0 -0.5 -1.0 -Correlation -Density - - - - - -% CLI -% CLI-in-community -Over all counties with at least 500 cumulative cases -Correlation between CLI signals and case rates +0.0 +0.5 +1.0 +1.5 +2.0 + + + + + + + + + + +-1.0 +-0.5 +0.0 +0.5 +1.0 +Correlation +Density + + + + + +% CLI +% CLI-in-community +Over all counties with at least 500 cumulative cases +Correlation between CLI signals and case rates diff --git a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-8-1.svg b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-8-1.svg index 3e0d937b6..f479c9760 100644 --- a/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-8-1.svg +++ b/static/blog/2020-08-26-fb-survey_files/figure-html/unnamed-chunk-8-1.svg @@ -13,3187 +13,3187 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --1 --0.71 --0.43 --0.14 -0.14 -0.43 -0.71 -1 +-1 +-0.71 +-0.43 +-0.14 +0.14 +0.43 +0.71 +1 @@ -3210,3189 +3210,3189 @@ -Correlation between % CLI and case rates +Correlation between % CLI and case rates - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --1 --0.71 --0.43 --0.14 -0.14 -0.43 -0.71 -1 +-1 +-0.71 +-0.43 +-0.14 +0.14 +0.43 +0.71 +1 @@ -6409,5 +6409,5 @@ -Correlation between % CLI-in-community and case rates +Correlation between % CLI-in-community and case rates diff --git a/static/blog/2020-08-28-api_files/figure-html/dv-graph-1.svg b/static/blog/2020-08-28-api_files/figure-html/dv-graph-1.svg index 3068bfdab..b87b6f555 100644 --- a/static/blog/2020-08-28-api_files/figure-html/dv-graph-1.svg +++ b/static/blog/2020-08-28-api_files/figure-html/dv-graph-1.svg @@ -14,54 +14,54 @@ - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + -0 -10 -20 -30 - - - - - - -Apr -Jul -Date -Value - - - - - - - -ny -pa -tx -% of hospital admissions due to COVID-19 +0 +10 +20 +30 + + + + + + +Apr +Jul +Date +Value + + + + + + + +ny +pa +tx +% of hospital admissions due to COVID-19 diff --git a/static/blog/2020-08-28-api_files/figure-html/dv-maps-1.svg b/static/blog/2020-08-28-api_files/figure-html/dv-maps-1.svg index e8f66a8c7..3fcda7dd8 100644 --- a/static/blog/2020-08-28-api_files/figure-html/dv-maps-1.svg +++ b/static/blog/2020-08-28-api_files/figure-html/dv-maps-1.svg @@ -13,2941 +13,2941 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -0 -1.96 -3.91 -5.87 -7.83 -9.79 -11.74 -13.7 - - - - - - - - - - - - - - - - -Viewing MD, DE, VA, WV, KY, TN, NC, SC, FL, GA, AL, MS, LA, AR, TX, OK -% of doctor's visits due to CLI on July 15 + +0 +2.4 +4.8 +7.2 +9.59 +11.99 +14.39 +16.79 + + + + + + + + + + + + + + + + +Viewing MD, DE, VA, WV, KY, TN, NC, SC, FL, GA, AL, MS, LA, AR, TX, OK +% of doctor's visits due to CLI on July 15 - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -0 -1.96 -3.91 -5.87 -7.83 -9.79 -11.74 -13.7 - - - - - - - - - - - - - - - - -Viewing MD, DE, VA, WV, KY, TN, NC, SC, FL, GA, AL, MS, LA, AR, TX, OK -% of doctor's visits due to CLI on August 24 + +0 +2.4 +4.8 +7.2 +9.59 +11.99 +14.39 +16.79 + + + + + + + + + + + + + + + + +Viewing MD, DE, VA, WV, KY, TN, NC, SC, FL, GA, AL, MS, LA, AR, TX, OK +% of doctor's visits due to CLI on August 24 diff --git a/static/blog/2020-08-28-api_files/figure-html/python-data-1.svg b/static/blog/2020-08-28-api_files/figure-html/python-data-1.svg index 45cb2e5f5..38cd0768b 100644 --- a/static/blog/2020-08-28-api_files/figure-html/python-data-1.svg +++ b/static/blog/2020-08-28-api_files/figure-html/python-data-1.svg @@ -7,7 +7,7 @@ - 2020-11-11T17:09:21.709176 + 2020-12-14T12:40:20.323938 image/svg+xml @@ -31,7 +31,7 @@ z - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" style="fill:#e6e6e6;stroke:#cccccc;stroke-width:0.5;"/> - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" style="fill:#e6e6e6;stroke:#cccccc;stroke-width:0.5;"/> - - + - + - + - + - + - + +" style="fill:#e6e6e6;stroke:#cccccc;stroke-width:0.5;"/> - - + - + - + - + - + - + - + +" style="fill:#e6e6e6;stroke:#cccccc;stroke-width:0.5;"/> - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" style="fill:#fea546;"/> - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + +" style="fill:#fead4a;"/> - - + - + - + - + - + - + - + +" style="fill:#fec561;"/> @@ -173313,7 +173313,7 @@ z - - @@ -173332,10 +173332,10 @@ iVBORw0KGgoAAAANSUhEUgAAApkAAAAhCAYAAACSqbBjAAAByUlEQVR4nO3WS27DMAwFQKX3P1rPJHYR +" id="mc8b7356606" style="stroke:#000000;stroke-width:0.8;"/> - + @@ -173359,13 +173359,35 @@ z - + - + + + - - + - - + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - + - + - - + + - - + + - + - - - - + + + + + + + - - + + - + - + - - + + - - + + @@ -173654,10 +173654,10 @@ z - + - + diff --git a/static/blog/2020-09-18-google-survey_files/figure-html/unnamed-chunk-2-1.svg b/static/blog/2020-09-18-google-survey_files/figure-html/unnamed-chunk-2-1.svg index dbd7b51fa..a5464d6e4 100644 --- a/static/blog/2020-09-18-google-survey_files/figure-html/unnamed-chunk-2-1.svg +++ b/static/blog/2020-09-18-google-survey_files/figure-html/unnamed-chunk-2-1.svg @@ -14,176 +14,176 @@ - + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -AK -AL -AR -AZ -CA -CO -CT -DC -DE -FL -GA -HI -IA -ID -IL -IN -KS -KY -LA -MA -MD -ME -MI -MN -MO -MS -MT -NC -ND -NE -NH -NJ -NM -NV -NY -OH -OK -OR -PA -RI -SC -SD -TN -TX -UT -VA -VT -WA -WI -WV -WY - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +AK +AL +AR +AZ +CA +CO +CT +DC +DE +FL +GA +HI +IA +ID +IL +IN +KS +KY +LA +MA +MD +ME +MI +MN +MO +MS +MT +NC +ND +NE +NH +NJ +NM +NV +NY +OH +OK +OR +PA +RI +SC +SD +TN +TX +UT +VA +VT +WA +WI +WV +WY + -0 -10 -20 -30 - - - - - - - - -5 -7 -9 -11 -% CLI-in-community from Google surveys -Daily new confirmed COVID-19 cases per 100,000 people - -Population - - - - - - -1e+07 -2e+07 -3e+07 -Averaged over 2020-04-11 to 2020-05-14 -COVID-19 case rates vs Google % CLI-in-community +0 +10 +20 +30 + + + + + + + + +5 +7 +9 +11 +% CLI-in-community from Google surveys +Daily new confirmed COVID-19 cases per 100,000 people + +Population + + + + + + +1e+07 +2e+07 +3e+07 +Averaged over 2020-04-11 to 2020-05-14 +COVID-19 case rates vs Google % CLI-in-community @@ -196,161 +196,161 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -AK -AL -AR -AZ -CA -CO -CT -DC -DE -FL -GA -HI -IA -ID -IL -IN -KS -KY -LA -MA -MD -ME -MI -MN -MO -MS -MT -NC -ND -NE -NH -NJ -NM -NV -NY -OH -OK -OR -PA -PR -RI -SC -SD -TN -TX -UT -VA -VT -WA -WI -WV -WY - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +AK +AL +AR +AZ +CA +CO +CT +DC +DE +FL +GA +HI +IA +ID +IL +IN +KS +KY +LA +MA +MD +ME +MI +MN +MO +MS +MT +NC +ND +NE +NH +NJ +NM +NV +NY +OH +OK +OR +PA +PR +RI +SC +SD +TN +TX +UT +VA +VT +WA +WI +WV +WY + -0 -10 -20 -30 - - - - - - - -15 -20 -25 -% CLI-in-community from Facebook surveys - -Population - - - - - - -1e+07 -2e+07 -3e+07 -Averaged over 2020-04-11 to 2020-05-14 -COVID-19 case rates vs Facebook % CLI-in-community +0 +10 +20 +30 + + + + + + + +15 +20 +25 +% CLI-in-community from Facebook surveys + +Population + + + + + + +1e+07 +2e+07 +3e+07 +Averaged over 2020-04-11 to 2020-05-14 +COVID-19 case rates vs Facebook % CLI-in-community diff --git a/static/blog/2020-09-18-google-survey_files/figure-html/unnamed-chunk-3-1.svg b/static/blog/2020-09-18-google-survey_files/figure-html/unnamed-chunk-3-1.svg index 1e3a6cc0d..bf9d7dc71 100644 --- a/static/blog/2020-09-18-google-survey_files/figure-html/unnamed-chunk-3-1.svg +++ b/static/blog/2020-09-18-google-survey_files/figure-html/unnamed-chunk-3-1.svg @@ -12,70 +12,70 @@ ]]> - + - - + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + -0.3 -0.5 -0.7 -0.9 - - - - - - - - - -May -Jun -Jul -Aug -Sep -Date -Correlation - - - - - - - -Facebook and case rates -Google and case rates -Google and Facebook -Over all counties with at least 200 cumulative cases -Correlation between survey signals and case rates +0.3 +0.5 +0.7 +0.9 + + + + + + + + + +May +Jun +Jul +Aug +Sep +Date +Correlation + + + + + + + +Facebook and case rates +Google and case rates +Google and Facebook +Over all counties with at least 200 cumulative cases +Correlation between survey signals and case rates diff --git a/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-4-1.svg b/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-4-1.svg index 372bafc72..86edaa714 100644 --- a/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-4-1.svg +++ b/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-4-1.svg @@ -14,212 +14,212 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - -7 days ahead + +7 days ahead - - + + - - + + - -Cases vs Cases + Facebook + +Cases vs Cases + Facebook - - + + @@ -228,32 +228,32 @@ - - + + - - + + - -7 days ahead + +7 days ahead - - + + - - + + - -Cases vs Cases + Google + +Cases vs Cases + Google - - + + @@ -262,32 +262,32 @@ - - + + - - + + - -7 days ahead + +7 days ahead - - + + - - + + - -Cases vs Cases + Facebook + Google + +Cases vs Cases + Facebook + Google - - + + @@ -295,46 +295,46 @@ - - - - - -0.00 -0.25 -0.50 -0.75 -1.00 - - - - - -0.00 -0.25 -0.50 -0.75 -1.00 - - - - - -0.00 -0.25 -0.50 -0.75 -1.00 -0 -1 -2 -3 -4 - - - - - -P-value -Count + + + + + +0.00 +0.25 +0.50 +0.75 +1.00 + + + + + +0.00 +0.25 +0.50 +0.75 +1.00 + + + + + +0.00 +0.25 +0.50 +0.75 +1.00 +0 +1 +2 +3 +4 + + + + + +P-value +Count diff --git a/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-6-1.svg b/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-6-1.svg index c7d39cec1..9ec44fb43 100644 --- a/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-6-1.svg +++ b/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-6-1.svg @@ -14,122 +14,122 @@ - - + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - + + - -7 days ahead + +7 days ahead - - + + - -14 days ahead + +14 days ahead - - - - -May -Jun -Jul -Aug - - - - -May -Jun -Jul -Aug -0.75 -1.00 -1.25 -1.50 - - - - -Date -Median scaled error - - - - - -Cases -Cases + Facebook + + + + +May +Jun +Jul +Aug + + + + +May +Jun +Jul +Aug +0.75 +1.00 +1.25 +1.50 + + + + +Date +Median scaled error + + + + + +Cases +Cases + Facebook diff --git a/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-8-1.svg b/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-8-1.svg index f58a80f2e..52c4197d5 100644 --- a/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-8-1.svg +++ b/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-8-1.svg @@ -14,154 +14,154 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - -7 days ahead + +7 days ahead - - + + - - + + - -Cases > Cases + Facebook + +Cases > Cases + Facebook - - + + @@ -170,32 +170,32 @@ - - + + - - + + - -14 days ahead + +14 days ahead - - + + - - + + - -Cases > Cases + Facebook + +Cases > Cases + Facebook - - + + @@ -203,36 +203,36 @@ - - - - - -0.00 -0.25 -0.50 -0.75 -1.00 - - - - - -0.00 -0.25 -0.50 -0.75 -1.00 -0 -10 -20 -30 -40 - - - - - -P-value -Count + + + + + +0.00 +0.25 +0.50 +0.75 +1.00 + + + + + +0.00 +0.25 +0.50 +0.75 +1.00 +0 +10 +20 +30 +40 + + + + + +P-value +Count diff --git a/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-9-1.svg b/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-9-1.svg index 96d43af41..e8e13ac24 100644 --- a/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-9-1.svg +++ b/static/blog/2020-09-21-forecast-demo_files/figure-html/unnamed-chunk-9-1.svg @@ -12,96 +12,96 @@ ]]> - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -0.96 -0.99 -1.02 -1.05 - - - - - - - - -5 -10 -15 -20 -Number of days ahead -Median scaled error - - - - - - - -Cases -Cases + Facebook -Over all counties with at least 200 cumulative cases -Forecasting errors by number of days ahead +0.96 +0.99 +1.02 +1.05 + + + + + + + + +5 +10 +15 +20 +Number of days ahead +Median scaled error + + + + + + + +Cases +Cases + Facebook +Over all counties with at least 200 cumulative cases +Forecasting errors by number of days ahead diff --git a/static/blog/2020-10-06-survey-wave-4_files/figure-html/mask-wearing-1.svg b/static/blog/2020-10-06-survey-wave-4_files/figure-html/mask-wearing-1.svg index fdc2cd5b2..3ba2a40aa 100644 --- a/static/blog/2020-10-06-survey-wave-4_files/figure-html/mask-wearing-1.svg +++ b/static/blog/2020-10-06-survey-wave-4_files/figure-html/mask-wearing-1.svg @@ -13,230 +13,230 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -55 -61.43 -67.86 -74.29 -80.71 -87.14 -93.57 -100 - - - - - - - - - - - - - - - - -October 7, 2020 -% wearing masks in public most or all the time + +55 +61.43 +67.86 +74.29 +80.71 +87.14 +93.57 +100 + + + + + + + + + + + + + + + + +October 7, 2020 +% wearing masks in public most or all the time - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -5 -10 -15 -20 -25 -30 -35 -40 - - - - - - - - - - - - - - - - -October 7, 2020 -% who know someone who is sick -Data from Delphi COVIDcast, covidcast.cmu.edu + +5 +10 +15 +20 +25 +30 +35 +40 + + + + + + + + + + + + + + + + +October 7, 2020 +% who know someone who is sick +Data from Delphi COVIDcast, covidcast.cmu.edu diff --git a/static/blog/2020-10-06-survey-wave-4_files/figure-html/pct-tested-1.svg b/static/blog/2020-10-06-survey-wave-4_files/figure-html/pct-tested-1.svg index 7491a64d7..1195f7f5c 100644 --- a/static/blog/2020-10-06-survey-wave-4_files/figure-html/pct-tested-1.svg +++ b/static/blog/2020-10-06-survey-wave-4_files/figure-html/pct-tested-1.svg @@ -13,117 +13,117 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -6 -8 -10 -12 -14 -16 -18 -20 - - - - - - - - - - - - - - - - -October 7, 2020 -% tested in the last 14 days -Data from Delphi COVIDcast, covidcast.cmu.edu + +6 +8 +10 +12 +14 +16 +18 +20 + + + + + + + + + + + + + + + + +October 7, 2020 +% tested in the last 14 days +Data from Delphi COVIDcast, covidcast.cmu.edu diff --git a/static/blog/2020-10-06-survey-wave-4_files/figure-html/test-positivity-1.svg b/static/blog/2020-10-06-survey-wave-4_files/figure-html/test-positivity-1.svg index bc13bea31..55045523f 100644 --- a/static/blog/2020-10-06-survey-wave-4_files/figure-html/test-positivity-1.svg +++ b/static/blog/2020-10-06-survey-wave-4_files/figure-html/test-positivity-1.svg @@ -13,117 +13,117 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -1 -4.57 -8.14 -11.71 -15.29 -18.86 -22.43 -26 - - - - - - - - - - - - - - - - -October 7, 2020 -% of tests that were positive, last 14 days -Data from Delphi COVIDcast, covidcast.cmu.edu + +1 +4.57 +8.14 +11.71 +15.29 +18.86 +22.43 +26 + + + + + + + + + + + + + + + + +October 7, 2020 +% of tests that were positive, last 14 days +Data from Delphi COVIDcast, covidcast.cmu.edu diff --git a/static/blog/2020-10-06-survey-wave-4_files/figure-html/wanted-test-1.svg b/static/blog/2020-10-06-survey-wave-4_files/figure-html/wanted-test-1.svg index 705f4b187..2bd5397f4 100644 --- a/static/blog/2020-10-06-survey-wave-4_files/figure-html/wanted-test-1.svg +++ b/static/blog/2020-10-06-survey-wave-4_files/figure-html/wanted-test-1.svg @@ -13,117 +13,117 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -5 -6 -7 -8 -9 -10 -11 -12 - - - - - - - - - - - - - - - - -October 7, 2020 -% not tested who wanted a test, last 14 days -Data from Delphi COVIDcast, covidcast.cmu.edu + +5 +6 +7 +8 +9 +10 +11 +12 + + + + + + + + + + + + + + + + +October 7, 2020 +% not tested who wanted a test, last 14 days +Data from Delphi COVIDcast, covidcast.cmu.edu diff --git a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-2-1.svg b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-2-1.svg index 28d11cbea..ccb89c7e2 100644 --- a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-2-1.svg +++ b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-2-1.svg @@ -13,100 +13,100 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -0 -2.14 -4.29 -6.43 -8.57 -10.71 -12.86 -15 +0 +2.14 +4.29 +6.43 +8.57 +10.71 +12.86 +15 @@ -123,103 +123,103 @@ -Averaged over 2020-04-15 to 2020-05-15 -% COVID-like illness in outpatient visits +Averaged over 2020-04-15 to 2020-05-15 +% COVID-like illness in outpatient visits - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -0 -4.29 -8.57 -12.86 -17.14 -21.43 -25.71 -30 +0 +3.57 +7.14 +10.71 +14.29 +17.86 +21.43 +25 @@ -236,6 +236,6 @@ -Averaged over 2020-04-15 to 2020-05-15 -Daily new confirmed COVID-19 cases per 100,000 people +Averaged over 2020-04-15 to 2020-05-15 +Daily new confirmed COVID-19 cases per 100,000 people diff --git a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-3-1.svg b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-3-1.svg index 4085a28e3..d90f95d25 100644 --- a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-3-1.svg +++ b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-3-1.svg @@ -14,441 +14,441 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + - -PA + +PA - - + + - -TX + +TX - - + + - -WI + +WI - - + + - -GA + +GA - - + + - -NJ + +NJ - - + + - -NY + +NY - - + + - -AZ + +AZ - - + + - -CA + +CA - - + + - -FL + +FL - - - - -May -Jun -Jul -Aug - - - - -May -Jun -Jul -Aug - - - - -May -Jun -Jul -Aug -5 -10 -15 -20 - - - - -5 -10 -15 -20 - - - - -5 -10 -15 -20 - - - - -Date -% CLI-in-DV - - - - - - - -Adjusted -Original -DV indicator, with and without weekday adjustment + + + + +May +Jun +Jul +Aug + + + + +May +Jun +Jul +Aug + + + + +May +Jun +Jul +Aug +5 +10 +15 +20 + + + + +5 +10 +15 +20 + + + + +5 +10 +15 +20 + + + + +Date +% CLI-in-DV + + + + + + + +Adjusted +Original +DV indicator, with and without weekday adjustment diff --git a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-4-1.svg b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-4-1.svg index 8bdc86437..1136dfee5 100644 --- a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-4-1.svg +++ b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-4-1.svg @@ -12,58 +12,58 @@ ]]> - + - - + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + -0.0 -0.5 -1.0 -1.5 - - - - - - - - - --1.0 --0.5 -0.0 -0.5 -1.0 -Correlation -Density -Over all counties with at least 500 cumulative cases -Correlation-by-space between DV indicator and case rates +0.0 +0.5 +1.0 +1.5 + + + + + + + + + +-1.0 +-0.5 +0.0 +0.5 +1.0 +Correlation +Density +Over all counties with at least 500 cumulative cases +Correlation-by-space between DV indicator and case rates diff --git a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-5-1.svg b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-5-1.svg index 0b1f43a06..27f97b766 100644 --- a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-5-1.svg +++ b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-5-1.svg @@ -12,60 +12,57 @@ ]]> - + - - + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + -0.500 -0.525 -0.550 -0.575 -0.600 - - - - - - - - - - -0 -5000 -10000 -15000 -20000 -Cumulative cases threshold -Correlation -Over all counties with cumulative cases above threshold -Mean correlation-by-space between DV indicator and case rates +0.525 +0.550 +0.575 +0.600 + + + + + + + + + +0 +5000 +10000 +15000 +20000 +Cumulative cases threshold +Correlation +Over all counties with cumulative cases above threshold +Mean correlation-by-space between DV indicator and case rates diff --git a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-6-1.svg b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-6-1.svg index 54d5e1ce0..72b8d5981 100644 --- a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-6-1.svg +++ b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-6-1.svg @@ -12,66 +12,65 @@ ]]> - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + -0.1 -0.2 -0.3 -0.4 -0.5 - - - - - - - - - - - -May -Jun -Jul -Aug -Sep -Oct -Date -Correlation -Over all counties with at least 500 cumulative cases -Correlation-by-time between DV indicator and case rates +0.1 +0.2 +0.3 +0.4 +0.5 + + + + + + + + + + + +May +Jun +Jul +Aug +Sep +Oct +Date +Correlation +Over all counties with at least 500 cumulative cases +Correlation-by-time between DV indicator and case rates diff --git a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-7-1.svg b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-7-1.svg index 2a2eb6977..90d1fce2d 100644 --- a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-7-1.svg +++ b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-7-1.svg @@ -14,116 +14,116 @@ - + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -0 -10 -20 -30 -40 - - - - - - - - - - - -May -Jun -Jul -Aug -Sep -Oct -Date -New cases per 100,000 people - -HHS - - - - - - - - - - - - - - - - - - - - -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -Mean case rate per HHS region +0 +10 +20 +30 +40 + + + + + + + + + + + +May +Jun +Jul +Aug +Sep +Oct +Date +New cases per 100,000 people + +HHS + + + + + + + + + + + + + + + + + + + + +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +Mean case rate per HHS region @@ -136,97 +136,97 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -5 -10 -15 - - - - - - - - - -May -Jun -Jul -Aug -Sep -Oct -Date -% CLI-in-DV - -HHS - - - - - - - - - - - - - - - - - - - - -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -Mean DV indicator per HHS region +5 +10 +15 + + + + + + + + + +May +Jun +Jul +Aug +Sep +Oct +Date +% CLI-in-DV + +HHS + + + + + + + + + + + + + + + + + + + + +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +Mean DV indicator per HHS region diff --git a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-8-1.svg b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-8-1.svg index 1d2f551a5..c838ceea4 100644 --- a/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-8-1.svg +++ b/static/blog/2020-10-14-dv-signal_files/figure-html/unnamed-chunk-8-1.svg @@ -12,72 +12,72 @@ ]]> - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + -0.2 -0.4 -0.6 -0.8 - - - - - - - - - - -May -Jun -Jul -Aug -Sep -Oct -Date -Correlation - - - - - - - -Original -Sensorized -Over all counties with at least 500 cumulative cases -Correlation-by-time of DV indicator and case rates +0.2 +0.4 +0.6 +0.8 + + + + + + + + + + +May +Jun +Jul +Aug +Sep +Oct +Date +Correlation + + + + + + + +Original +Sensorized +Over all counties with at least 500 cumulative cases +Correlation-by-time of DV indicator and case rates diff --git a/static/blog/2020-12-10-masks-public_files/anchor-sections-1.0/anchor-sections.css b/static/blog/2020-12-10-masks-public_files/anchor-sections-1.0/anchor-sections.css new file mode 100644 index 000000000..07aee5fcb --- /dev/null +++ b/static/blog/2020-12-10-masks-public_files/anchor-sections-1.0/anchor-sections.css @@ -0,0 +1,4 @@ +/* Styles for section anchors */ +a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} +a.anchor-section::before {content: '#';} +.hasAnchor:hover a.anchor-section {visibility: visible;} diff --git a/static/blog/2020-12-10-masks-public_files/anchor-sections-1.0/anchor-sections.js b/static/blog/2020-12-10-masks-public_files/anchor-sections-1.0/anchor-sections.js new file mode 100644 index 000000000..570f99a0a --- /dev/null +++ b/static/blog/2020-12-10-masks-public_files/anchor-sections-1.0/anchor-sections.js @@ -0,0 +1,33 @@ +// Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. +document.addEventListener('DOMContentLoaded', function() { + // Do nothing if AnchorJS is used + if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { + return; + } + + const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); + + // Do nothing if sections are already anchored + if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { + return null; + } + + // Use section id when pandoc runs with --section-divs + const section_id = function(x) { + return ((x.classList.contains('section') || (x.tagName === 'SECTION')) + ? x.id : ''); + }; + + // Add anchors + h.forEach(function(x) { + const id = x.id || section_id(x.parentElement); + if (id === '') { + return null; + } + let anchor = document.createElement('a'); + anchor.href = '#' + id; + anchor.classList = ['anchor-section']; + x.classList.add('hasAnchor'); + x.appendChild(anchor); + }); +}); diff --git a/static/blog/2020-12-10-masks-public_files/figure-html/mask_questions_compared-1.png b/static/blog/2020-12-10-masks-public_files/figure-html/mask_questions_compared-1.png new file mode 100644 index 000000000..25475c708 Binary files /dev/null and b/static/blog/2020-12-10-masks-public_files/figure-html/mask_questions_compared-1.png differ diff --git a/static/blog/2020-12-10-masks-public_files/figure-html/mask_questions_compared-1.svg b/static/blog/2020-12-10-masks-public_files/figure-html/mask_questions_compared-1.svg new file mode 100644 index 000000000..bf0c0ddcc --- /dev/null +++ b/static/blog/2020-12-10-masks-public_files/figure-html/mask_questions_compared-1.svg @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +AK +AL +AR +AZ +CA +CO +CT +DC +DE +FL +GA +HI +IA +ID +IL +IN +KS +KY +LA +MA +MD +ME +MI +MN +MO +MS +MT +NC +ND +NE +NH +NJ +NM +NV +NY +OH +OK +OR +PA +RI +SC +SD +TN +TX +UT +VA +VT +WA +WI +WV +WY + +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages +equal percentages + + + + + + +50 +60 +70 +80 +90 + + + + + + + + + +80 +85 +90 +95 +% who report wearing masks most/all the time +% who report most/all others wear masks +December 1st, 2020 +Mask use reported in symptom survey +Data from Delphi COVIDcast, delphi.cmu.edu + diff --git a/static/blog/2020-12-10-masks-public_files/figure-html/national_cases_time-1.png b/static/blog/2020-12-10-masks-public_files/figure-html/national_cases_time-1.png new file mode 100644 index 000000000..7dd2ea92a Binary files /dev/null and b/static/blog/2020-12-10-masks-public_files/figure-html/national_cases_time-1.png differ diff --git a/static/blog/2020-12-10-masks-public_files/figure-html/national_cases_time-1.svg b/static/blog/2020-12-10-masks-public_files/figure-html/national_cases_time-1.svg new file mode 100644 index 000000000..ce9ca0ac7 --- /dev/null +++ b/static/blog/2020-12-10-masks-public_files/figure-html/national_cases_time-1.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +50000 +100000 +150000 + + + + + + +Oct 2020 +Nov 2020 +Dec 2020 +Date +Reported new cases +7-day rolling average +Number of reported new cases per day +Data from Delphi COVIDcast, delphi.cmu.edu + diff --git a/static/blog/2020-12-10-masks-public_files/figure-html/restaurants-1.svg b/static/blog/2020-12-10-masks-public_files/figure-html/restaurants-1.svg new file mode 100644 index 000000000..52d619101 --- /dev/null +++ b/static/blog/2020-12-10-masks-public_files/figure-html/restaurants-1.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +AK +AL +AR +AZ +CA +CO +CT +DC +DE +FL +GA +HI +IA +ID +IL +IN +KS +KY +LA +MA +MD +ME +MI +MN +MO +MS +MT +NC +ND +NE +NH +NJ +NM +NV +NY +OH +OK +OR +PA +RI +SC +SD +TN +TX +UT +VA +VT +WA +WI +WV +WY + + + + + + +0 +200 +400 +600 +800 + + + + + + + + + +80 +85 +90 +95 +% who report wearing masks most/all the time +Visits by SafeGraph panel, per 100,000 population +December 1st, 2020 +Restaurant visits and mask use +Data from Delphi COVIDcast, delphi.cmu.edu + diff --git a/static/blog/2020-12-10-masks-public_files/figure-html/social_distancing-1.png b/static/blog/2020-12-10-masks-public_files/figure-html/social_distancing-1.png new file mode 100644 index 000000000..e802bdb7d Binary files /dev/null and b/static/blog/2020-12-10-masks-public_files/figure-html/social_distancing-1.png differ diff --git a/static/blog/2020-12-10-masks-public_files/figure-html/social_distancing-1.svg b/static/blog/2020-12-10-masks-public_files/figure-html/social_distancing-1.svg new file mode 100644 index 000000000..dc326be3c --- /dev/null +++ b/static/blog/2020-12-10-masks-public_files/figure-html/social_distancing-1.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +AK +AL +AR +AZ +CA +CO +CT +DC +DE +FL +GA +HI +IA +ID +IL +IN +KS +KY +LA +MA +MD +ME +MI +MN +MO +MS +MT +NC +ND +NE +NH +NJ +NM +NV +NY +OH +OK +OR +PA +RI +SC +SD +TN +TX +UT +VA +VT +WA +WI +WV +WY + + + + + + +30 +35 +40 + + + + + + + +80 +85 +90 +95 +% who report wearing masks most/all the time +% who spent time with others in past 24 hours +December 1st, 2020 +Social distancing reported in symptom survey +Data from Delphi COVIDcast, delphi.cmu.edu + diff --git a/static/blog/2020-12-10-masks-public_files/figure-html/state_masks_time-1.png b/static/blog/2020-12-10-masks-public_files/figure-html/state_masks_time-1.png new file mode 100644 index 000000000..9e4db40a8 Binary files /dev/null and b/static/blog/2020-12-10-masks-public_files/figure-html/state_masks_time-1.png differ diff --git a/static/blog/2020-12-10-masks-public_files/figure-html/state_masks_time-1.svg b/static/blog/2020-12-10-masks-public_files/figure-html/state_masks_time-1.svg new file mode 100644 index 000000000..1d3a3d434 --- /dev/null +++ b/static/blog/2020-12-10-masks-public_files/figure-html/state_masks_time-1.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +WY +ID +SD +NY +MA +DC + + + + + + +50 +60 +70 +80 +90 +100 + + + + + + + + + +Oct 2020 +Nov 2020 +Dec 2020 +Date +% wearing masks in public most/all the time +From Delphi's surveys, conducted through Facebook +Self-reported public mask usage +Data from Delphi COVIDcast, delphi.cmu.edu + diff --git a/static/blog/images/masks-public-full-size.jpg b/static/blog/images/masks-public-full-size.jpg new file mode 100644 index 000000000..c6f6670fb Binary files /dev/null and b/static/blog/images/masks-public-full-size.jpg differ diff --git a/static/blog/images/masks-public-thumb.jpg b/static/blog/images/masks-public-thumb.jpg new file mode 100644 index 000000000..fe8bfa092 Binary files /dev/null and b/static/blog/images/masks-public-thumb.jpg differ diff --git a/static/favicon-16x16.png b/static/favicon-16x16.png deleted file mode 100644 index 049def12c..000000000 Binary files a/static/favicon-16x16.png and /dev/null differ diff --git a/static/favicon-32x32.png b/static/favicon-32x32.png deleted file mode 100644 index 9d7e862a6..000000000 Binary files a/static/favicon-32x32.png and /dev/null differ diff --git a/static/images/landing-page/team-image.png b/static/images/landing-page/team-image.png deleted file mode 100644 index 973e3c465..000000000 Binary files a/static/images/landing-page/team-image.png and /dev/null differ diff --git a/static/rmarkdown-libs/htmlwidgets/htmlwidgets.js b/static/rmarkdown-libs/htmlwidgets/htmlwidgets.js index 6f3d672d2..3d2276248 100644 --- a/static/rmarkdown-libs/htmlwidgets/htmlwidgets.js +++ b/static/rmarkdown-libs/htmlwidgets/htmlwidgets.js @@ -249,13 +249,13 @@ function tryEval(code) { var result = null; try { - result = eval(code); + result = eval("(" + code + ")"); } catch(error) { if (!error instanceof SyntaxError) { throw error; } try { - result = eval("(" + code + ")"); + result = eval(code); } catch(e) { if (e instanceof SyntaxError) { throw error; diff --git a/themes/delphi/README.md b/themes/delphi/README.md index 4d2ce1627..9043a8669 100644 --- a/themes/delphi/README.md +++ b/themes/delphi/README.md @@ -2,102 +2,6 @@ Hugo theme based on `Noteworthy` for Delphi -## Features - -* Fully responsive -* Google Analytics and Disqus integration -* Ko-fi donation button -* Syntax highlighting -* Mathematical notations with KaTex -* About, Tags, and Archives pages -* RSS feeds -* Social media links -* SCSS for styling - - -## Installation - -Navigate to the root directory of your Hugo site and clone this repository. - -``` -git clone https://github.com/kimcc/hugo-theme-noteworthy.git themes/noteworthy -``` - -Refer to the [Hugo docs](https://gohugo.io/getting-started/quick-start/) for more information. - -## Image shortcode for large images - -To add images using the resize-image shortcode included with this theme, you will need to create a [Post Bundle](https://gohugo.io/content-management/organization/#page-bundles). Create a folder for your post, put your Markdown file and images inside, and rename your Markdown file `index.md`. For example: - -``` -my-new-post -- index.md -- image1.jpg -- image2.png -``` - -Then, you can add an image within your Markdown file by using the shortcode like this: - -``` -{{}} -``` - -Add captions like this: - -``` -{{}} -``` - -## Read more link for posts - -Set `showReadMore = false` to `true` in the config file to have a "read more" link show up when posts are truncated. - -## Social media accounts - -In the `params` section of the `config.toml` file, you can add links to your social media accounts. Simply remove the ones that you don't want to include, and their icons will disappear from the site. - -``` -# Main -email = "#" -facebook = "#" -twitter = "#" -instagram = "#" -tumblr = "#" -reddit = "#" -pinterest = "#" -youtube = "#" -vimeo = "#" -weibo = "#" -vk = "#" -linkedin = "#" - -# Writing -medium = "#" -blogger = "#" -wordpress = "#" - -# Creative & Visual -dribbble = "#" -behance = "#" -deviantart = "#" -flickr = "#" - -# Audio & Music -soundcloud = "#" - -# Programming -github = "#" -stackoverflow = "#" -gitlab = "#" -codepen = "#" - -# Academic -googlescholar = "#" -impactstory = "#" -orcid = "#" -``` - - ## Disqus and Google Analytics Add your Disqus shortname and Google Analytics identifier in the `config.toml` file. @@ -110,7 +14,6 @@ disqusShortname = "" googleAnalytics = "" ``` - ## License -Released under the [MIT License](https://github.com/kimcc/hugo-theme-noteworthy/blob/master/LICENSE.md). \ No newline at end of file +Released under the [MIT License](https://github.com/kimcc/hugo-theme-noteworthy/blob/master/LICENSE.md). diff --git a/themes/delphi/archetypes/default.md b/themes/delphi/archetypes/default.md index 03855e356..9546e4dda 100644 --- a/themes/delphi/archetypes/default.md +++ b/themes/delphi/archetypes/default.md @@ -1,4 +1,4 @@ +++ title = "" date = "" -+++ \ No newline at end of file ++++ diff --git a/themes/delphi/assets/css/_customize.scss b/themes/delphi/assets/css/_customize.scss index 5295e6bea..20938763c 100644 --- a/themes/delphi/assets/css/_customize.scss +++ b/themes/delphi/assets/css/_customize.scss @@ -2,6 +2,9 @@ $global-font-family: "Open Sans", Roboto, Arial, sans-serif; $global-color: #666; +$menu-active-color: #f03f3f; +$menu-active-border-width: 2px; + $base-em-color: $global-color; // Breakpoints: @@ -17,11 +20,16 @@ $navbar-dropdown-padding: 10px; $navbar-dropdown-nav-item-color: #232735; $nav-default-item-active-color: red; -$button-padding-horizontal: 0px; -$button-line-height: 0px; - +// size when both the burger menu and the navbar should be visible +$menu-mode-hybrid: 1140px; +// size when only the burger menu is visible +$menu-mode-mobile-only: $breakpoint-small; +// Breadcrumb $breadcrumb-divider-margin-horizontal: 3px; +// Tab +$tab-item-active-border: $menu-active-color; +$tab-item-border-width: $menu-active-border-width; -$grid-gap: (32/1440)*100%; \ No newline at end of file +$grid-gap: (32/1440) * 100%; diff --git a/themes/delphi/assets/css/blog_extra.scss b/themes/delphi/assets/css/blog_extra.scss index 5fc49e4cd..f80c4e698 100644 --- a/themes/delphi/assets/css/blog_extra.scss +++ b/themes/delphi/assets/css/blog_extra.scss @@ -1,3 +1,3 @@ // separate file to avoid including big libraries into everything -@import './node_modules/highlight.js/scss/github'; -@import './node_modules/katex/dist/katex.min'; \ No newline at end of file +@import "./node_modules/highlight.js/scss/github"; +@import "./node_modules/katex/dist/katex.min"; diff --git a/themes/delphi/assets/css/components/_arrow_link.scss b/themes/delphi/assets/css/components/_arrow_link.scss index be30475fa..4dcc6e3bf 100644 --- a/themes/delphi/assets/css/components/_arrow_link.scss +++ b/themes/delphi/assets/css/components/_arrow_link.scss @@ -1,21 +1,21 @@ .arrow-link { + display: flex; + align-items: center; + + > .inline-svg-icon { + border-radius: 50%; + padding: 5px; + border: 1px solid currentColor; + width: 40px; + height: 40px; display: flex; + box-sizing: border-box; align-items: center; - - > .inline-svg-icon { - border-radius: 50%; - padding: 5px; - border: 1px solid currentColor; - width: 40px; - height: 40px; - display: flex; - box-sizing: border-box; - align-items: center; - justify-content: center; - margin-right: 1em; - - > svg { - width: 14px; - } + justify-content: center; + margin-right: 1em; + + > svg { + width: 14px; } + } } diff --git a/themes/delphi/assets/css/components/_font_awesome.scss b/themes/delphi/assets/css/components/_font_awesome.scss index 25697a8fa..3266ad039 100644 --- a/themes/delphi/assets/css/components/_font_awesome.scss +++ b/themes/delphi/assets/css/components/_font_awesome.scss @@ -1,10 +1,10 @@ .inline-svg-icon { - display: inline-block; - fill: currentColor; - width: 1.2em; - padding: 0 0.5em 0 0.25em; + display: inline-block; + fill: currentColor; + width: 1.2em; + padding: 0 0.5em 0 0.25em; } .uk-icon-button > .inline-svg-icon { - padding: 0; + padding: 0; } diff --git a/themes/delphi/assets/css/components/_latest_card.scss b/themes/delphi/assets/css/components/_latest_card.scss index d385c833e..d753ac874 100644 --- a/themes/delphi/assets/css/components/_latest_card.scss +++ b/themes/delphi/assets/css/components/_latest_card.scss @@ -1,30 +1,29 @@ - .latest-card { - background: #FAFAFC; - border: 1px solid #D3D4D8; - border-radius: 8px; - - > .uk-card-media-top img { - border-radius: 8px 8px 0 0; - width: 100%; - height: 15em; - object-fit: cover; - } - - > .uk-card-body { - flex-grow: 1; - } - - > .uk-card-footer { - border-top: none; - - a { - color: inherit; - } + background: #fafafc; + border: 1px solid #d3d4d8; + border-radius: 8px; + + > .uk-card-media-top img { + border-radius: 8px 8px 0 0; + width: 100%; + height: 15em; + object-fit: cover; + } + + > .uk-card-body { + flex-grow: 1; + } + + > .uk-card-footer { + border-top: none; + + a { + color: inherit; } + } } .latest-card-category { - font-weight: 600; - text-transform: uppercase; -} \ No newline at end of file + font-weight: 600; + text-transform: uppercase; +} diff --git a/themes/delphi/assets/css/components/_toc.scss b/themes/delphi/assets/css/components/_toc.scss new file mode 100644 index 000000000..cc7da03ea --- /dev/null +++ b/themes/delphi/assets/css/components/_toc.scss @@ -0,0 +1,27 @@ +.toc-container { + margin-top: 2em; + + h5 { + letter-spacing: 3px; + text-transform: uppercase; + } +} + +.toc { + background: #f5f5f5; + border-radius: 5px; + padding: 24px; + + li { + list-style: decimal; + } + + li li { + list-style: lower-latin; + } + + .uk-nav-default > li.uk-active > a { + color: unset; + font-weight: 600; + } +} diff --git a/themes/delphi/assets/css/layout/_content.scss b/themes/delphi/assets/css/layout/_content.scss index 7a8bf0cdd..ab7e34843 100644 --- a/themes/delphi/assets/css/layout/_content.scss +++ b/themes/delphi/assets/css/layout/_content.scss @@ -1,15 +1,9 @@ - // Site-wide .uk-container { - margin-top: 20px; - margin-bottom: 20px; + margin-top: 20px; + margin-bottom: 20px; } - .uk-text-bold-600 { - font-weight: 600; + font-weight: 600; } - -.uk-container [aria-hidden="true"] { - display: none; -} \ No newline at end of file diff --git a/themes/delphi/assets/css/layout/_header_footer.scss b/themes/delphi/assets/css/layout/_header_footer.scss index 2f8edfd1a..3a36f2eb3 100644 --- a/themes/delphi/assets/css/layout/_header_footer.scss +++ b/themes/delphi/assets/css/layout/_header_footer.scss @@ -1,76 +1,183 @@ +$mobile-margin: 15px; -.delphi-text-logo { - background-color: white; - color: #F03F3F !important; - font-size: 16px !important; - font-weight: 700; - line-height: 18px; - padding: 5px 10px; +.nav-cmu-delphi-logo { + background-image: url("./images/cmu_brand.png"); + background-size: contain; + background-repeat: no-repeat; + width: 220px; + height: 50px; + margin-right: 30px; + margin-bottom: 5px; + + > span { + display: none; + } } .uk-breadcrumb svg, .uk-navbar svg { - max-height: 18px; + max-height: 18px; } -// Navbar -.nav-active { - border-bottom: 2px solid #F03F3F !important; +.nav-container { + box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.15); + padding: 20px 0 0 0; + + > .uk-navbar-container { + margin-top: 0; + margin-bottom: 0; + align-items: flex-end; + } } -.uk-navbar-container { - box-shadow: 0 3px 5px -1px rgba(0,0,0,.15); - display: block; + +.nav-entries .uk-active { + border-bottom: $menu-active-border-width solid $menu-active-color !important; } -.uk-navbar-left { - margin-top: 40px; - margin-bottom: 0; +.nav-entries { + flex-shrink: 1; + overflow: hidden; } -.uk-navbar-nav>li { - padding-left: 15px; - padding-right: 15px; - white-space: nowrap; +.nav-spacer { + flex: 1 1 0; } -.uk-navbar-dropdown-bottom-left { - margin-left: -20px; - margin-top: 3px; + +li.nav-entry { + white-space: nowrap; + + > a { + padding: 0 15px; + } } -.mobile-nav { - height: 20px; - padding: 23px; - border-bottom: 1px solid #d2d2d2; +.nav-burger { + margin-left: 1em; } -.uk-navbar-toggle { - float:right; - margin-top: -10px; + +.nav-burger li { + display: flex; + align-items: center; + justify-content: flex-start; } -.dropdown-mobile { - left: 0 !important; - padding: 0; - width: 100%; + +.nav-toggle { + width: 20px; } -.menu-element { - border-top: 1px solid #d2d2d2; - font-weight: 400; - padding: 20px 0 20px 40px; + +.nav-dropdown-child { + padding-left: 2.2em; } -.menu-element.menu-parent { - font-weight: 600; + +.nav-dropdown-parent { + text-transform: none; } -.menu-element.menu-child { - padding-left: 64px; + +.nav-mobile { + left: unset !important; + right: 0; +} + +@media only screen and (min-width: $menu-mode-hybrid) { + .nav-burger { + display: none; + } +} + +@media only screen and (max-width: $menu-mode-mobile-only) { + .nav-container { + padding: 0; + } + .nav-cmu-delphi-logo { + background-image: url("./images/cmu_brand_mobile.png"); + margin: $mobile-margin 0; + height: 33px; + width: 193px; + } + + .nav-entries { + display: none; + } + + .nav-burger { + align-self: stretch; + } + .nav-burger > li { + align-items: stretch; + } + + // wide mobile menu + .nav-mobile { + padding: 0; + width: 100%; + + li { + border-top: 1px solid #d2d2d2; + font-weight: 400; + padding: 20px 0 20px 40px; + } + } + + li.nav-dropdown-parent { + margin-top: 0 !important; + font-weight: 600; + } + + li.nav-dropdown-child { + padding-left: 40px + 30px; + } } // Footer .footer { - background-color: #F2F2F2; - color: #232735; - padding: 50px 20% 20px 20%; + background-color: #f2f2f2; + color: #232735; + padding-top: 50px; + padding-bottom: 20px; + + > .uk-container { + display: flex; + } +} + +@media only screen and (max-width: $menu-mode-mobile-only) { + .footer > .uk-container { + display: block; + } +} + +.footer-logo { + display: flex; + flex-direction: column; + padding-top: 10px; +} + +.footer-footer { + flex: 1 1 0; + display: flex; + margin-top: 22px; +} + +.footer-cmu-delphi-logo { + background-image: url("./images/cmu_brand.png"); + background-size: contain; + background-repeat: no-repeat; + width: 220px; + height: 50px; + display: block; + margin-right: 30px; + margin-bottom: 30px; + + > span { + display: none; + } +} + +.footer h5 { + margin-top: 5px; } -.footer .delphi-text-logo { - border: 1px solid #D3D4D8; - padding: 8px 12px; +.breadcrumb-menu { + margin-top: 3px; + margin-bottom: 5px; } diff --git a/themes/delphi/assets/css/layout/_layouts.scss b/themes/delphi/assets/css/layout/_layouts.scss index 80652d074..049a3e5b4 100644 --- a/themes/delphi/assets/css/layout/_layouts.scss +++ b/themes/delphi/assets/css/layout/_layouts.scss @@ -1,41 +1,53 @@ -$grid-gap: (32/1440)*100%; +$grid-gap: (32/1440) * 100%; .content-grid { - display: grid; - grid-template-columns: repeat(12, 1fr); - grid-gap: $grid-gap; + display: grid; + grid-template-columns: repeat(12, 1fr); + grid-gap: $grid-gap; } .grid-2-8 { - grid-column: 2 / 8; + grid-column: 2 / 8; } .grid-2-10 { - grid-column: 2 / 10; + grid-column: 2 / 10; } .grid-8-12 { - grid-column: 8 / 12; + grid-column: 8 / 12; } .grid-3-11 { - grid-column: 3 / 11; + grid-column: 3 / 11; } .grid-2-12 { - grid-column: 2 / 12; + grid-column: 2 / 12; +} +.grid-3-12 { + grid-column: 3 / 12; +} +.grid-4-12 { + grid-column: 4 / 12; } .grid-1-2 { - grid-column: 1 / 2; + grid-column: 1 / 2; +} +.grid-1-3 { + grid-column: 1 / 3; +} +.grid-1-4 { + grid-column: 1 / 4; } @media only screen and (max-width: $breakpoint-small) { - .content-grid { - display: block; - } + .content-grid { + display: block; + } } .content-row { - display: flex; - flex-direction: row; + display: flex; + flex-direction: row; - .content-cell{ - flex: 1; - } -} \ No newline at end of file + .content-cell { + flex: 1; + } +} diff --git a/themes/delphi/assets/css/main.scss b/themes/delphi/assets/css/main.scss index 93782e8f6..3ff6dfdf5 100644 --- a/themes/delphi/assets/css/main.scss +++ b/themes/delphi/assets/css/main.scss @@ -22,6 +22,7 @@ @import "./components/font_awesome"; @import "./components/card_grid"; @import "./components/latest_card"; +@import "./components/toc"; // Page Designs @import "./pages/about"; diff --git a/themes/delphi/assets/css/pages/_about.scss b/themes/delphi/assets/css/pages/_about.scss index 725feea11..44371bbc6 100644 --- a/themes/delphi/assets/css/pages/_about.scss +++ b/themes/delphi/assets/css/pages/_about.scss @@ -1,49 +1,48 @@ .about-mission { - background-image: url("../images/red-bubble-map_mission-pg-short.jpg"); - background-size: auto; - height: 200px; + background-image: url("../images/red-bubble-map_mission-pg-short.jpg"); + background-size: auto; + height: 200px; } .mission-text { - font-weight: 600; - font-size: 24px; - line-height: 36px; + font-weight: 600; + font-size: 24px; + line-height: 36px; } -@media screen and (max-width: $breakpoint-medium) { - .mission-text { - font-size: 18px; - line-height: 28px; - } - .about-mission { - height: 50px; - } - .about-description { - margin-top: 0px; - } +@media screen and (max-width: $breakpoint-medium) { + .mission-text { + font-size: 18px; + line-height: 28px; + } + .about-mission { + height: 50px; + } + .about-description { + margin-top: 0px; + } } @media screen and (min-width: $breakpoint-medium) { - .about-description { - background: white; - border: 1px solid #D3D4D8; - border-radius: 5px; - margin-top: -6rem; - } + .about-description { + background: white; + border: 1px solid #d3d4d8; + border-radius: 5px; + margin-top: -6rem; + } } .about-description { - padding: 2em; - margin-bottom: 3rem; + padding: 2em; + margin-bottom: 3rem; - h3 { - letter-spacing: 3px; - text-transform: uppercase; - } + h3 { + letter-spacing: 3px; + text-transform: uppercase; + } } - .about-collaborators { - background: #FAFAFC; - padding: 0; - padding: 2em 0; + background: #fafafc; + padding: 0; + padding: 2em 0; } diff --git a/themes/delphi/assets/css/pages/_blog.scss b/themes/delphi/assets/css/pages/_blog.scss index 876db27d1..5e307be7d 100644 --- a/themes/delphi/assets/css/pages/_blog.scss +++ b/themes/delphi/assets/css/pages/_blog.scss @@ -1,131 +1,125 @@ - .code-wrapper > summary { - cursor: pointer; + cursor: pointer; } .blog-tags { - overflow: hidden; - text-overflow: ellipsis; + overflow: hidden; + text-overflow: ellipsis; } .blog-tag { - margin-right: 0.5em; - white-space: nowrap; - font-size: 14px; // TODO + margin-right: 0.5em; + white-space: nowrap; + font-size: 14px; // TODO } .blog-hero-image { - width: 100%; - height: 20em; - object-fit: fill; + width: 100%; + height: 20em; + object-fit: fill; } - $blog-list-date-width: 5em; .blog-list-content time, .blog-card time { - display: inline-block; - min-width: $blog-list-date-width; + display: inline-block; + min-width: $blog-list-date-width; } -@media(min-width: $breakpoint-medium) { - .blog-list-content { - margin-left: $blog-list-date-width; - time { - position: absolute; - left: 0; - } +@media (min-width: $breakpoint-medium) { + .blog-list-content { + margin-left: $blog-list-date-width; + time { + position: absolute; + left: 0; } + } } // sm -@media(max-width: $breakpoint-medium) { - .blog-list-hero-image { - order: -1; - img { - width: 100%; - max-height: 20em; - object-fit: contain; +@media (max-width: $breakpoint-medium) { + .blog-list-hero-image { + order: -1; + img { + width: 100%; + max-height: 20em; + object-fit: contain; } -} + } } .blog-card { - .uk-card-media-top img { - width: 100%; - object-fit: cover; - height: 14em; - } + .uk-card-media-top img { + width: 100%; + object-fit: cover; + height: 14em; + } - > .uk-card-footer { - border-top: none; - display: flex; - } + > .uk-card-footer { + border-top: none; + display: flex; + } } .blog-blog { - // center align auto generated images - p > img:first-of-type { - display: block; - margin: 0 auto; - } + // center align auto generated images + p > img:first-of-type, + .figure > img:first-of-type { + display: block; + margin: 0 auto; + } +} + +@media (min-width: $breakpoint-medium) { + .blog-blog > *, + .blog-blog div.section > * { + margin-right: 25%; + } + .blog-blog div.section, + .blog-blog .blog-image-wrapper.wide-figure { + margin-right: unset !important; + } } .blog-image-wrapper { - position: relative; + position: relative; } .blog-image-button { - position: absolute; - right: 0; - top: -14px; - width: 28px; - height: 28px; - cursor: pointer; + position: absolute; + right: 0; + top: -14px; + width: 28px; + height: 28px; + cursor: pointer; } .blog-image-modal { - height: 100%; - background: rgba(0,0,0,0.75); + height: 100%; + background: rgba(0, 0, 0, 0.75); - > img { - width: 100%; - height: 100%; - } + > img { + width: 100%; + height: 100%; + } } #TOC { - // hide original toc - display: none; + // hide original toc + display: none; } -.blog-toc-container { - margin-top: 2em; +.blog-license { + margin-top: 2em; - h5 { - letter-spacing: 3px; - text-transform: uppercase; - } + .inline-svg-icon { + padding: 0; + } } -.blog-toc { - background: #F5F5F5; - border-radius: 5px; - padding: 24px; - - li { - list-style: decimal; - } +.blog-acknowledgements { + font-style: italic; - .uk-nav-default > li.uk-active > a { - color: unset; - font-weight: 600; - } + > strong:first-of-type { + font-style: normal; + } } - -.blog-license { - margin-top: 2em; - - .inline-svg-icon { - padding: 0; - } -} \ No newline at end of file diff --git a/themes/delphi/assets/css/pages/_covidcast.scss b/themes/delphi/assets/css/pages/_covidcast.scss index 35f1ef923..eb2d85998 100644 --- a/themes/delphi/assets/css/pages/_covidcast.scss +++ b/themes/delphi/assets/css/pages/_covidcast.scss @@ -7,3 +7,7 @@ flex-direction: column; height: 100vh; } + +.covidcast_wrapper > footer { + display: none; +} diff --git a/themes/delphi/assets/css/pages/_landing.scss b/themes/delphi/assets/css/pages/_landing.scss index df9c59da0..a0c060695 100644 --- a/themes/delphi/assets/css/pages/_landing.scss +++ b/themes/delphi/assets/css/pages/_landing.scss @@ -5,99 +5,111 @@ // * Explicitly set heights for these three elements // //If this behavior ever becomes more sane, some of these work-arounds can be removed. -$carousel-height:500px; +$carousel-height: 500px; -#main-carousel{ - max-height: $carousel-height; +.main-carousel { + max-height: $carousel-height; } -#uikit-main-carousel{ - height: $carousel-height; +.uikit-main-carousel { + height: $carousel-height; } -#slideshow-container{ - max-height:$carousel-height; - height:$carousel-height; - img { - z-index: -1; - } +.slideshow-container { + max-height: $carousel-height; + height: $carousel-height; + + img { + z-index: -1; + } } .carousel-entry { - z-index: 10; - margin-top: 6rem; - h2 { - color: white; - font-weight: 400; - font-size: 14px; - text-transform: uppercase; - } - p { - color: white; - font-weight: 600; - font-size: 44px; - } - a { - color: white; - } + z-index: 10; + margin-top: 6rem; + + h2 { + color: white; + font-weight: 400; + font-size: 14px; + text-transform: uppercase; + } + + p { + color: white; + font-weight: 600; + font-size: 44px; + } + + a { + color: white; + } } @media screen and (max-width: $breakpoint-medium) { - .carousel-entry { - p { - font-size: 32px; - } + .carousel-entry { + p { + font-size: 32px; } + } } .white-area { - padding-top:2rem; - padding-bottom:2rem; + padding-top: 2rem; + padding-bottom: 2rem; } .gray-area { - padding-top:3rem; - padding-bottom:3rem; - background-color: #eee; + padding-top: 3rem; + padding-bottom: 3rem; + background-color: #eee; } .landing-entry { + line-height: 48px; + .inline-svg-icon { + font-size: x-large; + } + h2 { + font-weight: 600; + font-size: 14px; + letter-spacing: 3px; + text-transform: uppercase; + } + p { + font-weight: 500; + font-size: 28px; line-height: 48px; - .inline-svg-icon{ - font-size:x-large; - } - h2 { - font-weight: 600; - font-size: 14px; - letter-spacing: 3px; - text-transform: uppercase; - } + color: rgb(35, 39, 53); + } + + @media screen and (max-width: $breakpoint-small) { p { - font-weight: 500; - font-size: 28px; - line-height: 48px; - color: rgb(35, 39, 53); + font-size: 18px; + line-height: 32px; } + } + a { + color: $global-color; + font-weight: bold; + } +} - @media screen and (max-width: $breakpoint-small) { - p { - font-size: 18px; - line-height: 32px; - } - } - a { - color: $global-color; - font-weight: bold; - } +.entry-image { + width: 100%; + img { + max-width: 100%; + max-height: 100%; + } } -.entry-image{ - width: 100%; - img{ - max-width: 100%; - max-height: 100% - } +.latest-news { + padding: 0 50px; } +.landing-team-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); -.latest-news { - padding: 0 50px; -} \ No newline at end of file + > img { + filter: grayscale(100%); + } +} diff --git a/themes/delphi/assets/css/pages/_team.scss b/themes/delphi/assets/css/pages/_team.scss index 8661e1e26..6da2f87ee 100644 --- a/themes/delphi/assets/css/pages/_team.scss +++ b/themes/delphi/assets/css/pages/_team.scss @@ -1,23 +1,21 @@ - - .team-hero-image { - width: 100%; + width: 100%; } .team-member > img { - border-radius: 5px; + border-radius: 5px; } .team-header { - line-height: 64px; - font-size: 40px; - padding-top: .25em; - padding-bottom: 1em; + line-height: 64px; + font-size: 40px; + padding-top: 0.25em; + padding-bottom: 1em; } -@media screen and (max-width: $breakpoint-small) { - .team-header { - font-size: 18px; - line-height: 24px; - } - } \ No newline at end of file +@media screen and (max-width: $breakpoint-small) { + .team-header { + font-size: 18px; + line-height: 24px; + } +} diff --git a/themes/delphi/assets/js/blog/codeFolding.js b/themes/delphi/assets/js/blog/codeFolding.js index 4666f7b38..ccb2f5851 100644 --- a/themes/delphi/assets/js/blog/codeFolding.js +++ b/themes/delphi/assets/js/blog/codeFolding.js @@ -1,12 +1,14 @@ export function initializeCodeFolding(showAll) { - Array.from(document.querySelectorAll('pre.r, pre.python, pre.bash, pre.sql, pre.cpp, pre.stan, pre.julia, pre.foldable')).forEach((elem) => { - const wrapper = document.createElement('details'); - wrapper.classList.add('code-wrapper'); - wrapper.open = showAll || false; - elem.parentElement.replaceChild(wrapper, elem); - const summary = document.createElement('summary'); - summary.innerText = 'Code'; - wrapper.appendChild(summary); - wrapper.appendChild(elem); - }); -} \ No newline at end of file + Array.from( + document.querySelectorAll("pre.r, pre.python, pre.bash, pre.sql, pre.cpp, pre.stan, pre.julia, pre.foldable") + ).forEach((elem) => { + const wrapper = document.createElement("details"); + wrapper.classList.add("code-wrapper"); + wrapper.open = showAll || false; + elem.parentElement.replaceChild(wrapper, elem); + const summary = document.createElement("summary"); + summary.innerText = "Code"; + wrapper.appendChild(summary); + wrapper.appendChild(elem); + }); +} diff --git a/themes/delphi/assets/js/blog/imageModal.js b/themes/delphi/assets/js/blog/imageModal.js index fe6d0a769..b3fcf8907 100644 --- a/themes/delphi/assets/js/blog/imageModal.js +++ b/themes/delphi/assets/js/blog/imageModal.js @@ -1,33 +1,41 @@ function showModal(img) { - // based on UIkit.modal.dialog but with full size + // based on UIkit.modal.dialog but with full size - const dialog = UIkit.modal(`
    + const dialog = UIkit.modal(`
    ${img.outerHTML}
    `); - dialog.show(); - UIkit.util.on(dialog.$el, 'hidden', () => { - return Promise.resolve().then(() => dialog.$destroy(true)); - }, { self: true }); + dialog.show(); + UIkit.util.on( + dialog.$el, + "hidden", + () => { + return Promise.resolve().then(() => dialog.$destroy(true)); + }, + { self: true } + ); } export default function imageModal() { - const refButton = document.createElement('button'); - refButton.classList.add('uk-icon-button', 'uk-button-default', 'blog-image-button'); - refButton.title = 'Show image in fullscreen'; - refButton.innerHTML = `` + const refButton = document.createElement("button"); + refButton.classList.add("uk-icon-button", "uk-button-default", "blog-image-button"); + refButton.title = "Show image in fullscreen"; + refButton.innerHTML = ``; - Array.from(document.querySelectorAll('.blog-blog p > img')).forEach((elem) => { - const button = refButton.cloneNode(true); - elem.insertAdjacentElement('beforebegin', button); - elem.parentElement.classList.add('blog-image-wrapper'); - button.addEventListener('click', (e) => { - e.preventDefault(); - e.target.blur(); - showModal(elem); - }) + Array.from(document.querySelectorAll(".blog-blog p > img, .blog-blog .figure > img")).forEach((elem) => { + const button = refButton.cloneNode(true); + elem.insertAdjacentElement("beforebegin", button); + elem.parentElement.classList.add("blog-image-wrapper"); + elem.className + .split(" ") + .filter(Boolean) + .forEach((clazzName) => elem.parentElement.classList.add(clazzName)); + button.addEventListener("click", (e) => { + e.preventDefault(); + e.target.blur(); + showModal(elem); }); + }); } - diff --git a/themes/delphi/assets/js/blog/index.js b/themes/delphi/assets/js/blog/index.js index db5d1e8ff..bb4c3931c 100644 --- a/themes/delphi/assets/js/blog/index.js +++ b/themes/delphi/assets/js/blog/index.js @@ -1,11 +1,11 @@ -import hljs from 'highlight.js'; -import renderMathInElement from 'katex/dist/contrib/auto-render.mjs'; -import { initializeCodeFolding } from './codeFolding'; -import imageModal from './imageModal'; -import initializeTableOfContent from './toc'; +import hljs from "highlight.js"; +import renderMathInElement from "katex/dist/contrib/auto-render.mjs"; +import { initializeCodeFolding } from "./codeFolding"; +import imageModal from "./imageModal"; +import initializeTableOfContent from "./toc"; hljs.initHighlightingOnLoad(); initializeCodeFolding(); -Array.from(document.querySelectorAll('.math')).forEach((elem) => renderMathInElement(elem)); +Array.from(document.querySelectorAll(".math")).forEach((elem) => renderMathInElement(elem)); imageModal(); -initializeTableOfContent(); \ No newline at end of file +initializeTableOfContent(); diff --git a/themes/delphi/assets/js/blog/toc.js b/themes/delphi/assets/js/blog/toc.js index 5abf879e6..1ab5ac30d 100644 --- a/themes/delphi/assets/js/blog/toc.js +++ b/themes/delphi/assets/js/blog/toc.js @@ -1,37 +1,37 @@ export default function initializeTableOfContent() { - const toc = document.getElementById('TOC'); - if (!toc) { - return; - } - toc.remove(); // remove from old place + const toc = document.getElementById("TOC"); + if (!toc) { + return; + } + toc.remove(); // remove from old place - const container = document.querySelector('.blog-toc-container'); - if (!container) { - return; - } + const container = document.querySelector(".toc-container"); + if (!container) { + return; + } - const source = toc.querySelector('ul'); - const target = container.querySelector('ol'); + const source = toc.querySelector("ul"); + const target = container.querySelector("ol"); - const convert = (target, li) => { - target.appendChild(li); - const sub = li.querySelector('ul'); - if (!sub) { - // done - return; - } - li.classList.add('uk-parent'); - sub.remove(); - const subTarget = document.createElement('ol'); - subTarget.classList.add('uk-nav-sub'); - li.appendChild(subTarget); - Array.from(sub.children).forEach((subLi) => convert(subTarget, subLi)); - }; + const convert = (target, li) => { + target.appendChild(li); + const sub = li.querySelector("ul"); + if (!sub) { + // done + return; + } + li.classList.add("uk-parent"); + sub.remove(); + const subTarget = document.createElement("ol"); + subTarget.classList.add("uk-nav-sub"); + li.appendChild(subTarget); + Array.from(sub.children).forEach((subLi) => convert(subTarget, subLi)); + }; - Array.from(source.children).forEach((li) => { - convert(target, li); - }); + Array.from(source.children).forEach((li) => { + convert(target, li); + }); - // done make visible - container.classList.remove('uk-hidden'); -} \ No newline at end of file + // done make visible + container.classList.remove("uk-hidden"); +} diff --git a/themes/delphi/assets/js/main.js b/themes/delphi/assets/js/main.js index 91d33184c..a1a98c6b0 100644 --- a/themes/delphi/assets/js/main.js +++ b/themes/delphi/assets/js/main.js @@ -1,6 +1,6 @@ -import UIkit from 'uikit/dist/js/uikit.js'; +import UIkit from "uikit/dist/js/uikit.js"; // import plugin from 'uikit/dist/js/uikit-icons.js'; // UIkit.use(plugin); // re export for COVIDCast -window.UIkit = UIkit; \ No newline at end of file +window.UIkit = UIkit; diff --git a/themes/delphi/layouts/404.html b/themes/delphi/layouts/404.html index bb1be451c..40bbd212a 100644 --- a/themes/delphi/layouts/404.html +++ b/themes/delphi/layouts/404.html @@ -1,7 +1,7 @@ {{ define "title" }}404 page not found - {{ .Site.Title }}{{ end }} {{ define "main" }} -

    404: Not found

    -

    Sorry, we couldn't find the page you're looking for.

    - Go back home -{{ end }} \ No newline at end of file +

    404: Not found

    +

    Sorry, we couldn't find the page you're looking for.

    + Go back home +{{ end }} diff --git a/themes/delphi/layouts/_default/about.html b/themes/delphi/layouts/_default/about.html index 56f5eb5a6..a828d9841 100644 --- a/themes/delphi/layouts/_default/about.html +++ b/themes/delphi/layouts/_default/about.html @@ -1,14 +1,11 @@ {{ define "main" }} - -
    -
    -
    +
    +
    -

    Delphi Research Group

    -

    {{.Site.Params.mission}}

    - {{ .Content }} +

    Delphi Research Group

    +

    {{ .Site.Params.mission }}

    + {{ .Content }}
    -
    -{{partial "about/collaborators.html" .}} - -{{ end }} \ No newline at end of file +
    + {{ partial "about/collaborators.html" . }} +{{ end }} diff --git a/themes/delphi/layouts/_default/baseof.html b/themes/delphi/layouts/_default/baseof.html index 7610bdc74..f70a407fa 100644 --- a/themes/delphi/layouts/_default/baseof.html +++ b/themes/delphi/layouts/_default/baseof.html @@ -1,13 +1,17 @@ - {{ partial "head.html" . }} - - {{ partial "nav.html" . }} - {{ partial "menu/breadcrumb.html" . }} - {{ block "main" . }} - {{ end }} - {{ partial "footer.html" . }} - {{ partial "scripts.html" . }} - + + {{ partial "head/meta.html" . }} + {{ partial "head/styles.html" . }} + {{ block "styles" . }} {{ end }} + + + {{ partial "nav.html" . }} + {{ partial "menu/breadcrumb.html" . }} + {{ block "main" . }} {{ end }} + {{ partial "footer.html" . }} + {{ partial "scripts.html" . }} + {{ block "scripts" . }} {{ end }} + diff --git a/themes/delphi/layouts/_default/covidcast_app.html b/themes/delphi/layouts/_default/covidcast_app.html new file mode 100644 index 000000000..7f9876b78 --- /dev/null +++ b/themes/delphi/layouts/_default/covidcast_app.html @@ -0,0 +1,20 @@ +{{ define "styles" }} + + +{{ end }} +{{ define "scripts" }} + + + +{{ end }} +{{ define "body_class" }}covidcast_wrapper{{ end }} +{{ define "main" }} +
    + +
    +{{ end }} diff --git a/themes/delphi/layouts/_default/section.html b/themes/delphi/layouts/_default/section.html index d351fb22b..0da0c102f 100644 --- a/themes/delphi/layouts/_default/section.html +++ b/themes/delphi/layouts/_default/section.html @@ -1,27 +1,24 @@ {{ define "main" }} - -

    - Archives -

    + +

    Archives

    - - {{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }} - {{ range ($pages.GroupByDate "2006") }} -

    {{ .Key }}

    + + {{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }} + {{ range ($pages.GroupByDate "2006") }} +

    {{ .Key }}

    + -
      - - {{ range (.Pages) }} - -
    • - {{ .PublishDate.Format "Jan 2" }} - - {{ .Title }} - -
    • - {{ end }} -
    - {{ end }} +
      + {{ range (.Pages) }} +
    • + {{ .PublishDate.Format "Jan 2" }} + + {{ .Title }} + +
    • + {{ end }} +
    + {{ end }}
    -{{ end }} \ No newline at end of file +{{ end }} diff --git a/themes/delphi/layouts/_default/single.html b/themes/delphi/layouts/_default/single.html index b88d51f49..20605458d 100644 --- a/themes/delphi/layouts/_default/single.html +++ b/themes/delphi/layouts/_default/single.html @@ -1,6 +1,6 @@ {{ define "main" }} -
    +

    {{ .Title }}

    {{ .Content }} -
    -{{ end }} \ No newline at end of file +
    +{{ end }} diff --git a/themes/delphi/layouts/_default/taxonomy.html b/themes/delphi/layouts/_default/taxonomy.html index aed249866..5558a8659 100644 --- a/themes/delphi/layouts/_default/taxonomy.html +++ b/themes/delphi/layouts/_default/taxonomy.html @@ -1,26 +1,25 @@ {{ define "main" }} -
    - -

    Tagged "{{ .Data.Term }}"

    - {{range .Pages}} - - -
    -

    - - {{ .Title }} - -

    -
    - {{ .Summary }} - {{ if (and (.Site.Params.showReadMore) (.Truncated)) }} -

    Read more...

    - {{ end }} -
    -
    - -
    -
    +
    + +

    Tagged "{{ .Data.Term }}"

    + {{ range .Pages }} + + {{ end }} -
    -{{ end }} \ No newline at end of file +
    +{{ end }} diff --git a/themes/delphi/layouts/_default/team.html b/themes/delphi/layouts/_default/team.html index d7b7568c5..589afab80 100644 --- a/themes/delphi/layouts/_default/team.html +++ b/themes/delphi/layouts/_default/team.html @@ -1,27 +1,33 @@ {{ define "main" }} -
    -

    Thank you to our {{ len .Params.team }} members around the world, all the students, faculty, staff, and volunteers who have contributed to the COVIDcast project.

    +
    +

    + Thank you to our {{ len .Params.team }} members around the world, all the students, faculty, staff, and volunteers + who have contributed to the COVIDcast project. +

    -World map of team members + World map of team members {{ .Content }}
    - Abbreviations
      - {{range .Params.abbreviations}} -
    • {{.}}
    • - {{end}} + {{ range .Params.abbreviations }} +
    • {{ . }}
    • + {{ end }}

    -

    Thank you for your contributions

    -

    +

    Thank you for your contributions

    +

    {{ .Params.others }} -

    +

    -
    -{{ end }} \ No newline at end of file +
    +{{ end }} diff --git a/themes/delphi/layouts/_default/terms.html b/themes/delphi/layouts/_default/terms.html index 99afdd685..e65b67bdd 100644 --- a/themes/delphi/layouts/_default/terms.html +++ b/themes/delphi/layouts/_default/terms.html @@ -1,11 +1,11 @@ {{ define "main" }} - -
    + +

    Tags

    -
    -{{end}} \ No newline at end of file +
    +{{ end }} diff --git a/themes/delphi/layouts/_internal/pagination.html b/themes/delphi/layouts/_internal/pagination.html index b4feea6f4..3d5dfb0a3 100644 --- a/themes/delphi/layouts/_internal/pagination.html +++ b/themes/delphi/layouts/_internal/pagination.html @@ -1,35 +1,43 @@ {{ $pag := $.Paginator }} {{ if gt $pag.TotalPages 1 -}} -
      -
    • - -
    • - {{- $ellipsed := false -}} - {{- $shouldEllipse := false -}} - {{- range $pag.Pagers -}} - {{- $right := sub .TotalPages .PageNumber -}} - {{- $showNumber := or (le .PageNumber 3) (eq $right 0) -}} - {{- $showNumber := or $showNumber (le .TotalPages 5) -}}{{/* Issue #7523 */}} - {{- $showNumber := or $showNumber (and (gt .PageNumber (sub $pag.PageNumber 2)) (lt .PageNumber (add $pag.PageNumber 2))) -}} - {{- if $showNumber -}} - {{- $ellipsed = false -}} - {{- $shouldEllipse = false -}} - {{- else -}} - {{- $shouldEllipse = not $ellipsed -}} - {{- $ellipsed = true -}} - {{- end -}} - {{- if $showNumber }} -
    • - {{ .PageNumber }} -
    • - {{- else if $shouldEllipse }} -
    • - -
    • - {{- end -}} - {{- end }} -
    • - -
    • -
    -{{ end }} \ No newline at end of file +
      +
    • + {{ if $pag.HasPrev }} + + {{ else }} + + {{ end }} +
    • + {{- $ellipsed := false -}} + {{- $shouldEllipse := false -}} + {{- range $pag.Pagers -}} + {{- $right := sub .TotalPages .PageNumber -}} + {{- $showNumber := or (le .PageNumber 3) (eq $right 0) -}} + {{- $showNumber := or $showNumber (le .TotalPages 5) -}}{{/* Issue #7523 */}} + {{- $showNumber := or $showNumber (and (gt .PageNumber (sub $pag.PageNumber 2)) (lt .PageNumber (add $pag.PageNumber 2))) -}} + {{- if $showNumber -}} + {{- $ellipsed = false -}} + {{- $shouldEllipse = false -}} + {{- else -}} + {{- $shouldEllipse = not $ellipsed -}} + {{- $ellipsed = true -}} + {{- end -}} + {{- if $showNumber }} +
    • + {{ .PageNumber }} +
    • + {{- else if $shouldEllipse }} +
    • + +
    • + {{- end -}} + {{- end }} +
    • + {{ if $pag.HasNext }} + + {{ else }} + + {{ end }} +
    • +
    +{{ end }} diff --git a/themes/delphi/layouts/blog/list.html b/themes/delphi/layouts/blog/list.html index cbc385012..d76ea371d 100644 --- a/themes/delphi/layouts/blog/list.html +++ b/themes/delphi/layouts/blog/list.html @@ -1,35 +1,39 @@ {{ define "main" }} -
    -

    {{ .Title }}

    -

    {{ .Description }}

    +
    +

    {{ .Title }}

    +

    {{ .Description }}

    -
    - {{ range .Paginator.Pages }} -
    -
    {{ .Date.Format "Jan _2" }}
    - {{ .Title}} - Hero Image -
    -
    -

    {{.Title}}

    +
    + {{ range .Paginator.Pages }} +
    +
    {{ .Date.Format "Jan _2" }}
    + {{ .Title }} - Hero Image +
    +
    +

    {{ .Title }}

    {{ .Summary | safeHTML | truncate 150 }}

    - {{- range .Params.tags -}} - {{ partial "blog/tag.html" . }} - {{- end -}} + {{- range .Params.tags -}} + {{ partial "blog/tag.html" . }} + {{- end -}}

    -

    - By {{ .Params.author }} -

    -
    - +
    -
    +
    + {{ end }}
    - {{end}} + {{ template "_internal/pagination.html" . }}
    - {{ template "_internal/pagination.html" . }} -
    -{{ end }} \ No newline at end of file +{{ end }} diff --git a/themes/delphi/layouts/blog/single.html b/themes/delphi/layouts/blog/single.html index 550c67339..6bb8435d3 100644 --- a/themes/delphi/layouts/blog/single.html +++ b/themes/delphi/layouts/blog/single.html @@ -1,69 +1,82 @@ +{{ define "styles" }} + {{ $blog_style := resources.Get "css/blog_extra.scss" | toCSS | minify | fingerprint }} + +{{ end }} +{{ define "scripts" }} + {{ $script_blog := resources.Get "js/blog/index.js" | js.Build | minify | fingerprint -}} + +{{ end }} {{ define "main" }} -
    -

    {{ .Title }}

    -{{ partial "blog/tags.html" .}} -{{if isset .Params "heroimage"}} -
    - {{ .Title}} - Hero Image -
    -{{end}} -
    -
    -
    -
    - - {{if gt (len .Params.authors) 1}} - {{partial "font-awesome.html" "solid/users"}} - {{ else }} - {{partial "font-awesome.html" "solid/user"}} - {{ end }} - -
    -
    -

    {{ .Params.author }}

    -

    - {{ partial "share.html" . }} -
    + {{ $currentPage := . }} +
    +

    {{ .Title }}

    + {{ partial "blog/tags.html" . }} + {{ if isset .Params "heroimage" }} +
    + {{ .Title }} - Hero Image +
    + {{ end }} +
    +
    +
    +
    + + {{ if gt (len .Params.authors) 1 }} + {{ partial "font-awesome.html" "solid/users" }} + {{ else }} + {{ partial "font-awesome.html" "solid/user" }} + {{ end }} + +
    +
    +

    {{ .Params.author }}

    +

    + {{ partial "share.html" . }} +
    -
    -
    -
    Outline
    -
      -
      +
      +
      +
      Outline
      +
        +
        -
        -
        -
        +
        +
        +
        {{ .Content }} {{ if isset .Params "acknowledgements" }} -

        +

        Acknowledgements: {{ .Params.acknowledgements | markdownify }} -

        +

        {{ end }} {{ if isset .Params "related" }} - Related Posts: -
          - {{ $currentPage := . }} + Related Posts: + +
        {{ end }} {{ template "_internal/disqus.html" . }} +
        -
        -
        -{{ range .Params.authors}} -
        - {{ range first 1 (where $.Site.Data.authors "key" "eq" .)}} - {{ if isset . "link"}}{{.name}}{{ else }}{{.name}}{{ end}} {{.description}} +
        + {{ range .Params.authors }} +
        + {{ range first 1 (where $.Site.Data.authors "key" "eq" .) }} + {{ if isset . "link" }} + {{ .name }} + {{ else }} + {{ .name }} + {{ end }} + {{ .description }} + {{ end }} +
        {{ end }} -
        + {{ partial "blog/license.html" $currentPage }} +
        + {{ partial "blog/latestblogs.html" $currentPage }} +
        {{ end }} -{{ partial "blog/license.html" . }} -
        -{{ partial "blog/latestblogs.html" . }} -
        -{{end}} diff --git a/themes/delphi/layouts/covidcast_app/baseof.html b/themes/delphi/layouts/covidcast_app/baseof.html deleted file mode 100644 index 885e48aad..000000000 --- a/themes/delphi/layouts/covidcast_app/baseof.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - {{ partial "head.html" . }} - - {{ partial "nav.html" . }} - {{ partial "menu/breadcrumb.html" . }} - {{ block "main" . }} - {{ end }} - {{ partial "scripts.html" . }} - - diff --git a/themes/delphi/layouts/covidcast_app/list.html b/themes/delphi/layouts/covidcast_app/list.html deleted file mode 100644 index d975ecbd1..000000000 --- a/themes/delphi/layouts/covidcast_app/list.html +++ /dev/null @@ -1 +0,0 @@ -{{ define "main" }} {{ .Content }} {{ end }} diff --git a/themes/delphi/layouts/index.html b/themes/delphi/layouts/index.html index ed057a4de..4cfd224d4 100644 --- a/themes/delphi/layouts/index.html +++ b/themes/delphi/layouts/index.html @@ -1,4 +1,4 @@ {{ define "main" }} -

        {{ .Title }}

        -{{ .Content }} -{{ end }} \ No newline at end of file +

        {{ .Title }}

        + {{ .Content }} +{{ end }} diff --git a/themes/delphi/layouts/landing.html b/themes/delphi/layouts/landing.html index 9cc1e3a20..25f8de2d4 100644 --- a/themes/delphi/layouts/landing.html +++ b/themes/delphi/layouts/landing.html @@ -1,65 +1,38 @@ -{{ define "main" }} -
        - -
        -
        -
        -

        - Our Mission -

        -

        - {{.Site.Params.mission}} -

        -
        -
        -
        - -
        -
        -
        -
        - -
        -

        Our Team

        -

        Meet the Delphi team

        - {{partial "arrow-link.html" (dict "link" (relref . "team") "alt" "View all")}} -
        -
        -
        - -
        -

        Our API

        -

        Access our data and tools

        - {{partial "arrow-link.html" (dict "link" .Site.Params.apiUrl "alt" "Learn more")}} -
        -
        -
        - - {{partial "landing/latest-news.html" .}} -
        -{{ end }} \ No newline at end of file +{{ define "main" }} +
        + {{ partial "landing/carousel.html" . }} +
        +
        +
        +

        Our Mission

        +

        + {{ .Site.Params.mission }} +

        +
        +
        +
        + +
        +
        +
        +
        + {{ partial "landing/teampic.html" (dict "Site" .Site "team" "highlight") }} +
        +

        Our Team

        +

        Meet the Delphi team

        + {{ partial "arrow-link.html" (dict "link" (relref . "team") "alt" "View all") }} +
        +
        +
        + +
        +

        Our API

        +

        Access our data and tools

        + {{ partial "arrow-link.html" (dict "link" .Site.Params.apiUrl "alt" "Learn more") }} +
        +
        +
        + + {{ partial "landing/latest-news.html" . }} +
        +{{ end }} diff --git a/themes/delphi/layouts/partials/about/collaborators.html b/themes/delphi/layouts/partials/about/collaborators.html index 997e286ba..dd36c0e9c 100644 --- a/themes/delphi/layouts/partials/about/collaborators.html +++ b/themes/delphi/layouts/partials/about/collaborators.html @@ -1,18 +1,17 @@ -
        -
        -

        Collaborators

        -

        We're grateful for financial and other support from our collaborators and supporters:

        -
        -
          - {{range .Site.Data.supporter}} -
        • - {{if eq .group "sponsor"}}With support from {{end}} +
          +

          Collaborators

          +

          We're grateful for financial and other support from our collaborators and supporters:

          +
          +
            + {{ range .Site.Data.supporter }} +
          • + {{ if eq .group "sponsor" }}With support from {{ end }} - {{.name}} -
          • - {{end}} -
          -
          + {{ .name }} +
        • + {{ end }} +
        -
        \ No newline at end of file +
        +
        diff --git a/themes/delphi/layouts/partials/arrow-link.html b/themes/delphi/layouts/partials/arrow-link.html index f6315afd9..774d0cee8 100644 --- a/themes/delphi/layouts/partials/arrow-link.html +++ b/themes/delphi/layouts/partials/arrow-link.html @@ -1,4 +1,4 @@ - - {{partial "font-awesome.html" "solid/arrow-right"}} - {{.alt}} - \ No newline at end of file + + {{ partial "font-awesome.html" "solid/arrow-right" }} + {{ .alt }} + diff --git a/themes/delphi/layouts/partials/blog/card.html b/themes/delphi/layouts/partials/blog/card.html index e5fcf09a7..9e650dceb 100644 --- a/themes/delphi/layouts/partials/blog/card.html +++ b/themes/delphi/layouts/partials/blog/card.html @@ -1,15 +1,20 @@
        -
        - {{ .Title}} - Hero Image -
        -
        - {{ partial "blog/tags.html" . }} -

        {{ .Title}}

        -
        - -
        \ No newline at end of file +
        + {{ .Title }} - Hero Image +
        +
        + {{ partial "blog/tags.html" . }} +

        {{ .Title }}

        +
        + +
        diff --git a/themes/delphi/layouts/partials/blog/latestblogs.html b/themes/delphi/layouts/partials/blog/latestblogs.html index 28be7c651..2c989f99c 100644 --- a/themes/delphi/layouts/partials/blog/latestblogs.html +++ b/themes/delphi/layouts/partials/blog/latestblogs.html @@ -1,11 +1,11 @@
        -

        Latest Stories

        - {{- $currentPage := . -}} -
        - {{ range first 3 (where .Parent.Pages ".Title" "!=" $currentPage.Title )}} -
        - {{ partial "blog/card.html" . }} -
        - {{end}} -
        -
        \ No newline at end of file +

        Latest Stories

        + {{- $currentPage := . -}} +
        + {{ range first 3 (where .Parent.Pages ".Title" "!=" $currentPage.Title ) }} +
        + {{ partial "blog/card.html" . }} +
        + {{ end }} +
        +
        diff --git a/themes/delphi/layouts/partials/blog/license.html b/themes/delphi/layouts/partials/blog/license.html index f22a2bea3..c94c31847 100644 --- a/themes/delphi/layouts/partials/blog/license.html +++ b/themes/delphi/layouts/partials/blog/license.html @@ -1,7 +1,7 @@
        - © {{ now.Format "2006" }} Delphi group authors. - Text and figures released under - CC BY 4.0 {{ partial "font-awesome.html" "brands/creative-commons"}} {{ partial "font-awesome.html" "brands/creative-commons-by"}} - ; - code under the MIT license. + © {{ now.Format "2006" }} Delphi group authors. Text and figures released under + + CC BY 4.0 {{ partial "font-awesome.html" "brands/creative-commons" }} + {{ partial "font-awesome.html" "brands/creative-commons-by" }} ; code under the MIT license.
        diff --git a/themes/delphi/layouts/partials/blog/tag.html b/themes/delphi/layouts/partials/blog/tag.html index cb811cd1b..98c7b3ac4 100644 --- a/themes/delphi/layouts/partials/blog/tag.html +++ b/themes/delphi/layouts/partials/blog/tag.html @@ -1 +1,3 @@ -#{{.}} \ No newline at end of file +#{{ . }} diff --git a/themes/delphi/layouts/partials/blog/tags.html b/themes/delphi/layouts/partials/blog/tags.html index a18917c2e..3ee374247 100644 --- a/themes/delphi/layouts/partials/blog/tags.html +++ b/themes/delphi/layouts/partials/blog/tags.html @@ -1,5 +1,5 @@
        - {{- range .Params.tags -}} + {{- range .Params.tags -}} {{ partial "blog/tag.html" . }} - {{- end -}} -
        \ No newline at end of file + {{- end -}} +
        diff --git a/themes/delphi/layouts/partials/delphi-text-logo.html b/themes/delphi/layouts/partials/delphi-text-logo.html deleted file mode 100644 index e93dfd158..000000000 --- a/themes/delphi/layouts/partials/delphi-text-logo.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/themes/delphi/layouts/partials/font-awesome.html b/themes/delphi/layouts/partials/font-awesome.html index 7faf0d3a2..ca31eb1fa 100644 --- a/themes/delphi/layouts/partials/font-awesome.html +++ b/themes/delphi/layouts/partials/font-awesome.html @@ -1,3 +1,3 @@ - {{ readFile (print "./node_modules/@fortawesome/fontawesome-free/svgs/" . ".svg" ) | safeHTML }} - \ No newline at end of file + {{ readFile (print "./node_modules/@fortawesome/fontawesome-free/svgs/" . ".svg" ) | safeHTML }} + diff --git a/themes/delphi/layouts/partials/footer.html b/themes/delphi/layouts/partials/footer.html index a597f4202..c448317e7 100644 --- a/themes/delphi/layouts/partials/footer.html +++ b/themes/delphi/layouts/partials/footer.html @@ -1,3 +1,42 @@ -
        - {{ partial "footer/desktop.html" . }} -
        \ No newline at end of file + diff --git a/themes/delphi/layouts/partials/footer/desktop.html b/themes/delphi/layouts/partials/footer/desktop.html deleted file mode 100644 index 11bd0f401..000000000 --- a/themes/delphi/layouts/partials/footer/desktop.html +++ /dev/null @@ -1,34 +0,0 @@ - \ No newline at end of file diff --git a/themes/delphi/layouts/partials/footer/legal.html b/themes/delphi/layouts/partials/footer/legal.html deleted file mode 100644 index b42a73303..000000000 --- a/themes/delphi/layouts/partials/footer/legal.html +++ /dev/null @@ -1,7 +0,0 @@ -
        -
          -
        • © 2020 Delphi group authors.
        • -
        - Text and figures released under CC BY 4.0; - code under the MIT license. -
        diff --git a/themes/delphi/layouts/partials/head.html b/themes/delphi/layouts/partials/head.html deleted file mode 100644 index 1395473a9..000000000 --- a/themes/delphi/layouts/partials/head.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - {{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} | {{ .Site.Title }}{{ end }} - - - - - - - - - - - - - - {{ $main_style := resources.Get "css/main.scss" | toCSS | minify | fingerprint }} - - - {{ with .OutputFormats.Get "RSS" }} - {{ printf `` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }} - {{ end }} - {{- if not .Site.IsServer -}} - {{ template "_internal/google_analytics.html" . }} - {{- end -}} - - {{ if eq .Page.Type "blog" }} - {{ $blog_style := resources.Get "css/blog_extra.scss" | toCSS | minify | fingerprint }} - - {{ end }} - - {{ range .Page.Params.styles }} - - {{ end }} - diff --git a/themes/delphi/layouts/partials/head/meta.html b/themes/delphi/layouts/partials/head/meta.html new file mode 100644 index 000000000..e6478472f --- /dev/null +++ b/themes/delphi/layouts/partials/head/meta.html @@ -0,0 +1,20 @@ + + + + + +{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} | {{ .Site.Title }}{{ end }} + + + + + + + +{{ with .OutputFormats.Get "RSS" }} + {{ printf `` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }} +{{ end }} + +{{- if not .Site.IsServer -}} + {{ template "_internal/google_analytics.html" . }} +{{- end -}} diff --git a/themes/delphi/layouts/partials/head/styles.html b/themes/delphi/layouts/partials/head/styles.html new file mode 100644 index 000000000..3cac1ef9d --- /dev/null +++ b/themes/delphi/layouts/partials/head/styles.html @@ -0,0 +1,7 @@ + + + + + +{{ $main_style := resources.Get "css/main.scss" | toCSS | minify | fingerprint }} + diff --git a/themes/delphi/layouts/partials/landing/carousel.html b/themes/delphi/layouts/partials/landing/carousel.html new file mode 100644 index 000000000..e0a7b1054 --- /dev/null +++ b/themes/delphi/layouts/partials/landing/carousel.html @@ -0,0 +1,40 @@ +{{ $currentPage := . }} + diff --git a/themes/delphi/layouts/partials/landing/latest-card.html b/themes/delphi/layouts/partials/landing/latest-card.html index a2eb95025..d730da0bb 100644 --- a/themes/delphi/layouts/partials/landing/latest-card.html +++ b/themes/delphi/layouts/partials/landing/latest-card.html @@ -1,12 +1,12 @@ \ No newline at end of file +
        + {{ .title }} +
        +
        +
        {{ .source }}
        +

        {{ .title }}

        +
        + +
        diff --git a/themes/delphi/layouts/partials/landing/latest-news.html b/themes/delphi/layouts/partials/landing/latest-news.html index f75de565d..46026c558 100644 --- a/themes/delphi/layouts/partials/landing/latest-news.html +++ b/themes/delphi/layouts/partials/landing/latest-news.html @@ -1,29 +1,29 @@
        -

        Latest News

        - {{- $currentPage := . -}} - {{ define "partials/latest-blog" }} +

        Latest News

        + {{- $currentPage := . -}} + {{ define "partials/latest-blog" }} {{ return (dict "source" "blog" "image" .Params.heroImageThumb "title" .Title "link" .RelPermalink "date" .PublishDate ) }} - {{ end }} - {{ $items := apply (.Site.GetPage "/blog").Pages "partial" "latest-blog" "."}} - - + {{ end }} + {{ $items := apply (.Site.GetPage "/blog").Pages "partial" "latest-blog" "." }} - {{ $top := 6 }} - -
        -
        -
          - {{range first $top (sort $items "date" "desc")}} -
        • - {{ partial "landing/latest-card.html" .}} -
        • - {{end}} -
        -
        - - + {{ $top := 6 }} + +
        +
        +
          + {{ range first $top (sort $items "date" "desc") }} +
        • + {{ partial "landing/latest-card.html" . }} +
        • + {{ end }} +
        -
        \ No newline at end of file + + +
        +
        diff --git a/themes/delphi/layouts/partials/landing/teampic.html b/themes/delphi/layouts/partials/landing/teampic.html new file mode 100644 index 000000000..0d75142c7 --- /dev/null +++ b/themes/delphi/layouts/partials/landing/teampic.html @@ -0,0 +1,9 @@ +
        + {{ $team := .Site.GetPage "/about/team" }} + {{ $images := $team.Resources.ByType "image" }} + {{ $team := where $team.Params.team ".team" "intersect" (slice .team) }} + {{ range first 8 (sort $team "lastName" "asc" "firstName" "asc") }} + {{ $img := $images.GetMatch (path.Join "images" .image) }} + {{ printf + {{ end }} +
        diff --git a/themes/delphi/layouts/partials/legal.html b/themes/delphi/layouts/partials/legal.html new file mode 100644 index 000000000..11c048dd4 --- /dev/null +++ b/themes/delphi/layouts/partials/legal.html @@ -0,0 +1,12 @@ +
        +
          +
        • © 2020 Delphi group authors.
        • +
        + Text and figures released under CC BY 4.0; code under the MIT license. +
        diff --git a/themes/delphi/layouts/partials/menu/breadcrumb.html b/themes/delphi/layouts/partials/menu/breadcrumb.html index 8c4c9830e..0b587a5c1 100644 --- a/themes/delphi/layouts/partials/menu/breadcrumb.html +++ b/themes/delphi/layouts/partials/menu/breadcrumb.html @@ -1,11 +1,17 @@ {{ if .Parent }} -{{ if (not .Parent.IsHome) }} - + {{ if (not .Parent.IsHome) }} + + + {{ end }} {{ end }} -{{ end }} \ No newline at end of file diff --git a/themes/delphi/layouts/partials/menu/item.html b/themes/delphi/layouts/partials/menu/item.html index 323ec96c0..9298c1878 100644 --- a/themes/delphi/layouts/partials/menu/item.html +++ b/themes/delphi/layouts/partials/menu/item.html @@ -1,4 +1,4 @@ {{ if .Pre }} -{{ partial "font-awesome.html" .Pre }} -{{end}} -{{ .Name }} \ No newline at end of file + {{ partial "font-awesome.html" .Pre }} +{{ end }} +{{ .Name }} diff --git a/themes/delphi/layouts/partials/nav.html b/themes/delphi/layouts/partials/nav.html index 13d92b8ef..fb0d3d1cf 100644 --- a/themes/delphi/layouts/partials/nav.html +++ b/themes/delphi/layouts/partials/nav.html @@ -1,57 +1,65 @@ {{- $currentPage := . -}} - diff --git a/themes/delphi/layouts/partials/scripts.html b/themes/delphi/layouts/partials/scripts.html index a8b5a6d51..559fd48ab 100644 --- a/themes/delphi/layouts/partials/scripts.html +++ b/themes/delphi/layouts/partials/scripts.html @@ -1,11 +1,2 @@ {{ $script := resources.Get "js/main.js" | js.Build | minify | fingerprint -}} - - -{{ if eq .Page.Type "blog" }} -{{ $script_blog := resources.Get "js/blog/index.js" | js.Build | minify | fingerprint -}} - -{{ end }} - -{{ range .Page.Params.scripts }} - -{{ end }} + diff --git a/themes/delphi/layouts/partials/share.html b/themes/delphi/layouts/partials/share.html index ed1efa898..213090235 100644 --- a/themes/delphi/layouts/partials/share.html +++ b/themes/delphi/layouts/partials/share.html @@ -1,23 +1,29 @@ \ No newline at end of file + + {{ partial "font-awesome" "brands/twitter" }} + + + {{ partial "font-awesome" "brands/linkedin" }} + + + {{ partial "font-awesome" "brands/facebook" }} + +
        diff --git a/themes/delphi/layouts/section/archives.html b/themes/delphi/layouts/section/archives.html index 6f68b16c1..2db1fc057 100644 --- a/themes/delphi/layouts/section/archives.html +++ b/themes/delphi/layouts/section/archives.html @@ -1,26 +1,25 @@ {{ define "main" }} -
        - -

        Archives

        - - {{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }} - {{ range ($pages.GroupByDate "2006") }} -

        {{ .Key }}

        - + +

        Archives

        +
        + + {{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }} + {{ range ($pages.GroupByDate "2006") }} +

        {{ .Key }}

        + -
          - {{ range (.Pages) }} - -
        • - {{ .PublishDate.Format "Jan 2" }} - - {{ .Title }} - -
        • +
            + {{ range (.Pages) }} +
          • + {{ .PublishDate.Format "Jan 2" }} + + {{ .Title }} + +
          • + {{ end }} +
          {{ end }} -
        - {{ end }} +
        -
        {{ end }} diff --git a/themes/delphi/layouts/shortcodes/apiref.html b/themes/delphi/layouts/shortcodes/apiref.html index 841642031..2054c1f2a 100644 --- a/themes/delphi/layouts/shortcodes/apiref.html +++ b/themes/delphi/layouts/shortcodes/apiref.html @@ -1 +1 @@ -{{(print $.Page.Site.Params.apiUrl (cond (hasPrefix (.Get 0) "/") "" "/") (.Get 0)) | absURL}} \ No newline at end of file +{{ (print $.Page.Site.Params.apiUrl (cond (hasPrefix (.Get 0) "/") "" "/") (.Get 0)) | absURL }} diff --git a/themes/delphi/layouts/shortcodes/bibliography.html b/themes/delphi/layouts/shortcodes/bibliography.html index 74737dbcf..46b7a387e 100644 --- a/themes/delphi/layouts/shortcodes/bibliography.html +++ b/themes/delphi/layouts/shortcodes/bibliography.html @@ -1,15 +1,14 @@
          - {{ range $.Site.Data.bibliography}} -
        • - -

          - {{ .title }} -
          - {{ .authors}}
          - {{ .journal }} {{ .issue }} {{ if isset . "year" }} ({{ .year }}) - {{ end }} {{ if isset . "doi" }} DOI: - {{ .doi }}{{ end }} -

          -
        • + {{ range .Page.Params.bibliography }} +
        • + +

          + {{ .title }} +
          + {{ .authors }}
          + {{ .journal }} {{ .issue }} {{ if isset . "year" }} ({{ .year }}) {{ end }} + {{ if isset . "doi" }} DOI: {{ .doi }}{{ end }} +

          +
        • {{ end }} -
        \ No newline at end of file + diff --git a/themes/delphi/layouts/shortcodes/covidcast.html b/themes/delphi/layouts/shortcodes/covidcast.html deleted file mode 100644 index 38ab20304..000000000 --- a/themes/delphi/layouts/shortcodes/covidcast.html +++ /dev/null @@ -1,8 +0,0 @@ -
        - -
        diff --git a/themes/delphi/layouts/shortcodes/indicators.html b/themes/delphi/layouts/shortcodes/indicators.html deleted file mode 100644 index df6c2c47f..000000000 --- a/themes/delphi/layouts/shortcodes/indicators.html +++ /dev/null @@ -1,10 +0,0 @@ - -
        -{{ $tools := .Site.GetPage "/covidcast/indicators" }} -{{ range sort (where ($tools.Resources.ByType "page") ".Params.category" "eq" (.Get "category")) ".Params.order" }} -
        -

        {{ .Title }}

        - {{ .Content }} -
        -{{ end }} -
        \ No newline at end of file diff --git a/themes/delphi/layouts/shortcodes/news.html b/themes/delphi/layouts/shortcodes/news.html index 9954b5ed1..e2b3bea66 100644 --- a/themes/delphi/layouts/shortcodes/news.html +++ b/themes/delphi/layouts/shortcodes/news.html @@ -1,6 +1,5 @@ - {{ $news := .Site.GetPage "/news" }} -{{ range (sort ($news.Resources.ByType "page") ".PublishDate" "desc")}} +{{ range (sort ($news.Resources.ByType "page") ".PublishDate" "desc") }}

        {{ .PublishDate.Format "January 2006" }}

        {{ .Content }} -{{ end }} \ No newline at end of file +{{ end }} diff --git a/themes/delphi/layouts/shortcodes/releaselog.html b/themes/delphi/layouts/shortcodes/releaselog.html index c52bf063c..9f3fb5f10 100644 --- a/themes/delphi/layouts/shortcodes/releaselog.html +++ b/themes/delphi/layouts/shortcodes/releaselog.html @@ -1,12 +1,13 @@ - {{ $tools := .Site.GetPage "/covidcast/release-log/headless" }} \ No newline at end of file + + {{ end }} + diff --git a/themes/delphi/layouts/shortcodes/research-papers.html b/themes/delphi/layouts/shortcodes/research-papers.html index 92602cd84..2948530da 100644 --- a/themes/delphi/layouts/shortcodes/research-papers.html +++ b/themes/delphi/layouts/shortcodes/research-papers.html @@ -1,24 +1,22 @@ -{{ $images := .Page.Resources.ByType "image"}} +{{ $images := .Page.Resources.ByType "image" }}
        {{ range .Page.Params.papers }} - {{ $img := $images.GetMatch (path.Join "images" .image) }} -
        -
        {{ .year }}
        - -
        + {{ $img := $images.GetMatch (path.Join "images" .image) }} +
        +
        {{ .year }}
        + +
        -

        {{.title}}

        -
        - {{ .authors }} -
        -
        - {{.journal}}, {{ .year }} -
        +

        {{ .title }}

        +
        + {{ .authors }} +
        +
        {{ .journal }}, {{ .year }}
        +
        -
        - {{end}} + {{ end }}
        diff --git a/themes/delphi/layouts/shortcodes/systems.html b/themes/delphi/layouts/shortcodes/systems.html index f9bd413d3..e2ba8d50d 100644 --- a/themes/delphi/layouts/shortcodes/systems.html +++ b/themes/delphi/layouts/shortcodes/systems.html @@ -1,12 +1,11 @@ - {{ $tools := .Site.GetPage "/systems" }} {{ range sort ($tools.Resources.ByType "page") "Params.order" }}

        - {{ if isset .Params "externallink" }} - {{.Title}} - {{else}} - {{.Title}} - {{ end }} + {{ if isset .Params "externallink" }} + {{ .Title }} + {{ else }} + {{ .Title }} + {{ end }}

        {{ .Content }} -{{ end }} \ No newline at end of file +{{ end }} diff --git a/themes/delphi/layouts/shortcodes/team.html b/themes/delphi/layouts/shortcodes/team.html index 669cf1f23..8e28baccf 100644 --- a/themes/delphi/layouts/shortcodes/team.html +++ b/themes/delphi/layouts/shortcodes/team.html @@ -1,15 +1,18 @@ -{{ $images := .Page.Resources.ByType "image"}} -
        -{{ $team := where .Page.Params.team ".team" (.Get "team")}} -{{ range sort $team "lastName" "asc" "firstName" "asc"}} - {{ $img := $images.GetMatch (path.Join "images" .image) }} -
        - {{ .name }} -
        {{ printf "%s %s" .firstName .lastName }}
        +{{ $images := .Page.Resources.ByType "image" }} +
        + {{ $team := where .Page.Params.team ".team" "intersect" (slice (.Get "team")) }} + {{ range sort $team "lastName" "asc" "firstName" "asc" }} + {{ $img := $images.GetMatch (path.Join "images" .image) }} +
        + {{ printf +
        {{ printf "%s %s" .firstName .lastName | safeHTML }}
        {{ .affiliation }}
        {{ if isset . "note" }} -
        {{ .note }}
        +
        {{ .note }}
        {{ end }} -
        +
        {{ end }}
        diff --git a/themes/delphi/layouts/shortcodes/tools.html b/themes/delphi/layouts/shortcodes/tools.html index cfd19bd55..7f4789648 100644 --- a/themes/delphi/layouts/shortcodes/tools.html +++ b/themes/delphi/layouts/shortcodes/tools.html @@ -1,6 +1,5 @@ - {{ $tools := .Site.GetPage "/tools" }} {{ range sort ($tools.Resources.ByType "page") "Params.order" }} -

        {{ .Title}}

        +

        {{ .Title }}

        {{ .Content }} -{{ end }} \ No newline at end of file +{{ end }} diff --git a/themes/delphi/static/android-chrome-192x192.png b/themes/delphi/static/android-chrome-192x192.png new file mode 100644 index 000000000..3abd6f2d6 Binary files /dev/null and b/themes/delphi/static/android-chrome-192x192.png differ diff --git a/themes/delphi/static/android-chrome-512x512.png b/themes/delphi/static/android-chrome-512x512.png new file mode 100644 index 000000000..c051a468d Binary files /dev/null and b/themes/delphi/static/android-chrome-512x512.png differ diff --git a/themes/delphi/static/apple-touch-icon.png b/themes/delphi/static/apple-touch-icon.png new file mode 100644 index 000000000..502454541 Binary files /dev/null and b/themes/delphi/static/apple-touch-icon.png differ diff --git a/themes/delphi/static/browserconfig.xml b/themes/delphi/static/browserconfig.xml new file mode 100644 index 000000000..b3930d0f0 --- /dev/null +++ b/themes/delphi/static/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/themes/delphi/static/css/images/cmu_brand.png b/themes/delphi/static/css/images/cmu_brand.png new file mode 100644 index 000000000..988d4c995 Binary files /dev/null and b/themes/delphi/static/css/images/cmu_brand.png differ diff --git a/themes/delphi/static/css/images/cmu_brand_mobile.png b/themes/delphi/static/css/images/cmu_brand_mobile.png new file mode 100644 index 000000000..f69f3fab6 Binary files /dev/null and b/themes/delphi/static/css/images/cmu_brand_mobile.png differ diff --git a/themes/delphi/static/favicon-16x16.png b/themes/delphi/static/favicon-16x16.png new file mode 100644 index 000000000..493388ee6 Binary files /dev/null and b/themes/delphi/static/favicon-16x16.png differ diff --git a/themes/delphi/static/favicon-32x32.png b/themes/delphi/static/favicon-32x32.png new file mode 100644 index 000000000..6e8160f6d Binary files /dev/null and b/themes/delphi/static/favicon-32x32.png differ diff --git a/themes/delphi/static/favicon.ico b/themes/delphi/static/favicon.ico new file mode 100644 index 000000000..a16538b51 Binary files /dev/null and b/themes/delphi/static/favicon.ico differ diff --git a/themes/delphi/static/mstile-150x150.png b/themes/delphi/static/mstile-150x150.png new file mode 100644 index 000000000..2ae4cf9db Binary files /dev/null and b/themes/delphi/static/mstile-150x150.png differ diff --git a/themes/delphi/static/safari-pinned-tab.svg b/themes/delphi/static/safari-pinned-tab.svg new file mode 100644 index 000000000..feccc38eb --- /dev/null +++ b/themes/delphi/static/safari-pinned-tab.svg @@ -0,0 +1,17 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + diff --git a/themes/delphi/static/site.webmanifest b/themes/delphi/static/site.webmanifest new file mode 100644 index 000000000..f42417307 --- /dev/null +++ b/themes/delphi/static/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "DELPHI", + "short_name": "DELPHI", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +}