{"id":22966681,"url":"https://github.com/favstats/538_pred_results","last_synced_at":"2025-08-20T14:08:30.060Z","repository":{"id":108349421,"uuid":"157920946","full_name":"favstats/538_pred_results","owner":"favstats","description":"Assessing the 538 Predictions for the 2018 Midterm Elections","archived":false,"fork":false,"pushed_at":"2018-11-16T23:32:15.000Z","size":260,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T05:13:04.191Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/favstats.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-16T21:03:08.000Z","updated_at":"2019-04-22T18:28:21.000Z","dependencies_parsed_at":"2023-12-01T21:45:18.166Z","dependency_job_id":null,"html_url":"https://github.com/favstats/538_pred_results","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/favstats/538_pred_results","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/favstats%2F538_pred_results","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/favstats%2F538_pred_results/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/favstats%2F538_pred_results/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/favstats%2F538_pred_results/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/favstats","download_url":"https://codeload.github.com/favstats/538_pred_results/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/favstats%2F538_pred_results/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271330292,"owners_count":24740815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-20T02:00:09.606Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-14T20:45:01.694Z","updated_at":"2025-08-20T14:08:30.053Z","avatar_url":"https://github.com/favstats.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# 538_pred_results\n\nAssessing the 538 Predictions for the 2018 Midterm Elections\n\n## Packages\n\n``` r\n# Install these packages if you don't have them yet\n# if (!require(\"pacman\")) install.packages(\"pacman\")\n# devtools::install_github(\"favstats/tidytemplate\")\n\npacman::p_load(tidyverse, tidytemplate, janitor, ggthemes, ggpubr, rvest, ggrepel)\n```\n\n## Load Data\n\n``` r\ncsv_link \u003c- \"https://blogs.sciencemag.org/sciencehound/wp-content/uploads/sites/5/2018/11/Congressional-election-results-and-forecasts.csv\"\n\npred_dat \u003c- read_csv(csv_link) %\u003e% \n  clean_names() %\u003e% \n  mutate(close = ifelse(election_results \u003c= 55 \u0026 election_results \u003e= 45, \"Close\", \"Safe\")) %\u003e% \n  left_join(tibble(state = state.name, abbr =state.abb)) %\u003e% \n  mutate(distr_abbr = paste0(abbr, district))\n```\n\n\n``` r\npred_dat\n```\n\n    ## # A tibble: 435 x 14\n    ##    state district democratic_cand~ republican_cand~ election_results\n    ##    \u003cchr\u003e    \u003cint\u003e \u003cchr\u003e            \u003cchr\u003e                       \u003cdbl\u003e\n    ##  1 Alab~        1 Kennedy          Byrne                        36.7\n    ##  2 Alab~        2 Isner            Roby                         38.5\n    ##  3 Alab~        3 Hagan            Rogers                       36.2\n    ##  4 Alab~        4 Auman            Aderholt                     20.1\n    ##  5 Alab~        5 Joffrion         Brooks                       38.9\n    ##  6 Alab~        6 Kline            Palmer                       30.7\n    ##  7 Alab~        7 Sewell           -                           100  \n    ##  8 Alas~        1 Glavin           Young                        46  \n    ##  9 Ariz~        1 O'Halleran       Rogers                       53.8\n    ## 10 Ariz~        2 Kirkpatrick      Peterson                     54.4\n    ## # ... with 425 more rows, and 9 more variables: predicted_lite \u003cdbl\u003e,\n    ## #   predicted_classic \u003cdbl\u003e, predicted_deluxe \u003cdbl\u003e,\n    ## #   predicted_probability_deluxe \u003cdbl\u003e, correct_deluxe \u003cint\u003e,\n    ## #   democratic_win \u003cint\u003e, close \u003cchr\u003e, abbr \u003cchr\u003e, distr_abbr \u003cchr\u003e\n\n## How did 538 Predictions fare in the 2018 Midterm Elections?\n\n``` r\ntext_dat \u003c- pred_dat %\u003e% \n  count(correct_deluxe) %\u003e%\n  spread(correct_deluxe, n) %\u003e% \n  rename(incorrect = `0`, correct = `1`) %\u003e%\n  mutate(total = (incorrect + correct)) %\u003e% \n  mutate(perc_correct = round(((correct / total)*100), 2)) %\u003e% \n  mutate(label = glue::glue(\"538 predicted {correct} out of {total} races correctly ({perc_correct}%)\"))\n\npred_dat %\u003e% \n  mutate(correct_deluxe = as.factor(correct_deluxe)) %\u003e% \n  ggplot(aes(predicted_deluxe, election_results)) +\n  geom_point(aes(color = correct_deluxe)) +\n  theme_minimal() +\n  scale_color_colorblind() +\n  geom_smooth(method = \"lm\", color = \"black\", alpha = 0.4) +\n  theme(legend.position = \"bottom\") +\n  geom_text(data = text_dat, aes(x = 22, y = 97, label = label)) + \n  labs(title = \"How did 538 Predictions fare in the 2018 Midterm Elections?\",\n       x=\"Forecast from 538 Deluxe forecast % for Democratic candidates\", \n       y=\"Actual % for Democratic candidates from the election\",\n       subtitle = \"Black dots show 10 races that were wrongly predicted\",\n       caption = \"favstats.eu; @favstats\\nData: @jeremymberg\")  +\n  guides(color = F)  +\n  theme(plot.title = element_text(size = 13, face = \"bold\"),\n    plot.subtitle = element_text(size = 11, face = \"italic\"))\n```\n\n![](538_preds_files/figure-gfm/unnamed-chunk-2-1.png)\u003c!-- --\u003e\n\n``` r\nggsave_it(pred1, width = 10, height = 6)\n```\n\n## How did 538 Predictions fare in the 2018 Midterm Elections? - Close Races\n\n``` r\npred_dat %\u003e% \n  ggplot(aes(predicted_deluxe, election_results)) +\n  geom_point(aes(color = close)) +\n  theme_minimal() +\n  scale_color_colorblind() +\n  geom_hline(yintercept = 55, linetype = \"dashed\") +\n  geom_hline(yintercept = 45, linetype = \"dashed\") +\n  geom_smooth(method = \"lm\", color = \"black\", alpha = 0.4) +\n  theme(legend.position = \"bottom\") +\n  stat_cor() +\n  labs(title = \"How did 538 Predictions fare in the 2018 Midterm Elections?\",\n       x=\"Forecast from 538 Deluxe forecast % for Democratic candidates\",\n       y=\"Actual % for Democratic candidates from the election\",\n       subtitle = \"Black dots show 89 races that were close\",\n       caption = \"favstats.eu; @favstats\\nData: @jeremymberg\")  +\n  guides(color = F)  +\n  theme(plot.title = element_text(size = 13, face = \"bold\"),\n    plot.subtitle = element_text(size = 11, face = \"italic\"))\n```\n\n![](538_preds_files/figure-gfm/unnamed-chunk-3-1.png)\u003c!-- --\u003e\n\n``` r\nggsave_it(pred2, width = 10, height = 6)\n```\n\n## How did 538 Predictions fare in the 2018 Midterm Elections? - Close Races II\n\n``` r\npred_dat %\u003e% \n  mutate(correct_deluxe = as.factor(correct_deluxe)) %\u003e% \n  filter(close == \"Close\") %\u003e% \n  ggplot(aes(predicted_deluxe, election_results)) +\n  geom_point(aes(color = correct_deluxe)) +\n  theme_minimal() +\n  geom_hline(yintercept = 50, linetype = \"dashed\") +\n  scale_color_colorblind() +\n  scale_y_continuous(breaks = c(45, 50, 55)) +\n  geom_smooth(method = \"lm\", color = \"black\", alpha = 0.4) +\n  geom_text_repel(data = pred_dat %\u003e% filter(correct_deluxe == 0), aes(label = distr_abbr)) +\n  theme(legend.position = \"bottom\") +\n  stat_cor() +\n  labs(title = \"How did 538 Predictions fare in the 2018 Midterm Elections?\",\n       x=\"Forecast from 538 Deluxe forecast % for Democratic candidates\", \n       y=\"Actual % for Democratic candidates from the election\",\n       subtitle = \"Black dots show 10 races that were wrongly predicted\",\n       caption = \"favstats.eu; @favstats\\nData: @jeremymberg\")  +\n  guides(color = F)  +\n  theme(plot.title = element_text(size = 13, face = \"bold\"),\n    plot.subtitle = element_text(size = 11, face = \"italic\"))\n```\n\n![](538_preds_files/figure-gfm/analysis-1.png)\u003c!-- --\u003e\n\n``` r\nggsave_it(pred3, width = 10, height = 6)\n```\n\n## How did 538 Predictions fare in the 2018 Midterm Elections? - Prediction\n\n``` r\nhist_dat \u003c- pred_dat %\u003e% \n  mutate(diff = abs(election_results - predicted_deluxe)) %\u003e% \n  arrange(desc(diff)) \n\ndifference \u003c- mean(hist_dat$diff) %\u003e% round(2)\n\nhist_dat %\u003e% \n  ggplot(aes(diff)) +\n  theme_minimal() +\n  geom_histogram(alpha = 0.75) +\n  geom_vline(xintercept = difference, linetype = \"dashed\") +\n  geom_text(aes(x = difference + .5, y = 62, label = difference)) +\n  labs(title = \"How did 538 Predictions fare in the 2018 Midterm Elections?\",\n       x=\"Absolute Difference between 538 Forecast and Results in %\", \n       y=\"Frequency\",\n       caption = \"favstats.eu; @favstats\\nData: @jeremymberg\")  +\n  guides(color = F)  +\n  theme(plot.title = element_text(size = 13, face = \"bold\"))\n```\n\n    ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.\n\n![](538_preds_files/figure-gfm/unnamed-chunk-4-1.png)\u003c!-- --\u003e\n\n``` r\nggsave_it(pred4, width = 10, height = 6)\n```\n\n    ## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffavstats%2F538_pred_results","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffavstats%2F538_pred_results","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffavstats%2F538_pred_results/lists"}