diff --git a/DESCRIPTION b/DESCRIPTION index ff75fca..163dbc7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,14 +1,16 @@ Package: catchpole Type: Package -Title: catchpole title goes here otherwise CRAN checks fail -Version: 0.1.0 -Date: 2020-03-01 +Title: 2020 Democrat POTUS Delegate Map Tracker +Version: 0.1.1 +Date: 2020-03-02 Authors@R: c( person("Bob", "Rudis", email = "bob@rud.is", role = c("aut", "cre"), - comment = c(ORCID = "0000-0001-5670-2640")) + comment = c(ORCID = "0000-0001-5670-2640")), + person("Brian", "McGill", role = "aut", + comment = "Creator of the lovingly handcrafted basemap") ) Maintainer: Bob Rudis -Description: A good description goes here otherwise CRAN checks fail. +Description: Tools to build a 2020 (D) delegate cartogram URL: https://git.rud.is/hrbrmstr/catchpole BugReports: https://git.rud.is/hrbrmstr/catchpole/issues Encoding: UTF-8 @@ -16,12 +18,13 @@ License: MIT + file LICENSE Suggests: covr, tinytest Depends: - R (>= 3.2.0) + R (>= 3.4.0), + sf Imports: - sf, dplyr, tidyr, jsonlite, + purrr, ggplot2, hrbrthemes Roxygen: list(markdown = TRUE) diff --git a/NAMESPACE b/NAMESPACE index e4755df..c5af636 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,23 @@ # Generated by roxygen2: do not edit by hand +export(delegates_map) +export(delegates_pal) +export(expand_candidates) export(gg_catchpole) export(read_delegates) -import(httr) +import(sf) +importFrom(dplyr,arrange) +importFrom(dplyr,bind_cols) +importFrom(dplyr,filter) +importFrom(dplyr,left_join) +importFrom(dplyr,tibble) +importFrom(ggplot2,aes) +importFrom(ggplot2,coord_sf) +importFrom(ggplot2,ggplot) +importFrom(ggplot2,guide_legend) +importFrom(ggplot2,guides) +importFrom(ggplot2,scale_fill_manual) +importFrom(hrbrthemes,theme_ft_rc) importFrom(jsonlite,fromJSON) +importFrom(purrr,map_df) +importFrom(tidyr,gather) diff --git a/R/catchpole-package.R b/R/catchpole-package.R index 9c9e898..0ebdc78 100644 --- a/R/catchpole-package.R +++ b/R/catchpole-package.R @@ -1,9 +1,21 @@ -#' ... -#' +#' 2020 Democrat POTUS Delegate Map Tracker +#' +#' @section Credit: +#' +#' The hard work was done by WSJ's Brian McGill ([@@brian_mcgill](https://twitter.com/brian_mcgill/)) who **manually crafted** the base cartogram over **days** then translated that into the beautiful and illuminating creation that is the WSJ online delegate tracker: . +#' +#' Brians's tweetnouncement: +#' #' @md #' @name catchpole #' @keywords internal #' @author Bob Rudis (bob@@rud.is) -#' @import httr +#' @author Brian McGill +#' @import sf +#' @importFrom purrr map_df +#' @importFrom dplyr left_join filter bind_cols tibble arrange +#' @importFrom tidyr gather +#' @importFrom ggplot2 ggplot aes scale_fill_manual guides guide_legend coord_sf +#' @importFrom hrbrthemes theme_ft_rc #' @importFrom jsonlite fromJSON "_PACKAGE" diff --git a/R/delegates-map.R b/R/delegates-map.R new file mode 100644 index 0000000..0ca297e --- /dev/null +++ b/R/delegates-map.R @@ -0,0 +1,6 @@ +#' Retrieves the delegates basemap +#' +#' @export +delegates_map <- function() { + delegates_sf +} \ No newline at end of file diff --git a/R/delegates-pal.R b/R/delegates-pal.R new file mode 100644 index 0000000..325fc3a --- /dev/null +++ b/R/delegates-pal.R @@ -0,0 +1,15 @@ +#' WSJ palette for the candidates likely getting delegates +#' +#' @docType data +#' @export +c( + "Biden" = "#5ac4c2", + "Sanders" = "#63bc51", + "Warren" = "#9574ae", + "Buttigieg" = "#007bb1", + "Klobuchar" = "#af973a", + "Bloomberg" = "#AA4671", + "Steyer" = "#4E4EAA", + "Yang" = "#C76C48", + "Gabbard" = "#7B8097" +) -> delegates_pal diff --git a/R/expand-candidates.R b/R/expand-candidates.R new file mode 100644 index 0000000..e45f653 --- /dev/null +++ b/R/expand-candidates.R @@ -0,0 +1,40 @@ +#' Expand the state totals per delegate into an indexed data frame +#' +#' @param delegates a data frame with `state`, `candidate`, and +#' `delegates` count or use the default which gets the +#' current data as long as the WSJ keeps it alive. +#' @export +expand_candidates <- function(delegates = read_delegates()) { + + map_df(unique(delegates$state), ~{ + + filter(delegates, state == .x) %>% + arrange(desc(delegates)) -> cur + + tibble( + state = character(0), + candidate = character(0), + idx = integer(0) + ) -> res + + last_idx <- 0 + + for (cand in unique(cur$candidate)) { + + tibble( + state = cur$state[1], + candidate = cand, + idx = (last_idx+1):(last_idx+1+cur[cur$candidate == cand,]$delegates) + ) -> out + + last_idx <- tail(out$idx, 1) + + res <- bind_rows(res, out) + + } + + res + + }) + +} diff --git a/R/gg-catchpole.R b/R/gg-catchpole.R index cd3a75a..5cc3a75 100644 --- a/R/gg-catchpole.R +++ b/R/gg-catchpole.R @@ -6,48 +6,7 @@ #' @export gg_catchpole <- function(delegates = read_delegates()) { - map_df(unique(delegates$state), ~{ - - filter(delegates, state == .x) %>% - arrange(desc(delegates)) -> cur - - tibble( - state = character(0), - candidate = character(0), - idx = integer(0) - ) -> res - - last_idx <- 0 - - for (cand in unique(cur$candidate)) { - - tibble( - state = cur$state[1], - candidate = cand, - idx = (last_idx+1):(last_idx+1+cur[cur$candidate == cand,]$delegates) - ) -> out - - last_idx <- tail(out$idx, 1) - - res <- bind_rows(res, out) - - } - - res - - }) -> candidates_expanded - - c( - "Biden" = "#5ac4c2", - "Sanders" = "#63bc51", - "Warren" = "#9574ae", - "Buttigieg" = "#007bb1", - "Klobuchar" = "#af973a", - "Bloomberg" = "#AA4671", - "Steyer" = "#4E4EAA", - "Yang" = "#C76C48", - "Gabbard" = "#7B8097" - ) -> dcols + candidates_expanded <- expand_candidates(delegates) gsf <- left_join(delegates_sf, candidates_expanded, by = c("state", "idx")) @@ -58,7 +17,7 @@ gg_catchpole <- function(delegates = read_delegates()) { col = "#617a89", shape = 22, size = 2, stroke = 0.125 ) + scale_fill_manual( - name = NULL, values = dcols, na.value = "gray20", + name = NULL, values = delegates_pal, na.value = "gray20", limits = intersect(unique(delegates$candidate), names(dcols)) ) + guides( diff --git a/README.Rmd b/README.Rmd index ae65ae4..196218e 100644 --- a/README.Rmd +++ b/README.Rmd @@ -15,6 +15,12 @@ hrbrpkghelpr::stinking_badges() hrbrpkghelpr::yank_title_and_description() ``` +## CREDIT + +The hard work was done by WSJ's Brian McGill ([@brian_mcgill](https://twitter.com/brian_mcgill/)) who **manually crafted** the base cartogram over **days** then translated that into the beautiful and illuminating creation that is the WSJ online delegate tracker: . + +Brians's tweetnouncement: + ## What's Inside The Tin The following functions are implemented: diff --git a/man/catchpole.Rd b/man/catchpole.Rd index f697986..2c8deac 100644 --- a/man/catchpole.Rd +++ b/man/catchpole.Rd @@ -4,10 +4,18 @@ \name{catchpole} \alias{catchpole} \alias{catchpole-package} -\title{...} +\title{2020 Democrat POTUS Delegate Map Tracker} \description{ -A good description goes here otherwise CRAN checks fail. +Tools to build a 2020 (D) delegate cartogram } +\section{Credit}{ + + +The hard work was done by WSJ's Brian McGill (\href{https://twitter.com/brian_mcgill/}{@brian_mcgill}) who \strong{manually crafted} the base cartogram over \strong{days} then translated that into the beautiful and illuminating creation that is the WSJ online delegate tracker: \url{https://www.wsj.com/graphics/elections/2020/track-the-delegate-count/}. + +Brians's tweetnouncement: \url{https://twitter.com/brian_mcgill/status/1222556373864648704?ref_src=twsrc\%5Etfw} +} + \seealso{ Useful links: \itemize{ @@ -18,5 +26,7 @@ Useful links: } \author{ Bob Rudis (bob@rud.is) + +Brian McGill } \keyword{internal} diff --git a/man/delegates_map.Rd b/man/delegates_map.Rd new file mode 100644 index 0000000..d85095b --- /dev/null +++ b/man/delegates_map.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/delegates-map.R +\name{delegates_map} +\alias{delegates_map} +\title{Retrieves the delegates basemap} +\usage{ +delegates_map() +} +\description{ +Retrieves the delegates basemap +} diff --git a/man/delegates_pal.Rd b/man/delegates_pal.Rd new file mode 100644 index 0000000..563c706 --- /dev/null +++ b/man/delegates_pal.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/delegates-pal.R +\docType{data} +\name{delegates_pal} +\alias{delegates_pal} +\title{WSJ palette for the candidates likely getting delegates} +\format{An object of class \code{character} of length 9.} +\usage{ +delegates_pal +} +\description{ +WSJ palette for the candidates likely getting delegates +} +\keyword{datasets} diff --git a/man/expand_candidates.Rd b/man/expand_candidates.Rd new file mode 100644 index 0000000..57cd414 --- /dev/null +++ b/man/expand_candidates.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/expand-candidates.R +\name{expand_candidates} +\alias{expand_candidates} +\title{Expand the state totals per delegate into an indexed data frame} +\usage{ +expand_candidates(delegates = read_delegates()) +} +\arguments{ +\item{delegates}{a data frame with \code{state}, \code{candidate}, and +\code{delegates} count or use the default which gets the +current data as long as the WSJ keeps it alive.} +} +\description{ +Expand the state totals per delegate into an indexed data frame +}