├── .Rbuildignore ├── .gitignore ├── .travis.yml ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS ├── R ├── admin1.R ├── admin1_data.R ├── choropleth.R ├── choroplethr.R ├── choroplethr_acs.R ├── choroplethr_animate.R ├── choroplethr_wdi.R ├── country.R ├── country_data.R ├── county.R ├── county_data.R ├── county_zoom.R ├── state.R ├── state_data.R ├── usa.R ├── zip.R └── zip_data.R ├── README.md ├── choroplethr.Rproj ├── data ├── .Rapp.history ├── df_japan_census.rdata ├── df_pop_country.rdata ├── df_pop_county.rdata ├── df_pop_state.rdata ├── df_pop_zip.rdata ├── df_president.rdata └── df_president_ts.rdata ├── inst └── tests │ ├── test-country.R │ ├── test-county.R │ ├── test-num_buckets.R │ ├── test-state.R │ └── test-zip.R ├── man ├── Admin1Choropleth.Rd ├── CountryChoropleth.Rd ├── CountyChoropleth.Rd ├── CountyZoomChoropleth.Rd ├── StateChoropleth.Rd ├── USAChoropleth.Rd ├── ZipMap.Rd ├── admin1_choropleth.Rd ├── choroplethr.Rd ├── choroplethr_acs.Rd ├── choroplethr_animate.Rd ├── choroplethr_wdi.Rd ├── country_choropleth.Rd ├── county_choropleth.Rd ├── county_zoom_choropleth.Rd ├── df_japan_census.Rd ├── df_pop_country.Rd ├── df_pop_county.Rd ├── df_pop_state.Rd ├── df_pop_zip.Rd ├── df_president.Rd ├── df_president_ts.Rd ├── get_acs_df.Rd ├── state_choropleth.Rd └── zip_map.Rd ├── tests └── test-all.R ├── vignettes ├── a-introduction.Rmd ├── b-state-choropleth.Rmd ├── c-county-choropleth.Rmd ├── d-zip-map.Rmd ├── e-country-choropleth.Rmd ├── f-mapping-us-census-data.Rmd ├── g-world-bank-data.Rmd ├── h-animated-choropleths.Rmd ├── i-creating-your-own-maps.Rmd └── j-creating-admin1-maps.Rmd └── wiki-images ├── animation-screenshot.png ├── choroplethr-acs-state-pop.png ├── county-pop.png ├── election-2012.png ├── r6-examples ├── country.png ├── state-1.png └── state-2.png ├── state-pop-1m.png ├── state-pop-2-buckets.png ├── state-pop-9-buckets.png ├── state-pop-boxplot.png ├── state-pop-continuous-scale.png ├── state-pop.png ├── v20 ├── acs-example.png ├── country-pop-palette-2.png ├── country-pop-zoom-continuous.png ├── country-pop.png ├── county-pop-palette-2.png ├── county-pop-zoom-continuous.png ├── county-pop.png ├── create-you-own-map.png ├── election-red-blue.png ├── state-pop-zoom-continuous.png ├── state-pop.png ├── wdi-life-expect.png ├── wdi-per-capita.png ├── wdi-pop-continuous.png ├── zip-pop-palette-2.png ├── zip-pop-zoom-continuous.png └── zip-pop.png └── zip-pop.png /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^\.travis\.yml$ 4 | wiki-images 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .Rproj.user 3 | .Rhistory 4 | .RData 5 | .idea 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | before_install: 3 | - curl -OL http://raw.github.com/craigcitro/r-travis/master/scripts/travis-tool.sh 4 | - chmod 755 ./travis-tool.sh 5 | - ./travis-tool.sh bootstrap 6 | install: 7 | - ./travis-tool.sh r_binary_install Rcpp highlight 8 | - ./travis-tool.sh github_package hadley/testthat 9 | - ./travis-tool.sh install_deps 10 | script: ./travis-tool.sh run_tests 11 | before_script: 12 | - Rscript -e "library(acs); api.key.install('f8b2a6df01479981aef39577b3c4466f5a4c8274')" 13 | on_failure: 14 | - ./travis-tool.sh dump_logs 15 | branches: 16 | except: 17 | - /-expt$/ 18 | notifications: 19 | email: 20 | recipients: 21 | - arilamstein@gmail.com 22 | on_success: change 23 | on_failure: change 24 | env: 25 | global: 26 | secure: dJg3yqT+n5oTkRM1PzPhLy2cPzbKG/LPMvqdpNER298KzivMHnMjTOPz2NTc+TfeCfB6s0UROeaqMoCl6OkVqS6zXhnQkisdkJP8SsYZ+Pf5GTExSyeE3NEX/SNmjD+c9wufv8Un9T3CYzVh68VK4Ql5/VXAeTAIP2GqWOBLciY= 27 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: choroplethr 2 | Title: Simplify the Creation of Choropleth Maps in R 3 | Description: Choropleths are thematic maps where geographic regions, such as 4 | states, are colored according to some metric, such as the number of people 5 | who live in that state. choroplethr simplifies this process by 1. 6 | Providing ready-made functions for creating choropleths of common maps. 2. 7 | Providing API connections to interesting data sources for making 8 | choropleths. 3. Providing a framework for creating choropleths from 9 | arbitrary shapefiles. Please see the vignettes for more details. 10 | Version: 2.2.0 11 | Author: Ari Lamstein [cre, aut], 12 | Brian P Johnson [ctb, frontend animation code] 13 | Maintainer: Ari Lamstein 14 | URL: https://github.com/trulia/choroplethr/, 15 | https://groups.google.com/forum/#!forum/choroplethr 16 | BugReports: https://github.com/trulia/choroplethr/issues 17 | Copyright: Trulia, Inc. 18 | License: BSD_3_clause + file LICENSE 19 | Imports: 20 | scales, 21 | Hmisc, 22 | stringr, 23 | ggplot2, 24 | dplyr, 25 | R6, 26 | acs, 27 | WDI 28 | Suggests: 29 | testthat, 30 | zipcode, 31 | knitr, 32 | choroplethrMaps, 33 | choroplethrAdmin1 34 | Depends: 35 | R (>= 3.0.0) 36 | VignetteBuilder: knitr 37 | Collate: 38 | 'choropleth.R' 39 | 'admin1.R' 40 | 'admin1_data.R' 41 | 'choroplethr.R' 42 | 'choroplethr_acs.R' 43 | 'choroplethr_animate.R' 44 | 'choroplethr_wdi.R' 45 | 'country.R' 46 | 'country_data.R' 47 | 'usa.R' 48 | 'county.R' 49 | 'county_data.R' 50 | 'county_zoom.R' 51 | 'state.R' 52 | 'state_data.R' 53 | 'zip.R' 54 | 'zip_data.R' 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2013-2014 2 | COPYRIGHT HOLDER: Trulia, Inc. 3 | ORGANIZATION: Trulia, Inc. -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2 (4.0.2): do not edit by hand 2 | 3 | export(Admin1Choropleth) 4 | export(CountryChoropleth) 5 | export(CountyChoropleth) 6 | export(CountyZoomChoropleth) 7 | export(StateChoropleth) 8 | export(USAChoropleth) 9 | export(ZipMap) 10 | export(admin1_choropleth) 11 | export(choroplethr) 12 | export(choroplethr_acs) 13 | export(choroplethr_animate) 14 | export(choroplethr_wdi) 15 | export(country_choropleth) 16 | export(county_choropleth) 17 | export(county_zoom_choropleth) 18 | export(get_acs_df) 19 | export(state_choropleth) 20 | export(zip_map) 21 | importFrom(Hmisc,cut2) 22 | importFrom(R6,R6Class) 23 | importFrom(WDI,WDI) 24 | importFrom(acs,acs.fetch) 25 | importFrom(acs,estimate) 26 | importFrom(acs,geo.make) 27 | importFrom(acs,geography) 28 | importFrom(dplyr,left_join) 29 | importFrom(ggplot2,aes) 30 | importFrom(ggplot2,annotation_custom) 31 | importFrom(ggplot2,element_blank) 32 | importFrom(ggplot2,geom_point) 33 | importFrom(ggplot2,geom_polygon) 34 | importFrom(ggplot2,geom_text) 35 | importFrom(ggplot2,ggplot) 36 | importFrom(ggplot2,ggplotGrob) 37 | importFrom(ggplot2,ggsave) 38 | importFrom(ggplot2,ggtitle) 39 | importFrom(ggplot2,scale_color_brewer) 40 | importFrom(ggplot2,scale_color_continuous) 41 | importFrom(ggplot2,scale_colour_brewer) 42 | importFrom(ggplot2,scale_fill_brewer) 43 | importFrom(ggplot2,scale_fill_continuous) 44 | importFrom(ggplot2,theme) 45 | importFrom(ggplot2,theme_grey) 46 | importFrom(grid,grobTree) 47 | importFrom(grid,unit) 48 | importFrom(scales,comma) 49 | importFrom(stringr,fixed) 50 | importFrom(stringr,str_extract_all) 51 | importFrom(stringr,str_replace) 52 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | choroplethr 2.2.0 2 | ---------------------------------------------------------------- 3 | -Bug fix: zip_map wasn't working for zoom of HI or AK 4 | -Bug fix: documentation of choroplethr_animate() was not working 5 | 6 | 7 | choroplethr 2.1.1 8 | ---------------------------------------------------------------- 9 | -Bug fix: text for vignettes was for some reason not rebuilt into HTML. 10 | 11 | 12 | choroplethr 2.1.0 13 | ---------------------------------------------------------------- 14 | -Add function county_zoom_choropleth, which allows you to zoom in on counties, not states. If 15 | an individual county is specified, render it with no fill color. 16 | -Updated and corrected the values of df_president. Thank you to Richard Careaga. 17 | -Update vignettes about US maps. Specifically, provide information about custom scales to include warning about interactions with insets of AK and HI. 18 | -Add admin1_choropleth function which allows you to create an Administrative Level 1 choropleth of any 19 | country in the world. (Administrative Level 1 is the generic term for states, provinces, etc.). Create 20 | a vignette demonstrating usage of this function. 21 | 22 | choroplethr 2.0.0 23 | ---------------------------------------------------------------- 24 | 25 | -Move the maps and their helper data.frames to a separate package, choroplethrMaps 26 | -Change dependencies (remove dependencies on maps, grid, plyr->dplyr, add R6, add WDI) 27 | -Create R6 objects to simplify map creation 28 | -Base Choropleth object 29 | -CountryChoropleth inherits directly from Choropleth 30 | -Create USAChoropleth object to handle similar issues for all USA maps, such as insets and state boundaries 31 | -StateChoropleth, CountyChoropleth, ZipMap all inherit from those USAChoropleth 32 | -From a user's perspective, the only important functions on Choropleth are: new()/initialize() and render(). 33 | -From a developer's perspective, you care about three additional functions: clip(), discretize() and bind(). If you are using choroplethr as a framework to create your own choropleth, you might want to override those functions. Those functions are all called by prepare_map(). So in some sense, you just need to care about prepare_map() and render(). 34 | -Create helper functions for creating the 4 maps. See ?state_choropleth, ?county_choropleth, ?zip_map, ?country_choropleth for details. Importantly, all those functions have the five exact same parameters, four of which are optional. 35 | -Remove some functions that I think no one was using (see NAMESPACE diff for details) 36 | -Change some parameters on choroplethr_acs for consistency. 37 | -Break up the "data(choroplethr)" object. Now just say the object you actually want (e.g. "data(df_pop_state)"). This makes maintenance much easier. 38 | -Add choroplethr_wdi function, which generates choropleths from World Bank data. See the documentation of the WDI package for details. 39 | -Update function documentation and examples. 40 | -Update tests. 41 | -Change country.names from being a vector of English words to a data.frame with 2 columns: one named region (which contains English words), and one named "iso2c", which contains the iso2c equivalent names. 42 | 43 | BUG FIX 44 | -with character input for values inset maps were not having consistent scales with main map. Fix this by converting character input to factors early on. 45 | -setting custom scales and having the values work across insets (e.g. AK and HI) now works if you create a Choropleth object and set the ggplot_scale field to the scale you want. 46 | 47 | choroplethr 1.7.0 48 | ---------------------------------------------------------------- 49 | 50 | FEATURE 51 | -Add a world map: see ?map.world for more info 52 | -Add a vector of all countries in the world map: see ?country.names for more info 53 | -Add support for the world map to the choroplethr() function: see ?choroplethr for more info. 54 | 55 | choroplethr 1.6.0 56 | ---------------------------------------------------------------- 57 | 58 | FEATURE 59 | -Add a flag to the choroplethr() function, renderAsInsets. If TRUE and user asked to view all 60 | states, then AK and HI will be rendered as insets, which is the standard way of rendering a map of 61 | all 50 US states. 62 | -Create a data.frame, map.states, which contains a map for all 50 states plus the District of Columbia. See ?map.states for details. 63 | -Create a data.frame, state.names, which contains naming information for each state in map.states. See ?state.names for more information. 64 | -Create a data.frame, map.counties, which contains a map for the counties of all 50 states plus the District of Columbia. See ?map.counties for details. 65 | -Create a data.frame, county.names, which contains naming information for each county in map.counties. See ?county.names for more information. 66 | 67 | BUG FIXES 68 | 69 | choroplethr 1.5.0 70 | ---------------------------------------------------------------- 71 | 72 | FEATURE 73 | -Make NA values appear black on the map. The default value for NA values in ggplot2, grey50, was difficult to distinguish from the light values in the brewer scale. 74 | -Create function clip_df(data.frame, lod) that clips a data.frame to a map. This is useful 75 | when you want to do statistics on a data.frame (such as above/below median values), and have your computations match the map. For example, maps in choroplethr do not contain Alaska or Hawaii. 76 | -Rename vignettes so that they appear in proper order on CRAN website. 77 | -Export format_levels function 78 | 79 | BUG FIXES 80 | -handle counties with leading zeroes. 81 | 82 | choroplethr 1.4.0 83 | ---------------------------------------------------------------- 84 | 85 | FEATURE 86 | -New choroplethr_animate function for animating choropleth maps. See ?choroplethr_animate 87 | -Handle string data as values 88 | -add example datasets and update help 89 | -Add commas to scales. 90 | 91 | BUG FIXES 92 | -Choropleths of state, county and zip data with factor values were broken 93 | 94 | choroplethr 1.3.0 95 | ---------------------------------------------------------------- 96 | 97 | BUG FIXES 98 | -Subsetting by state was broken for state and county choropleths 99 | -Fix a bug where ACS state choropleths were not displaying titles 100 | 101 | FEATURES 102 | -Some features to support integration with shiny - requested by pssguy via github. 103 | -New function get_acs_column_names 104 | -New parameter column_idx parameter to function get_acs_df 105 | -Improve formatting of discrete scales 106 | 107 | choroplethr 1.2.0 108 | ---------------------------------------------------------------- 109 | 110 | FEATURES 111 | -Create 3 new functions which support a workflow of giving users more control of choropleths 112 | -get_acs_df, which gets an ACS table as a data.frame. You can then use, for example, cut2 to discretize the values as you see fit. 113 | -bind_df_to_map, which binds a data.frame of (region, value) pairs to a state, county or zip map. 114 | -render_choropleth, which renders a choropleth from (map, value) pairs. 115 | 116 | -Improve documentation 117 | 118 | choroplethr 1.1.0 119 | ---------------------------------------------------------------- 120 | 121 | FEATURES 122 | -Allow users to specify choropleths of a subset of states. See the "states" parameter in ?choroplethr and ?choroplethr_acs. 123 | -choroplethr_acs now supports year and span fields. See http://1.usa.gov/1geFSSj for a list of all ACS years with spans. However, see http://www.census.gov/developers/data/ for a list of which ACS are available via the Census API. Currently it is the 5-year surveys ending in 2010, 2011, 2012. Thanks to Ezra Haber Glenn for clarifying this. 124 | 125 | choroplethr 1.0.1 126 | ---------------------------------------------------------------- 127 | 128 | -Add requirement of minimum R version of 3.0.0 in the DESCRIPTION file. See https://groups.google.com/forum/#!topic/choroplethr/Owv7NgAacGE for details. 129 | -------------------------------------------------------------------------------- /R/admin1.R: -------------------------------------------------------------------------------- 1 | #' An R6 object for creating Administration Level 1 choropleths. 2 | #' @export 3 | #' @importFrom dplyr left_join 4 | #' @importFrom R6 R6Class 5 | #' @include choropleth.R 6 | Admin1Choropleth = R6Class("Admin1Choropleth", 7 | inherit = Choropleth, 8 | public = list( 9 | 10 | # initialize with a map of the country 11 | initialize = function(country.name, user.df) 12 | { 13 | if (!requireNamespace("choroplethrAdmin1", quietly = TRUE)) { 14 | stop("Package choroplethrAdmin1 is needed for this function to work. Please install it.", call. = FALSE) 15 | } 16 | 17 | admin1.map = get_admin1_map(country.name) 18 | super$initialize(admin1.map, user.df) 19 | 20 | if (private$has_invalid_regions) 21 | { 22 | warning("Please use ?get_admin1_regions in the chroplethrAdmin1 package to get a list of mappable regions") 23 | } 24 | } 25 | ) 26 | ) 27 | 28 | #' Create an admin1-level choropleth for a specified country 29 | #' 30 | #' The map used comes from ?admin1.map in the choroplethrAdmin1 package. See ?get_admin_countries 31 | #' and ?get_admin_regions in the choroplethrAdmin1 package for help with the spelling of regions. 32 | #' 33 | #' @param country.name The name of the country. Must exactly match how the country is named in the "country" 34 | #' column of ?admin1.regions in the choroplethrAdmin1 package. 35 | #' @param df A data.frame with a column named "region" and a column named "value". Elements in 36 | #' the "region" column must exactly match how regions are named in the "region" column in ?admin1.regions 37 | #' in the choroplethrAdmin1 package 38 | #' @param title An optional title for the map. 39 | #' @param legend An optional name for the legend. 40 | #' @param buckets The number of equally sized buckets to places the values in. A value of 1 41 | #' will use a continuous scale, and a value in [2, 9] will use that many buckets. 42 | #' @param zoom An optional vector of regions to zoom in on. Elements of this vector must exactly 43 | #' match the names of regions as they appear in the "region" column of ?admin1.regions. 44 | 45 | #' @examples 46 | #' \dontrun{ 47 | #' 48 | #' data(df_japan_census) 49 | #' head(df_japan_census) 50 | #' # set the value we want to map to be the 2010 population estimates 51 | #' df_japan_census$value=df_japan_census$pop_2010 52 | #' 53 | #' # default map of all of japan 54 | #' admin1_choropleth("japan", 55 | #' df_japan_census, 56 | #' "2010 Japan Population Estimates", 57 | #' "Population") 58 | #' 59 | #' # zoom in on the Kansai region and use a continuous scale 60 | #' kansai = c("mie", "nara", "wakayama", "kyoto", "osaka", "hyogo", "shiga") 61 | #' admin1_choropleth("japan", 62 | #' df_japan_census, 63 | #' "2010 Japan Population Estimates", 64 | #' "Population", 65 | #' 1, 66 | #' kansai) 67 | #' } 68 | #' @export 69 | #' @importFrom Hmisc cut2 70 | #' @importFrom stringr str_extract_all 71 | #' @importFrom ggplot2 ggplot aes geom_polygon scale_fill_brewer ggtitle theme theme_grey element_blank geom_text 72 | #' @importFrom ggplot2 scale_fill_continuous scale_colour_brewer ggplotGrob annotation_custom 73 | #' @importFrom scales comma 74 | #' @importFrom grid unit grobTree 75 | admin1_choropleth = function(country.name, df, title="", legend="", buckets=7, zoom=NULL) 76 | { 77 | if (!requireNamespace("choroplethrAdmin1", quietly = TRUE)) { 78 | stop("Package choroplethrAdmin1 is needed for this function to work. Please install it.", call. = FALSE) 79 | } 80 | c = Admin1Choropleth$new(country.name, df) 81 | c$title = title 82 | c$legend = legend 83 | c$set_buckets(buckets) 84 | c$set_zoom(zoom) 85 | c$render() 86 | } -------------------------------------------------------------------------------- /R/admin1_data.R: -------------------------------------------------------------------------------- 1 | #' A data.frame containing basic demographic information about Japan. 2 | #' 3 | #' @name df_japan_census 4 | #' @usage data(df_japan_census) 5 | #' @docType data 6 | #' @references Taken from the "Total Population" table from the Statistics Bureau of Japan website 7 | #' (\url{http://www.stat.go.jp/english/data/nenkan/1431-02.htm}) on 12/1/2014. 8 | #' @keywords data 9 | NULL -------------------------------------------------------------------------------- /R/choropleth.R: -------------------------------------------------------------------------------- 1 | #' @importFrom R6 R6Class 2 | #' @importFrom scales comma 3 | #' @importFrom ggplot2 scale_color_continuous 4 | Choropleth = R6Class("Choropleth", 5 | 6 | public = list( 7 | # the key objects for this class 8 | user.df = NULL, # input from user 9 | map.df = NULL, # geometry of the map 10 | choropleth.df = NULL, # result of binding user data with our map data 11 | 12 | title = "", # title for map 13 | legend = "", # title for legend 14 | warn = TRUE, # warn user on clipped or missing values 15 | ggplot_scale = NULL, # override default scale. 16 | # warning, you need to set "drop=FALSE" for insets to render correctly 17 | 18 | # a choropleth map is defined by these two variables 19 | # a data.frame of a map 20 | # a data.frame that expresses values for regions of each map 21 | initialize = function(map.df, user.df) 22 | { 23 | stopifnot(is.data.frame(map.df)) 24 | stopifnot("region" %in% colnames(map.df)) 25 | self$map.df = map.df 26 | 27 | # all input, regardless of map, is just a bunch of (region, value) pairs 28 | stopifnot(is.data.frame(user.df)) 29 | stopifnot(c("region", "value") %in% colnames(user.df)) 30 | self$user.df = user.df 31 | self$user.df = self$user.df[, c("region", "value")] 32 | 33 | stopifnot(anyDuplicated(self$user.df$region) == 0) 34 | 35 | # things like insets won't color properly if they are characters, and not factors 36 | if (is.character(self$user.df$value)) 37 | { 38 | self$user.df$value = as.factor(self$user.df$value) 39 | } 40 | 41 | # initialize the map to the max zoom - i.e. all regions 42 | self$set_zoom(NULL) 43 | 44 | # if the user's data contains values which are not on the map, 45 | # then emit a warning if appropriate 46 | if (self$warn) 47 | { 48 | all_regions = unique(self$map.df$region) 49 | user_regions = unique(self$user.df$region) 50 | invalid_regions = setdiff(user_regions, all_regions) 51 | if (length(invalid_regions) > 0) 52 | { 53 | invalid_regions = paste(invalid_regions, collapse = ", ") 54 | warning(paste0("Your data.frame contains the following regions which are not mappable: ", invalid_regions)) 55 | } 56 | } 57 | 58 | }, 59 | 60 | render = function() 61 | { 62 | self$prepare_map() 63 | 64 | ggplot(self$choropleth.df, aes(long, lat, group = group)) + 65 | geom_polygon(aes(fill = value), color = "dark grey", size = 0.2) + 66 | self$get_scale() + 67 | self$theme_clean() + 68 | ggtitle(self$title) 69 | }, 70 | 71 | # support e.g. users just viewing states on the west coast 72 | clip = function() { 73 | stopifnot(!is.null(private$zoom)) 74 | 75 | self$user.df = self$user.df[self$user.df$region %in% private$zoom, ] 76 | self$map.df = self$map.df[self$map.df$region %in% private$zoom, ] 77 | }, 78 | 79 | # for us, discretizing values means 80 | # 1. breaking the values into buckets equal intervals 81 | # 2. formatting the intervals e.g. with commas 82 | #' @importFrom Hmisc cut2 83 | discretize = function() 84 | { 85 | if (is.numeric(self$user.df$value) && private$buckets > 1) { 86 | 87 | # if cut2 uses scientific notation, our attempt to put in commas will fail 88 | scipen_orig = getOption("scipen") 89 | options(scipen=999) 90 | self$user.df$value = cut2(self$user.df$value, g = private$buckets) 91 | options(scipen=scipen_orig) 92 | 93 | levels(self$user.df$value) = sapply(levels(self$user.df$value), self$format_levels) 94 | } 95 | }, 96 | 97 | bind = function() { 98 | self$choropleth.df = left_join(self$map.df, self$user.df, by="region") 99 | missing_regions = unique(self$choropleth.df[is.na(self$choropleth.df$value), ]$region) 100 | if (self$warn && length(missing_regions) > 0) 101 | { 102 | missing_regions = paste(missing_regions, collapse = ", "); 103 | warning_string = paste("The following regions were missing and are being set to NA:", missing_regions); 104 | warning(warning_string); 105 | } 106 | 107 | self$choropleth.df = self$choropleth.df[order(self$choropleth.df$order), ]; 108 | }, 109 | 110 | prepare_map = function() 111 | { 112 | self$clip() # clip the input - e.g. remove value for Washington DC on a 50 state map 113 | self$discretize() # discretize the input. normally people don't want a continuous scale 114 | self$bind() # bind the input values to the map values 115 | }, 116 | 117 | #' @importFrom scales comma 118 | get_scale = function() 119 | { 120 | if (!is.null(self$ggplot_scale)) 121 | { 122 | self$ggplot_scale 123 | } else if (private$buckets == 1) { 124 | 125 | min_value = min(self$choropleth.df$value, na.rm = TRUE) 126 | max_value = max(self$choropleth.df$value, na.rm = TRUE) 127 | stopifnot(!is.na(min_value) && !is.na(max_value)) 128 | 129 | # by default, scale_fill_continuous uses a light value for high values and a dark value for low values 130 | # however, this is the opposite of how choropleths are normally colored (see wikipedia) 131 | # these low and high values are from the 7 color brewer blue scale (see colorbrewer.org) 132 | scale_fill_continuous(self$legend, low="#eff3ff", high="#084594", labels=comma, na.value="black", limits=c(min_value, max_value)) 133 | } else { 134 | scale_fill_brewer(self$legend, drop=FALSE, labels=comma, na.value="black") 135 | } 136 | }, 137 | 138 | #' Removes axes, margins and sets the background to white. 139 | #' This code, with minor modifications, comes from section 13.19 140 | # "Making a Map with a Clean Background" of "R Graphics Cookbook" by Winston Chang. 141 | # Reused with permission. 142 | theme_clean = function() 143 | { 144 | theme( 145 | axis.title = element_blank(), 146 | axis.text = element_blank(), 147 | panel.background = element_blank(), 148 | panel.grid = element_blank(), 149 | axis.ticks.length = unit(0, "cm"), 150 | axis.ticks.margin = unit(0, "cm"), 151 | panel.margin = unit(0, "lines"), 152 | plot.margin = unit(c(0, 0, 0, 0), "lines"), 153 | complete = TRUE 154 | ) 155 | }, 156 | 157 | # like theme clean, but also remove the legend 158 | theme_inset = function() 159 | { 160 | theme( 161 | legend.position = "none", 162 | axis.title = element_blank(), 163 | axis.text = element_blank(), 164 | panel.background = element_blank(), 165 | panel.grid = element_blank(), 166 | axis.ticks.length = unit(0, "cm"), 167 | axis.ticks.margin = unit(0, "cm"), 168 | panel.margin = unit(0, "lines"), 169 | plot.margin = unit(c(0, 0, 0, 0), "lines"), 170 | complete = TRUE 171 | ) 172 | }, 173 | 174 | #' Make the output of cut2 a bit easier to read 175 | #' 176 | #' Adds commas to numbers, removes unnecessary whitespace and allows an arbitrary separator. 177 | #' 178 | #' @param x A factor with levels created via Hmisc::cut2. 179 | #' @param nsep A separator which you wish to use. Defaults to " to ". 180 | #' 181 | #' @export 182 | #' @examples 183 | #' data(df_pop_state) 184 | #' 185 | #' x = Hmisc::cut2(df_pop_state$value, g=3) 186 | #' levels(x) 187 | #' # [1] "[ 562803, 2851183)" "[2851183, 6353226)" "[6353226,37325068]" 188 | #' levels(x) = sapply(levels(x), format_levels) 189 | #' levels(x) 190 | #' # [1] "[562,803 to 2,851,183)" "[2,851,183 to 6,353,226)" "[6,353,226 to 37,325,068]" 191 | #' 192 | #' @seealso \url{http://stackoverflow.com/questions/22416612/how-can-i-get-cut2-to-use-commas/}, which this implementation is based on. 193 | #' @importFrom stringr str_extract_all 194 | format_levels = function(x, nsep=" to ") 195 | { 196 | n = str_extract_all(x, "[-+]?[0-9]*\\.?[0-9]+")[[1]] # extract numbers 197 | v = format(as.numeric(n), big.mark=",", trim=TRUE) # change format 198 | x = as.character(x) 199 | 200 | # preserve starting [ or ( if appropriate 201 | prefix = "" 202 | if (substring(x, 1, 1) %in% c("[", "(")) 203 | { 204 | prefix = substring(x, 1, 1) 205 | } 206 | 207 | # preserve ending ] or ) if appropriate 208 | suffix = "" 209 | if (substring(x, nchar(x), nchar(x)) %in% c("]", ")")) 210 | { 211 | suffix = substring(x, nchar(x), nchar(x)) 212 | } 213 | 214 | # recombine 215 | paste0(prefix, paste(v,collapse=nsep), suffix) 216 | }, 217 | 218 | set_zoom = function(zoom) 219 | { 220 | if (is.null(zoom)) 221 | { 222 | # initialize the map to the max zoom - i.e. all regions 223 | private$zoom = unique(self$map.df$region) 224 | } else { 225 | stopifnot(all(zoom %in% unique(self$map.df$region))) 226 | private$zoom = zoom 227 | } 228 | }, 229 | get_zoom = function() { private$zoom }, 230 | 231 | set_buckets = function(buckets) 232 | { 233 | # if R's ?is.integer actually tested if a value was an integer, we could replace the 234 | # first 2 tests with is.integer(buckets) 235 | stopifnot(is.numeric(buckets) 236 | && buckets%%1 == 0 237 | && buckets > 0 238 | && buckets < 10) 239 | 240 | private$buckets = buckets 241 | } 242 | ), 243 | 244 | private = list( 245 | zoom = NULL, # a vector of regions to zoom in on. if NULL, show all 246 | buckets = 7, # number of equally-sized buckets for scale. if 1 then use a continuous scale 247 | has_invalid_regions = FALSE 248 | ) 249 | ) 250 | -------------------------------------------------------------------------------- /R/choroplethr.R: -------------------------------------------------------------------------------- 1 | #' Create a choropleth 2 | #' 3 | #' This function is deprecated as of choroplether version 2.0.0. Please use ?state_choropleth, 4 | #' ?county_choropleth, ?zip_map and ?country_choroplethr instead. The last version of choroplethr 5 | #' in which this function worked was version 1.7.0, which can be downloaded from CRAN 6 | #' here: http://cran.r-project.org/web/packages/choroplethr/index.html")) 7 | #' 8 | #' @param 9 | #' ... All arguments are ignored. 10 | #' 11 | #' @export 12 | choroplethr = function(...) 13 | { 14 | warning(paste("This function is deprecated as of choroplether version 2.0.0.", 15 | "Please use ?state_choropleth, ?county_choropleth, ?zip_map and ?country_choroplethr instead.", 16 | "The last version of choroplethr in which this function worked was version 1.7.0, which can be downloaded", 17 | "from CRAN here: http://cran.r-project.org/web/packages/choroplethr/index.html")) 18 | } -------------------------------------------------------------------------------- /R/choroplethr_acs.R: -------------------------------------------------------------------------------- 1 | if (base::getRversion() >= "2.15.1") { 2 | utils::globalVariables(c("state.fips")) 3 | } 4 | 5 | #' Create a choropleth from ACS data. 6 | #' 7 | #' Creates a choropleth using the US Census' American Community Survey (ACS) data. 8 | #' Requires the acs package to be installed, and a Census API Key to be set with 9 | #' the acs's api.key.install function. Census API keys can be obtained at http://www.census.gov/developers/tos/key_request.html. 10 | #' 11 | #' @param tableId The id of an ACS table 12 | #' @param map A string indicating which map the data is for. Must be "state", "county" or "zip". 13 | #' @param endyear The end year of the survey to use. See acs.fetch (?acs.fetch) and http://1.usa.gov/1geFSSj for details. 14 | #' @param span The span of time to use. See acs.fetch and http://1.usa.gov/1geFSSj for details. 15 | #' on the same longitude and latitude map to scale. This variable is only checked when the "states" variable is equal to all 50 states. 16 | #' @param buckets The number of equally sized buckets to places the values in. A value of 1 17 | #' will use a continuous scale, and a value in [2, 9] will use that many buckets. 18 | #' @param zoom An optional list of states to zoom in on. Must come from the "name" column in 19 | #' ?state.regions. 20 | #' @return A choropleth. 21 | #' 22 | #' @keywords choropleth, acs 23 | #' 24 | #' @seealso \code{api.key.install} in the acs package which sets an Census API key for the acs library 25 | #' @seealso http://factfinder2.census.gov/faces/help/jsf/pages/metadata.xhtml?lang=en&type=survey&id=survey.en.ACS_ACS 26 | #' which contains a list of all ACS surveys. 27 | #' @references Uses the acs package created by Ezra Haber Glenn. 28 | 29 | #' @export 30 | #' @examples 31 | #' \dontrun{ 32 | #' # population of all states, 9 equally sized buckets 33 | #' choroplethr_acs("B01003", "state") 34 | #' 35 | #' # median income, continuous scale, counties in New York, New Jersey and Connecticut 36 | #' choroplethr_acs("B19301", "county", buckets=1, zoom=c("new york", "new jersey", "connecticut")) 37 | #' 38 | #' # median income, all zip codes 39 | #' choroplethr_acs("B19301", "zip") } 40 | #' @importFrom acs acs.fetch geography estimate geo.make 41 | choroplethr_acs = function(tableId, map, endyear=2011, span=5, buckets=7, zoom=NULL) 42 | { 43 | stopifnot(map %in% c("state", "county", "zip")) 44 | stopifnot(buckets > 0 && buckets < 10) 45 | 46 | acs.data = acs.fetch(geography=make_geo(map), table.number = tableId, col.names = "pretty", endyear = endyear, span = span) 47 | column_idx = get_column_idx(acs.data, tableId) # some tables have multiple columns 48 | title = acs.data@acs.colnames[column_idx] 49 | acs.df = make_df(map, acs.data, column_idx) # choroplethr requires a df 50 | 51 | if (map=="state") { 52 | state_choropleth(acs.df, title, "", buckets, zoom) 53 | } else if (map=="county") { 54 | county_choropleth(acs.df, title, "", buckets, zoom) 55 | } else if (map=="zip") { 56 | zip_map(acs.df, title, "", buckets, zoom) 57 | } 58 | } 59 | 60 | #' Returns a data.frame representing American Community Survey estimates. 61 | #' 62 | #' Requires the acs package to be installed, and a Census API Key to be set with the 63 | #' acs's api.key.install function. Census API keys can be obtained at http://www.census.gov/developers/tos/key_request.html. 64 | #' 65 | #' @param tableId The id of an ACS table. 66 | #' @param map The map you want the data to match. Must be one of "state", "county" or "zip". 67 | #' @param endyear The end year of the survey. Defaults to 2012. 68 | #' @param span The span of the survey. Defaults to 5. 69 | #' @param column_idx An optional column index to specify. 70 | #' @return A data.frame. 71 | #' @export 72 | #' @seealso http://factfinder2.census.gov/faces/help/jsf/pages/metadata.xhtml?lang=en&type=survey&id=survey.en.ACS_ACS, which lists all ACS Surveys. 73 | #' @importFrom acs acs.fetch geography estimate geo.make 74 | #' @examples 75 | #' \dontrun{ 76 | #' library(Hmisc) # for cut2 77 | #' # States with greater than 1M residents 78 | #' df = get_acs_df("B01003", "state") # population 79 | #' df$value = cut2(df$value, cuts=c(0,1000000,Inf)) 80 | #' state_choropleth(df, title="States with a population over 1M", legend="Population") 81 | #' 82 | #' # Counties with greater than or greater than 1M residents 83 | #' df = get_acs_df("B01003", "county") # population 84 | #' df$value = cut2(df$value, cuts=c(0,1000000,Inf)) 85 | #' county_choropleth(df, title="Counties with a population over 1M", legend="Population") 86 | #' 87 | #' # ZIP codes in California where median age is between 20 and 30 88 | #' df = get_acs_df("B01002", "zip") # median age 89 | #' df = df[df$value >= 20 & df$value <= 30, ] 90 | #' df$value = cut2(df$value, g=3) # 3 equally-sized groups 91 | #' zip_map(df, title="CA Zip Codes by Age", legend="Median Age", zoom="california") 92 | #' } 93 | get_acs_df = function(tableId, map, endyear=2012, span=5, column_idx = -1) 94 | { 95 | stopifnot(map %in% c("state", "county", "zip")) 96 | 97 | acs.data = acs.fetch(geography=make_geo(map), table.number = tableId, col.names = "pretty", endyear = endyear, span = span) 98 | if (column_idx == -1) { 99 | column_idx = get_column_idx(acs.data, tableId) # some tables have multiple columns 100 | } 101 | make_df(map, acs.data, column_idx) # turn into df 102 | } 103 | 104 | # support multiple column tables 105 | get_column_idx = function(acs.data, tableId) 106 | { 107 | column_idx = 1 108 | if (length(acs.data@acs.colnames) > 1) 109 | { 110 | num_cols = length(acs.data@acs.colnames) 111 | title = paste0("Table ", tableId, " has ", num_cols, " columns. Please choose which column to render:") 112 | column_idx = menu(acs.data@acs.colnames, title=title) 113 | } 114 | column_idx 115 | } 116 | 117 | make_geo = function(map) 118 | { 119 | stopifnot(map %in% c("state", "county", "zip")) 120 | if (map == "state") { 121 | geo.make(state = "*") 122 | } else if (map == "county") { 123 | geo.make(state = "*", county = "*") 124 | } else { 125 | geo.make(zip.code = "*") 126 | } 127 | } 128 | 129 | make_df = function(map, acs.data, column_idx) 130 | { 131 | stopifnot(map %in% c("state", "county", "zip")) 132 | 133 | if (map == "state") { 134 | df = data.frame(region = tolower(geography(acs.data)$NAME), 135 | value = as.numeric(estimate(acs.data[,column_idx]))); 136 | df[df$region != "puerto rico", ] 137 | } else if (map == "county") { 138 | # create fips code 139 | acs.data@geography$fips = paste(as.character(acs.data@geography$state), 140 | acs.data@geography$county, 141 | sep = "") 142 | # put in format for call to all_county_choropleth 143 | acs.data@geography$fips = as.numeric(acs.data@geography$fips) 144 | df = data.frame(region = geography(acs.data)$fips, 145 | value = as.numeric(estimate(acs.data[,column_idx]))); 146 | # remove state fips code 72, which is Puerto Rico, which we don't map 147 | df[df$region < 72000 | df$region > 72999, ] 148 | } else if (map == "zip") { 149 | # put in format for call to choroplethr 150 | acs.df = data.frame(region = geography(acs.data)$zipcodetabulationarea, 151 | value = as.numeric(estimate(acs.data[,column_idx]))) 152 | 153 | na.omit(acs.df) # surprisingly, this sometimes returns NA values 154 | } 155 | } -------------------------------------------------------------------------------- /R/choroplethr_animate.R: -------------------------------------------------------------------------------- 1 | #' Animate a list of chropleths 2 | #' 3 | #' Given a list of choropleths, represented as ggplot2 objects 4 | #' \enumerate{ 5 | #' \item Save the individual images to the working directory with the naming convention "choropleth_1.png", "choropleth_2.png", etc. 6 | #' \item Write a file called "animated_choropleth.html" which contains a viewer which animates them. 7 | #' } 8 | #' 9 | #' @param choropleths A list of choropleths represented as ggplot2 objects. 10 | #' @return Nothing. However, a variable number of files are written to the current working directory. 11 | #' 12 | #' @keywords choropleth animation 13 | #' @author Ari Lamstein (R code) and Brian Johnson (JavaScript, HTML and CSS code) 14 | #' 15 | #' @importFrom ggplot2 ggsave 16 | #' @importFrom stringr str_replace fixed 17 | #' @export 18 | #' @examples 19 | #' \dontrun{ 20 | #' data(df_president_ts) 21 | #' ?df_president_ts # time series of all US presidential elections 1789-2012 22 | #' 23 | #' # create a list of choropleths of presidential election results for each year 24 | #' choropleths = list() 25 | #' for (i in 2:(ncol(df_president_ts))) { 26 | #' df = df_president_ts[, c(1, i)] 27 | #' colnames(df) = c("region", "value") 28 | #' title = paste0("Presidential Election Results: ", colnames(df_president_ts)[i]) 29 | #' choropleths[[i-1]] = state_choropleth(df, title=title) 30 | #' } 31 | #' 32 | #' # set working directory and animate 33 | #' setwd("~/Desktop") 34 | #' choroplethr_animate(choropleths) 35 | #' } 36 | choroplethr_animate = function(choropleths) 37 | { 38 | stopifnot(is.list(choropleths)) 39 | print(paste0("All files will be written to the current working directory: ", getwd(), " . To change this use setwd()")) 40 | print("Now writing individual choropleth files there as 'choropleth_1.png', 'choropleth_2.png', etc.") 41 | 42 | # save individual frames 43 | for (i in 1:length(choropleths)) 44 | { 45 | filename = paste0("choropleth_", i, ".png") 46 | ggsave(filename=filename, plot=choropleths[[i]]) 47 | } 48 | 49 | # this is the html for an animated map 50 | # you need to replace {{minMaps}} and {{maxMaps}} with the min and max indices of frames 51 | txt = ' 52 | 53 | 54 | Choroplethr Playr 55 | 56 | 57 | 76 | 77 | 78 | 79 |
80 | 107 |
108 |
109 | 111 |
112 |
113 | 114 |
115 | 116 | 117 | 118 | 119 | 120 | 121 | 213 | 214 | 215 | ' 216 | 217 | txt = str_replace(txt, fixed("[[[max]]]"), length(choropleths)) 218 | print("Now writing code to animate all images in 'animated_choropleth.html'. Please open that file with a browser.") 219 | write(txt, "animated_choropleth.html") 220 | } -------------------------------------------------------------------------------- /R/choroplethr_wdi.R: -------------------------------------------------------------------------------- 1 | #' Create a country-level choropleth using data from the World Bank's World Development Indicators (WDI). 2 | #' 3 | #' @param code The WDI code to use. 4 | #' @param year The year of data to use. 5 | #' @param title A title for the map. If not specified, automatically generated to include WDI code and year. 6 | #' @param buckets The number of equally sized buckets to places the values in. A value of 1 7 | #' will use a continuous scale, and a value in [2, 9] will use that many buckets. 8 | #' @param zoom An optional list of countries to zoom in on. Must come from the "name" column in 9 | #' ?country.regions. 10 | #' 11 | #' @examples 12 | #' \dontrun{ 13 | #' # See http://data.worldbank.org/indicator/SP.POP.TOTL 14 | #' choroplethr_wdi(code="SP.POP.TOTL", year=2012, title="2012 Population Estimates", buckets=1) 15 | #' 16 | #' # See http://data.worldbank.org/indicator/SP.DYN.LE00.IN 17 | #' choroplethr_wdi(code="SP.DYN.LE00.IN", year=2012, title="2012 Life Expectancy Estimates") 18 | #' 19 | #' # See http://data.worldbank.org/indicator/NY.GDP.PCAP.CD 20 | #' choroplethr_wdi(code="NY.GDP.PCAP.CD", year=2012, title="2012 Per Capita Income") 21 | #' } 22 | #' 23 | #' @return A choropleth. 24 | #' 25 | #' @references Uses the WDI function from the WDI package by Vincent Arel-Bundock. 26 | #' @export 27 | #' @importFrom WDI WDI 28 | choroplethr_wdi = function(code="SP.POP.TOTL", year=2012, title="", buckets=7, zoom=NULL) 29 | { 30 | data(country.regions, package="choroplethrMaps", envir=environment()) 31 | if (is.null(title)) 32 | { 33 | title = paste0("WDI Indicator ", code, " for year ", year) 34 | } 35 | 36 | data = WDI(country=country.regions$iso2c, code, start=year, end=year) 37 | data = merge(data, country.regions) 38 | data$value = data[, names(data) == code] # choroplethr requires value column to be named "value" 39 | 40 | country_choropleth(data, title, "", buckets, zoom) 41 | } -------------------------------------------------------------------------------- /R/country.R: -------------------------------------------------------------------------------- 1 | #' An R6 object for creating country-level choropleths. 2 | #' @export 3 | #' @importFrom dplyr left_join 4 | #' @importFrom R6 R6Class 5 | #' @include choropleth.R 6 | CountryChoropleth = R6Class("CountryChoropleth", 7 | inherit = Choropleth, 8 | public = list( 9 | 10 | # initialize with a world map 11 | initialize = function(user.df) 12 | { 13 | if (!requireNamespace("choroplethrMaps", quietly = TRUE)) { 14 | stop("Package choroplethrMaps is needed for this function to work. Please install it.", call. = FALSE) 15 | } 16 | 17 | data(country.map, package="choroplethrMaps", envir=environment()) 18 | super$initialize(country.map, user.df) 19 | 20 | if (private$has_invalid_regions) 21 | { 22 | warning("Please see ?country.regions for a list of mappable regions") 23 | } 24 | } 25 | ) 26 | ) 27 | 28 | #' Create a country-level choropleth 29 | #' 30 | #' The map used is country.map in the choroplethrMaps package. See country.regions for 31 | #' an object which can help you coerce your regions into the required format. 32 | #' 33 | #' @param df A data.frame with a column named "region" and a column named "value". Elements in 34 | #' the "region" column must exactly match how regions are named in the "region" column in ?country.map. 35 | #' @param title An optional title for the map. 36 | #' @param legend An optional name for the legend. 37 | #' @param buckets The number of equally sized buckets to places the values in. A value of 1 38 | #' will use a continuous scale, and a value in [2, 9] will use that many buckets. 39 | #' @param zoom An optional vector of countries to zoom in on. Elements of this vector must exactly 40 | #' match the names of countries as they appear in the "region" column of ?country.regions 41 | 42 | #' @examples 43 | #' # demonstrate default options 44 | #' data(df_pop_country) 45 | #' country_choropleth(df_pop_country, "2012 World Bank Populate Estimates") 46 | #' 47 | #' # demonstrate continuous scale 48 | #' country_choropleth(df_pop_country, "2012 World Bank Populate Estimates", buckets=1) 49 | #' 50 | #' # demonstrate zooming 51 | #' country_choropleth(df_pop_country, 52 | #' "2012 World Bank Population Estimates", 53 | #' buckets=1, 54 | #' zoom=c("united states of america", "canada", "mexico")) 55 | 56 | #' @export 57 | #' @importFrom Hmisc cut2 58 | #' @importFrom stringr str_extract_all 59 | #' @importFrom ggplot2 ggplot aes geom_polygon scale_fill_brewer ggtitle theme theme_grey element_blank geom_text 60 | #' @importFrom ggplot2 scale_fill_continuous scale_colour_brewer ggplotGrob annotation_custom 61 | #' @importFrom scales comma 62 | #' @importFrom grid unit grobTree 63 | country_choropleth = function(df, title="", legend="", buckets=7, zoom=NULL) 64 | { 65 | c = CountryChoropleth$new(df) 66 | c$title = title 67 | c$legend = legend 68 | c$set_buckets(buckets) 69 | c$set_zoom(zoom) 70 | c$render() 71 | } 72 | -------------------------------------------------------------------------------- /R/country_data.R: -------------------------------------------------------------------------------- 1 | #' A data.frame containing population estimates for Countries in 2012. 2 | #' 3 | #' @name df_pop_country 4 | #' @docType data 5 | #' @references Taken from the WDI package with code SP.POP.TOTL for year 2012. 6 | #' 7 | #' @keywords data 8 | #' @usage data(df_pop_country) 9 | NULL -------------------------------------------------------------------------------- /R/county.R: -------------------------------------------------------------------------------- 1 | #' Create a county-level choropleth 2 | #' @export 3 | #' @importFrom dplyr left_join 4 | #' @include usa.R 5 | CountyChoropleth = R6Class("CountyChoropleth", 6 | inherit = USAChoropleth, 7 | 8 | public = list( 9 | # this map looks better with an outline of the states added 10 | add_state_outline = TRUE, 11 | 12 | # initialize with us state map 13 | initialize = function(user.df) 14 | { 15 | if (!requireNamespace("choroplethrMaps", quietly = TRUE)) { 16 | stop("Package choroplethrMaps is needed for this function to work. Please install it.", call. = FALSE) 17 | } 18 | 19 | data(county.map, package="choroplethrMaps", envir=environment()) 20 | data(county.regions, package="choroplethrMaps", envir=environment()) 21 | # USAChoropleth requires a column called "state" that has full lower case state name (e.g. "new york") 22 | county.map$state = merge(county.map, county.regions, sort=FALSE, by.x="region", by.y="region")$state.name 23 | super$initialize(county.map, user.df) 24 | 25 | # by default, show all states on the map 26 | data(state.map, package="choroplethrMaps", envir=environment()) 27 | private$zoom = unique(state.map$region) 28 | 29 | if (private$has_invalid_regions) 30 | { 31 | warning("Please see ?county.regions for a list of mappable regions") 32 | } 33 | 34 | }, 35 | 36 | # user.df has county FIPS codes for regions, but subsetting happens at the state level 37 | clip = function() 38 | { 39 | # remove regions not on the map before doing the merge 40 | data(county.regions, package="choroplethrMaps", envir=environment()) 41 | 42 | self$user.df = self$user.df[self$user.df$region %in% county.regions$region, ] 43 | self$user.df$state = merge(self$user.df, county.regions, sort=FALSE, all.X=TRUE, by.x="region", by.y="region")$state.name 44 | self$user.df = self$user.df[self$user.df$state %in% private$zoom, ] 45 | self$user.df$state = NULL 46 | 47 | self$map.df = self$map.df[self$map.df$state %in% private$zoom, ] 48 | } 49 | ) 50 | ) 51 | 52 | 53 | #' Create a choropleth of USA Counties with sensible defaults. 54 | #' 55 | #' The map used is county.map in the choroplethrMaps package. See country.regions 56 | #' in the choroplethrMaps package for an object which can help you coerce your regions 57 | #' into the required format. 58 | #' 59 | #' @param df A data.frame with a column named "region" and a column named "value". Elements in 60 | #' the "region" column must exactly match how regions are named in the "region" column in county.map. 61 | #' @param title An optional title for the map. 62 | #' @param legend An optional name for the legend. 63 | #' @param buckets The number of equally sized buckets to places the values in. A value of 1 64 | #' will use a continuous scale, and a value in [2, 9] will use that many buckets. 65 | #' @param zoom An optional vector of states to zoom in on. Elements of this vector must exactly 66 | #' match the names of states as they appear in the "region" column of ?state.regions. 67 | #' 68 | #' @examples 69 | #' \dontrun{ 70 | #' # demonstrate default parameters - visualization using 7 equally sized buckets 71 | #' data(df_pop_county) 72 | #' county_choropleth(df_pop_county, title="US 2012 County Population Estimates", legend="Population") 73 | #' 74 | #'#' # demonstrate continuous scale and zoom 75 | #' data(df_pop_county) 76 | #' county_choropleth(df_pop_county, 77 | #' title="US 2012 County Population Estimates", 78 | #' legend="Population", 79 | #' buckets=1, 80 | #' zoom=c("california", "oregon", "washington")) 81 | #' 82 | #' # demonstrate how choroplethr handles character and factor values 83 | #' # demonstrate user creating their own discretization of the input 84 | #' data(df_pop_county) 85 | #' df_pop_county$str = "" 86 | #' for (i in 1:nrow(df_pop_county)) 87 | #' { 88 | #' if (df_pop_county[i,"value"] < 1000000) 89 | #' { 90 | #' df_pop_county[i,"str"] = "< 1M" 91 | #' } else { 92 | #' df_pop_county[i,"str"] = "> 1M" 93 | #' } 94 | #' } 95 | #' df_pop_county$value = df_pop_county$str 96 | #' county_choropleth(df_pop_county, title="Which counties have more than 1M people?") 97 | #' } 98 | #' @export 99 | #' @importFrom Hmisc cut2 100 | #' @importFrom stringr str_extract_all 101 | #' @importFrom ggplot2 ggplot aes geom_polygon scale_fill_brewer ggtitle theme theme_grey element_blank geom_text 102 | #' @importFrom ggplot2 scale_fill_continuous scale_colour_brewer 103 | #' @importFrom scales comma 104 | #' @importFrom grid unit 105 | county_choropleth = function(df, title="", legend="", buckets=7, zoom=NULL) 106 | { 107 | c = CountyChoropleth$new(df) 108 | c$title = title 109 | c$legend = legend 110 | c$set_buckets(buckets) 111 | c$set_zoom(zoom) 112 | c$render() 113 | } 114 | -------------------------------------------------------------------------------- /R/county_data.R: -------------------------------------------------------------------------------- 1 | #' A data.frame containing population estimates for US Counties in 2012. 2 | #' 3 | #' @name df_pop_county 4 | #' @docType data 5 | #' @references Taken from the US American Community Survey (ACS) 5 year estimates. 6 | #' 7 | #' @keywords data 8 | #' @usage data(df_pop_county) 9 | NULL 10 | -------------------------------------------------------------------------------- /R/county_zoom.R: -------------------------------------------------------------------------------- 1 | #' Create a county-level choropleth that zooms on counties, not states. 2 | #' @export 3 | #' @importFrom dplyr left_join 4 | #' @include usa.R 5 | CountyZoomChoropleth = R6Class("CountyZoomChoropleth", 6 | inherit = Choropleth, 7 | 8 | public = list( 9 | # initialize with us state map 10 | initialize = function(user.df) 11 | { 12 | if (!requireNamespace("choroplethrMaps", quietly = TRUE)) { 13 | stop("Package choroplethrMaps is needed for this function to work. Please install it.", call. = FALSE) 14 | } 15 | 16 | data(county.map, package="choroplethrMaps", envir=environment()) 17 | data(county.regions, package="choroplethrMaps", envir=environment()) 18 | super$initialize(county.map, user.df) 19 | 20 | # by default, show all counties on the map 21 | private$zoom = unique(county.map$region) 22 | 23 | if (private$has_invalid_regions) 24 | { 25 | warning("Please see ?county.regions for a list of mappable regions") 26 | } 27 | }, 28 | 29 | render = function() 30 | { 31 | if (length(private$zoom) > 1) 32 | { 33 | super$render() 34 | } else { 35 | self$prepare_map() 36 | 37 | ggplot(self$choropleth.df, aes(long, lat, group = group)) + 38 | geom_path(color = "black", size = 1) + 39 | self$theme_clean() + 40 | ggtitle(self$title) 41 | } 42 | } 43 | ) 44 | ) 45 | 46 | #' Create a choropleth of USA Counties, with sensible defaults, that zooms on counties. 47 | #' 48 | #' The map used is county.map in the choroplethrMaps package. See country.regions 49 | #' in the choroplethrMaps package for an object which can help you coerce your regions 50 | #' into the required format. If you zoom in on a single county, only an outline of the 51 | #' county is shown. 52 | #' 53 | #' @param df A data.frame with a column named "region" and a column named "value". Elements in 54 | #' the "region" column must exactly match how regions are named in the "region" column in county.map. 55 | #' @param title An optional title for the map. 56 | #' @param legend An optional name for the legend. Ignored if zooming in on a single county. 57 | #' @param buckets The number of equally sized buckets to places the values in. A value of 1 58 | #' will use a continuous scale, and a value in [2, 9] will use that many buckets. Ignored if 59 | #' zooming in on a single county. 60 | #' @param zoom An optional vector of counties to zoom in on. Elements of this vector must exactly 61 | #' match the names of counties as they appear in the "region" column of ?county.regions. 62 | #' 63 | #' @examples 64 | #' \dontrun{ 65 | #' 66 | #' library(choroplethrMaps) 67 | #' data(county.regions) 68 | #' 69 | #' library(dplyr) 70 | #' 71 | #' # show the population of the 5 counties (boroughs) that make up New York City 72 | #' nyc_county_names=c("kings", "bronx", "new york", "queens", "richmond") 73 | #' nyc_county_fips = county.regions %>% 74 | #' filter(state.name=="new york" & county.name %in% nyc_county_names) %>% 75 | #' select(region) 76 | #' county_zoom_choropleth(df_pop_county, 77 | #' title="Population of Counties in New York City", 78 | #' legend="Population", 79 | #' buckets=1, 80 | #' zoom=nyc_county_fips$region) 81 | #' 82 | #' # zooming in on a single county shows just an outline. 83 | #' county_zoom_choropleth(df_pop_county, 84 | #' title="Zoom of Manhattan", 85 | #' zoom=36061) # manhattan 86 | #' 87 | #' # population of the 9 counties in the san francisco bay area 88 | #' bay_area_county_names = c("alameda", "contra costa", "marin", "napa", "san francisco", 89 | #' "san mateo", "santa clara", "solano", "sonoma") 90 | #' bay_area_county_fips = county.regions %>% 91 | #' filter(state.name=="california" & county.name %in% bay_area_county_names) %>% 92 | #' select(region) 93 | #' county_zoom_choropleth(df_pop_county, 94 | #' title="Population of Counties in the San Francisco Bay Area", 95 | #' legend="Population", 96 | #' buckets=1, 97 | #' zoom=bay_area_county_fips$region) 98 | #' } 99 | #' @export 100 | #' @importFrom Hmisc cut2 101 | #' @importFrom stringr str_extract_all 102 | #' @importFrom ggplot2 ggplot aes geom_polygon scale_fill_brewer ggtitle theme theme_grey element_blank geom_text 103 | #' @importFrom ggplot2 scale_fill_continuous scale_colour_brewer 104 | #' @importFrom scales comma 105 | #' @importFrom grid unit 106 | county_zoom_choropleth = function(df, title="", legend="", buckets=7, zoom=NULL) 107 | { 108 | c = CountyZoomChoropleth$new(df) 109 | c$title = title 110 | c$legend = legend 111 | c$set_buckets(buckets) 112 | c$set_zoom(zoom) 113 | c$render() 114 | } 115 | -------------------------------------------------------------------------------- /R/state.R: -------------------------------------------------------------------------------- 1 | #' Create a state-level choropleth 2 | #' @export 3 | #' @importFrom dplyr left_join 4 | #' @include usa.R 5 | StateChoropleth = R6Class("StateChoropleth", 6 | inherit = USAChoropleth, 7 | 8 | public = list( 9 | show_labels = TRUE, 10 | 11 | # initialize with us state map 12 | initialize = function(user.df) 13 | { 14 | if (!requireNamespace("choroplethrMaps", quietly = TRUE)) { 15 | stop("Package choroplethrMaps is needed for this function to work. Please install it.", call. = FALSE) 16 | } 17 | 18 | data(state.map, package="choroplethrMaps", envir=environment()) 19 | state.map$state = state.map$region 20 | super$initialize(state.map, user.df) 21 | 22 | if (private$has_invalid_regions) 23 | { 24 | warning("Please see ?state.regions for a list of mappable regions") 25 | } 26 | }, 27 | 28 | render = function() 29 | { 30 | choropleth = super$render() 31 | 32 | # by default, add labels for the lower 48 states 33 | if (self$show_labels) { 34 | df_state_labels = data.frame(long = state.center$x, lat = state.center$y, name=tolower(state.name), label = state.abb) 35 | df_state_labels = df_state_labels[!df_state_labels$name %in% c("alaska", "hawaii"), ] 36 | df_state_labels = df_state_labels[df_state_labels$name %in% private$zoom, ] 37 | 38 | choropleth = choropleth + geom_text(data = df_state_labels, aes(long, lat, label = label, group = NULL), color = 'black') 39 | } 40 | 41 | choropleth 42 | } 43 | ) 44 | ) 45 | 46 | 47 | #' Create a choropleth of US States with sensible defaults. 48 | #' 49 | #' The map used is state.map in the package choroplethrMaps. See state.regions in 50 | #' the choroplethrMaps package for a data.frame that can help you coerce your regions 51 | #' into the required format. 52 | #' 53 | #' @param df A data.frame with a column named "region" and a column named "value". Elements in 54 | #' the "region" column must exactly match how regions are named in the "region" column in state.map. 55 | #' @param title An optional title for the map. 56 | #' @param legend An optional name for the legend. 57 | #' @param buckets The number of equally sized buckets to places the values in. A value of 1 58 | #' will use a continuous scale, and a value in [2, 9] will use that many buckets. 59 | #' @param zoom An optional vector of states to zoom in on. Elements of this vector must exactly 60 | #' match the names of states as they appear in the "region" column of ?state.regions. 61 | #' 62 | #' @examples 63 | #' # demonstrate default parameters - visualization using 7 equally sized buckets 64 | #' data(df_pop_state) 65 | #' state_choropleth(df_pop_state, title="US 2012 State Population Estimates", legend="Population") 66 | #' 67 | #' # demonstrate continuous scale and zoom 68 | #' data(df_pop_state) 69 | #' state_choropleth(df_pop_state, 70 | #' title="US 2012 State Population Estimates", 71 | #' legend="Population", 72 | #' buckets=1, 73 | #' zoom=c("california", "oregon", "washington")) 74 | #' 75 | #' # demonstrate how choroplethr handles character and factor values 76 | #' # demonstrate user creating their own discretization of the input 77 | #' data(df_pop_state) 78 | #' df_pop_state$str = "" 79 | #' for (i in 1:nrow(df_pop_state)) 80 | #' { 81 | #' if (df_pop_state[i,"value"] < 1000000) 82 | #' { 83 | #' df_pop_state[i,"str"] = "< 1M" 84 | #' } else { 85 | #' df_pop_state[i,"str"] = "> 1M" 86 | #' } 87 | #' } 88 | #' df_pop_state$value = df_pop_state$str 89 | #' state_choropleth(df_pop_state, title="Which states have less than 1M people?") 90 | #' 91 | #' @export 92 | #' @importFrom Hmisc cut2 93 | #' @importFrom stringr str_extract_all 94 | #' @importFrom ggplot2 ggplot aes geom_polygon scale_fill_brewer ggtitle theme theme_grey element_blank geom_text 95 | #' @importFrom ggplot2 scale_fill_continuous scale_colour_brewer 96 | #' @importFrom scales comma 97 | #' @importFrom grid unit 98 | state_choropleth = function(df, title="", legend="", buckets=7, zoom=NULL) 99 | { 100 | c = StateChoropleth$new(df) 101 | c$title = title 102 | c$legend = legend 103 | c$set_buckets(buckets) 104 | c$set_zoom(zoom) 105 | c$render() 106 | } 107 | -------------------------------------------------------------------------------- /R/state_data.R: -------------------------------------------------------------------------------- 1 | #' A data.frame containing election results from the 2012 US Presidential election. 2 | #' 3 | #' @name df_president 4 | #' @usage data(df_president) 5 | #' @docType data 6 | #' @references Taken from the FEC website on 11/21/2014. 7 | #' @keywords data 8 | #' @author Ari Lamstein and Richard Careaga 9 | NULL 10 | 11 | #' A data.frame containing population estimates for US States in 2012. 12 | #' 13 | #' @name df_pop_state 14 | #' @docType data 15 | #' @references Taken from the US American Community Survey (ACS) 5 year estimates. 16 | #' 17 | #' @keywords data 18 | #' @usage data(df_pop_state) 19 | NULL 20 | 21 | #' A data.frame containing all US presdiential election results from 1789 to 2012 22 | #' 23 | #' Legend: 24 | #' \itemize{ 25 | #' \item R = Republican 26 | #' \item D = Democratic 27 | #' \item DR = Democratic-Republican 28 | #' \item W = Whig 29 | #' \item F = Federalist 30 | #' \item GW = George Washington 31 | #' \item NR = National Republican 32 | #' \item SD = Southern Democrat 33 | #' \item PR = Progressive 34 | #' \item AI = American Independent 35 | #' \item SR = States' Rights 36 | #' \item PO = Populist 37 | #' \item CU = Constitutional Union 38 | #' \item I = Independent 39 | #' \item ND = Northern Democrat 40 | #' \item KN = Know Nothing 41 | #' \item AM = Anti-Masonic 42 | #' \item N = Nullifier 43 | #' \item SP = Split evenly 44 | #' } 45 | #' @docType data 46 | #' @references Taken from \url{http://en.wikipedia.org/wiki/List_of_United_States_presidential_election_results_by_state} 3/20/2014. 47 | #' @keywords data 48 | #' @name df_president_ts 49 | #' @usage data(df_president_ts) 50 | NULL -------------------------------------------------------------------------------- /R/usa.R: -------------------------------------------------------------------------------- 1 | #' Normal choropleth that draws Alaska and Hawaii as insets. 2 | #' In addition to a columns named "region" and "value", also requires a column named "state". 3 | #' @export 4 | #' @importFrom dplyr left_join 5 | #' @include choropleth.R 6 | USAChoropleth = R6Class("USAChoropleth", 7 | inherit = Choropleth, 8 | 9 | public = list( 10 | add_state_outline = FALSE, 11 | 12 | initialize = function(map.df, user.df) 13 | { 14 | super$initialize(map.df, user.df) 15 | # need a state field for doing insets of AK and HI 16 | stopifnot("state" %in% colnames(map.df)) 17 | }, 18 | 19 | # render the map, with AK and HI as insets 20 | render = function() 21 | { 22 | self$prepare_map() 23 | 24 | if (private$zoom == "alaska" || private$zoom == "hawaii") { 25 | choro = self$render_helper(self$choropleth.df, self$scale_name, self$theme_clean()) + ggtitle(self$title) 26 | if (self$add_state_outline) 27 | { 28 | choro + self$render_state_outline(private$zoom) 29 | } 30 | } else { 31 | # remove AK and HI from the "real" df 32 | continental.df = self$choropleth.df[!self$choropleth.df$state %in% c("alaska", "hawaii"), ] 33 | continental.ggplot = self$render_helper(continental.df, self$scale_name, self$theme_clean()) + ggtitle(self$title) 34 | if (self$add_state_outline) 35 | { 36 | continental.regions = subset(private$zoom, private$zoom!="alaska" & private$zoom!="hawaii") 37 | continental.ggplot = continental.ggplot + self$render_state_outline(continental.regions) 38 | } 39 | 40 | ret = continental.ggplot 41 | 42 | # subset AK and render it 43 | if (is.null(private$zoom) || 'alaska' %in% private$zoom) 44 | { 45 | alaska.df = self$choropleth.df[self$choropleth.df$state=='alaska',] 46 | alaska.ggplot = self$render_helper(alaska.df, "", self$theme_inset()) 47 | if (self$add_state_outline) 48 | { 49 | alaska.ggplot = alaska.ggplot + self$render_state_outline('alaska') 50 | } 51 | alaska.grob = ggplotGrob(alaska.ggplot) 52 | ret = ret + annotation_custom(grobTree(alaska.grob), xmin=-125, xmax=-110, ymin=22.5, ymax=30) 53 | } 54 | 55 | # subset HI and render it 56 | if (is.null(private$zoom) || 'hawaii' %in% private$zoom) 57 | { 58 | hawaii.df = self$choropleth.df[self$choropleth.df$state=='hawaii',] 59 | hawaii.ggplot = self$render_helper(hawaii.df, "", self$theme_inset()) 60 | if (self$add_state_outline) 61 | { 62 | hawaii.ggplot = hawaii.ggplot + self$render_state_outline('hawaii') 63 | } 64 | hawaii.grob = ggplotGrob(hawaii.ggplot) 65 | ret = ret + annotation_custom(grobTree(hawaii.grob), xmin=-107.5, xmax=-102.5, ymin=25, ymax=27.5) 66 | } 67 | 68 | ret + 69 | ggtitle(self$title) 70 | } 71 | }, 72 | 73 | render_helper = function(choropleth.df, scale_name, theme) 74 | { 75 | # maps with numeric values are mapped with a continuous scale 76 | if (is.numeric(choropleth.df$value)) 77 | { 78 | ggplot(choropleth.df, aes(long, lat, group = group)) + 79 | geom_polygon(aes(fill = value), color = "dark grey", size = 0.2) + 80 | self$get_scale() + 81 | theme; 82 | } else { # assume character or factor 83 | stopifnot(length(unique(na.omit(choropleth.df$value))) <= 9) # brewer scale only goes up to 9 84 | 85 | ggplot(choropleth.df, aes(long, lat, group = group)) + 86 | geom_polygon(aes(fill = value), color = "dark grey", size = 0.2) + 87 | self$get_scale() + 88 | theme; 89 | } 90 | }, 91 | 92 | render_state_outline = function(states) 93 | { 94 | if (!requireNamespace("choroplethrMaps", quietly = TRUE)) { 95 | stop("Package choroplethrMaps is needed for this function to work. Please install it.", call. = FALSE) 96 | } 97 | 98 | data(state.map, package="choroplethrMaps", envir=environment()) 99 | data(state.regions, package="choroplethrMaps", envir=environment()) 100 | 101 | stopifnot(states %in% state.regions$region) 102 | 103 | df = state.map[state.map$region %in% states, ] 104 | geom_polygon(data=df, aes(long, lat, group = group), color = "black", fill = NA, size = 0.2); 105 | }, 106 | 107 | # all maps of US states zoom at the unit of states. 108 | set_zoom = function(zoom) 109 | { 110 | if (!requireNamespace("choroplethrMaps", quietly = TRUE)) { 111 | stop("Package choroplethrMaps is needed for this function to work. Please install it.", call. = FALSE) 112 | } 113 | 114 | data(state.map, package="choroplethrMaps", envir=environment()) 115 | all_states = unique(state.map$region) 116 | 117 | if (is.null(zoom)) 118 | { 119 | # initialize the map to the max zoom - i.e. all regions 120 | private$zoom = all_states 121 | } else { 122 | stopifnot(all(zoom %in% all_states)) 123 | private$zoom = zoom 124 | } 125 | } 126 | ) 127 | ) 128 | 129 | -------------------------------------------------------------------------------- /R/zip.R: -------------------------------------------------------------------------------- 1 | if (base::getRversion() >= "2.15.1") { 2 | utils::globalVariables(c("country.regions")) 3 | } 4 | 5 | #' Create a county-level choropleth 6 | #' @export 7 | #' @importFrom dplyr left_join 8 | #' @include usa.R 9 | ZipMap = R6Class("CountyChoropleth", 10 | inherit = USAChoropleth, 11 | 12 | public = list( 13 | # this map looks better with an outline of the states added 14 | add_state_outline = TRUE, 15 | 16 | # there are lots of ZIPs in the official list that don't exist in any meaningful sense. 17 | # because of that, just delete them by default 18 | rm_na = TRUE, 19 | 20 | # initialize with us state map 21 | initialize = function(user.df) 22 | { 23 | # there are lots of zips in the zipcode that are not "real" zips, and so 24 | # warning on them would likely do more harm than good 25 | self$warn = FALSE 26 | 27 | # load zip code data 28 | data(zipcode, package="zipcode", envir=environment()) 29 | 30 | # only include states 31 | zipcode = zipcode[zipcode$state %in% state.abb, ] 32 | # remove bad data. 33 | # it has two zips in NY and VA in the atlantic/europe 34 | zipcode = zipcode[zipcode$longitude < -10, ] 35 | 36 | # rename variables so base class can process 37 | names(zipcode)[names(zipcode) == "zip" ] = "region" 38 | names(zipcode)[names(zipcode) == "longitude"] = "long" 39 | names(zipcode)[names(zipcode) == "latitude" ] = "lat" 40 | 41 | # USAChoropleth requires a column called "state" that has full lower case state name (e.g. "new york") 42 | zipcode$state = tolower(state.name[match(zipcode$state, state.abb)]) 43 | 44 | super$initialize(zipcode, user.df) 45 | 46 | # by default, show all states on the map 47 | data(state.map, package="choroplethrMaps", envir=environment()) 48 | private$zoom = unique(state.map$region) 49 | }, 50 | 51 | # support e.g. users just viewing states on the west coast 52 | clip = function() { 53 | # user.df has zip codes, but subsetting happens at the state level 54 | data(zipcode, package="zipcode", envir=environment()) 55 | # zipcode to state abbreviation 56 | self$user.df$state = merge(self$user.df, zipcode, sort=FALSE, all.x=TRUE, by.x="region", by.y="zip")$state 57 | # state abbrevoation to "region" - lowercase full state name 58 | self$user.df$state = tolower(state.name[match(self$user.df$state, state.abb)]) 59 | self$user.df = self$user.df[self$user.df$state %in% private$zoom, ] 60 | self$user.df$state = NULL 61 | 62 | self$map.df = self$map.df[self$map.df$state %in% private$zoom, ] 63 | }, 64 | 65 | bind = function() { 66 | self$choropleth.df = left_join(self$map.df, self$user.df, by="region") 67 | missing_regions = unique(self$choropleth.df[is.na(self$choropleth.df$value), ]$region) 68 | if (self$warn && length(missing_regions) > 0) 69 | { 70 | missing_regions = paste(missing_regions, collapse = ", "); 71 | warning_string = paste("The following regions were missing and are being set to NA:", missing_regions); 72 | print(warning_string); 73 | } 74 | 75 | if (self$rm_na) 76 | { 77 | self$choropleth.df = na.omit(self$choropleth.df) 78 | } 79 | }, 80 | 81 | # render the map, with AK and HI as insets 82 | render = function() 83 | { 84 | self$prepare_map() 85 | 86 | if (private$zoom == "alaska" || private$zoom == "hawaii") { 87 | choro = self$render_helper(self$choropleth.df, self$scale_name, self$theme_clean()) + ggtitle(self$title) 88 | if (self$add_state_outline) 89 | { 90 | choro + self$render_state_outline(private$zoom) 91 | } 92 | } else { 93 | # subset AK and render it 94 | alaska.df = self$choropleth.df[self$choropleth.df$state=='alaska',] 95 | alaska.ggplot = self$render_helper(alaska.df, "", self$theme_inset()) 96 | if (self$add_state_outline) 97 | { 98 | alaska.ggplot = alaska.ggplot + self$render_state_outline('alaska') 99 | } 100 | alaska.grob = ggplotGrob(alaska.ggplot) 101 | 102 | # subset HI and render it 103 | hawaii.df = self$choropleth.df[self$choropleth.df$state=='hawaii',] 104 | hawaii.ggplot = self$render_helper(hawaii.df, "", self$theme_inset()) 105 | if (self$add_state_outline) 106 | { 107 | hawaii.ggplot = hawaii.ggplot + self$render_state_outline('hawaii') 108 | } 109 | hawaii.grob = ggplotGrob(hawaii.ggplot) 110 | 111 | # remove AK and HI from the "real" df 112 | continental.df = self$choropleth.df[!self$choropleth.df$state %in% c("alaska", "hawaii"), ] 113 | continental.ggplot = self$render_helper(continental.df, self$scale_name, self$theme_clean()) + ggtitle(self$title) 114 | if (self$add_state_outline) 115 | { 116 | continental.regions = subset(private$zoom, private$zoom!="alaska" & private$zoom!="hawaii") 117 | continental.ggplot = continental.ggplot + self$render_state_outline(continental.regions) 118 | } 119 | 120 | continental.ggplot + 121 | annotation_custom(grobTree(hawaii.grob), xmin=-107.5, xmax=-102.5, ymin=25, ymax=27.5) + 122 | annotation_custom(grobTree(alaska.grob), xmin=-125, xmax=-110, ymin=22.5, ymax=30) + 123 | ggtitle(self$title) 124 | } 125 | }, 126 | 127 | render_helper = function(choropleth.df, scale_name, theme) 128 | { 129 | if (is.numeric(choropleth.df$value)) 130 | { 131 | ggplot(choropleth.df, aes(x=long, y=lat, color=value)) + 132 | geom_point() + 133 | self$get_scale() + 134 | theme; 135 | } else { # assume character or factor 136 | stopifnot(length(unique(na.omit(choropleth.df$value))) <= 9) # brewer scale only goes up to 9 137 | 138 | ggplot(choropleth.df, aes(x=long, y=lat, color=value)) + 139 | geom_point() + 140 | self$get_scale() + 141 | theme; 142 | } 143 | }, 144 | 145 | # we need to override this 146 | #' @importFrom scales comma 147 | get_scale = function() 148 | { 149 | if (!is.null(self$ggplot_scale)) 150 | { 151 | self$ggplot_scale 152 | } else if (private$buckets == 1) { 153 | 154 | min_value = min(self$choropleth.df$value, na.rm=TRUE) 155 | max_value = max(self$choropleth.df$value, na.rm=TRUE) 156 | stopifnot(!is.na(min_value) && !is.na(max_value)) 157 | 158 | # by default, scale_fill_continuous uses a light value for high values and a dark value for low values 159 | # however, this is the opposite of how choropleths are normally colored (see wikipedia) 160 | # these low and high values are from the 7 color brewer blue scale (see colorbrewer.org) 161 | scale_color_continuous(self$legend, low="#eff3ff", high="#084594", labels=comma, na.value="black", limits=c(min_value, max_value)) 162 | } else { 163 | scale_color_brewer(self$legend, drop=FALSE, labels=comma, na.value="black") 164 | } 165 | } 166 | ) 167 | ) 168 | 169 | #' Create a map visualizing US ZIP codes with sensible defaults. 170 | #' 171 | #' ZIPs are rendered as scatterplots against and outline of US States. 172 | #' 173 | #' @param df A data.frame with a column named "region" and a column named "value". Values of the 174 | #' "region" column must be valid 5-digit zip codes. 175 | #' @param title An optional title for the map. 176 | #' @param legend An optional name for the legend. 177 | #' @param buckets The number of equally sized buckets to places the values in. A value of 1 178 | #' will use a continuous scale, and a value in [2, 9] will use that many buckets. 179 | #' @param zoom An optional vector of states to zoom in on. Elements of this vector must exactly 180 | #' match the names of states as they appear in the "region" column of ?state.regions. 181 | #' 182 | #' @examples 183 | #' # demonstrate default parameters - visualization using 7 equally sized buckets 184 | #' data(df_pop_zip) 185 | #' zip_map(df_pop_zip, title="US 2012 ZCTA Population Estimates", legend="Population") 186 | #' 187 | #' # demonstrate continuous scale and zoom 188 | #' data(df_pop_zip) 189 | #' zip_map(df_pop_zip, 190 | #' title="US 2012 ZCTA Population Estimates", 191 | #' legend="Population", 192 | #' buckets=1, 193 | #' zoom=c("california", "oregon", "washington")) 194 | #' 195 | #' @note The longitude and latitude of ZIPs come from the "zipcode" package. The state outlines come 196 | #' from ?state.map. 197 | #' @export 198 | #' @importFrom Hmisc cut2 199 | #' @importFrom stringr str_extract_all 200 | #' @importFrom ggplot2 ggplot aes geom_polygon scale_fill_brewer ggtitle theme theme_grey element_blank geom_text 201 | #' @importFrom ggplot2 scale_fill_continuous scale_color_brewer geom_point 202 | #' @importFrom scales comma 203 | #' @importFrom grid unit 204 | #'@include choropleth.R 205 | zip_map = function(df, title="", legend="", buckets=7, zoom=NULL) 206 | { 207 | m = ZipMap$new(df) 208 | m$title = title 209 | m$legend = legend 210 | m$set_buckets(buckets) 211 | m$set_zoom(zoom) 212 | m$render() 213 | } 214 | -------------------------------------------------------------------------------- /R/zip_data.R: -------------------------------------------------------------------------------- 1 | #' A data.frame containing population estimates for US Zip Code Tabulated Areas (ZCTAs) in 2012. 2 | #' 3 | #' ZCTAs are intended to be roughly analogous to postal ZIP codes. 4 | #' 5 | #' @name df_pop_zip 6 | #' @docType data 7 | #' @references Taken from the US American Community Survey (ACS) 5 year estimates. 8 | #' ZCTAs, and their realationship to ZIP codes, are explained here \url{https://www.census.gov/geo/reference/zctas.html}. 9 | #' @keywords data 10 | #' @usage data(df_pop_zip) 11 | #' @examples 12 | #' data(df_pop_zip) 13 | #' zip_map(df_pop_zip, title="2012 Population Estimates") 14 | NULL 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # choroplethr 2 | Master: [![Build Status](https://travis-ci.org/trulia/choroplethr.png?branch=master)](https://travis-ci.org/trulia/choroplethr) 3 | Dev: [![Build Status](https://travis-ci.org/trulia/choroplethr.png?branch=dev)](https://travis-ci.org/trulia/choroplethr) 4 | 5 | choroplethr simplifies the creation of choropleth maps in R. Choropleths are thematic maps where geographic regions, such as states, are colored according to some metric, such as the number of people who live in that state. choroplethr simplifies this process by 6 | 7 | 1. Providing ready-made functions for creating choropleths using four different maps. 8 | 2. Providing API connections to interesting data sources for making choropleths. 9 | 3. Providing a framework for creating choropleths from arbitrary shapefiles. 10 | 11 | Please see the following pages for more details. 12 | 13 | 1. [Introduction](http://cran.r-project.org/web/packages/choroplethr/vignettes/a-introduction.html) 14 | 1. [US State Choropleths](http://cran.r-project.org/web/packages/choroplethr/vignettes/b-state-choropleth.html) 15 | 1. [US County Choropleths](http://cran.r-project.org/web/packages/choroplethr/vignettes/c-county-choropleth.html) 16 | 1. [US ZIP Maps](http://cran.r-project.org/web/packages/choroplethr/vignettes/d-zip-map.html) 17 | 1. [Country Choropleths](http://cran.r-project.org/web/packages/choroplethr/vignettes/e-country-choropleth.html) 18 | 1. [Mapping US Census Data](http://cran.r-project.org/web/packages/choroplethr/vignettes/f-mapping-us-census-data.html) 19 | 1. [Mapping World Bank WDI Data](http://cran.r-project.org/web/packages/choroplethr/vignettes/g-world-bank-data.html) 20 | 1. [Animated Choropleths](http://cran.r-project.org/web/packages/choroplethr/vignettes/h-animated-choropleths.html) 21 | 1. [Creating Your Own Maps](http://cran.r-project.org/web/packages/choroplethr/vignettes/i-creating-your-own-maps.html) 22 | 2. [Creating Administrative Level 1 Maps](http://cran.r-project.org/web/packages/choroplethr/vignettes/j-creating-admin1-maps.html) 23 | 24 | ## Installation 25 | 26 | To install the latest stable release type the following from an R console: 27 | 28 | ``` 29 | install.packages("choroplethr") 30 | ``` 31 | 32 | To install the development version use the `devtools` package: 33 | 34 | ``` 35 | # install.packages("devtools") 36 | library(devtools) 37 | install_github("choroplethr", "trulia") 38 | library(choroplethr) 39 | ``` 40 | -------------------------------------------------------------------------------- /choroplethr.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageInstallArgs: --no-multiarch --with-keep.source 17 | PackageCheckArgs: --as-cran 18 | -------------------------------------------------------------------------------- /data/.Rapp.history: -------------------------------------------------------------------------------- 1 | load("/Users/alamstein/code/R/choroplethr/data/choroplethr.rdata") 2 | -------------------------------------------------------------------------------- /data/df_japan_census.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/data/df_japan_census.rdata -------------------------------------------------------------------------------- /data/df_pop_country.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/data/df_pop_country.rdata -------------------------------------------------------------------------------- /data/df_pop_county.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/data/df_pop_county.rdata -------------------------------------------------------------------------------- /data/df_pop_state.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/data/df_pop_state.rdata -------------------------------------------------------------------------------- /data/df_pop_zip.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/data/df_pop_zip.rdata -------------------------------------------------------------------------------- /data/df_president.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/data/df_president.rdata -------------------------------------------------------------------------------- /data/df_president_ts.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/data/df_president_ts.rdata -------------------------------------------------------------------------------- /inst/tests/test-country.R: -------------------------------------------------------------------------------- 1 | context("test country_choropleth") 2 | 3 | # to avoid spurious warnings, use this df. df_pop_country is missing a few regions 4 | get_test_df = function() 5 | { 6 | data(country.regions, package="choroplethrMaps") 7 | n = nrow(country.regions) 8 | data.frame(region=country.regions$region, value=sample(n)) 9 | } 10 | 11 | test_that("default parameters returns ggplot", { 12 | df = get_test_df() 13 | expect_is(country_choropleth(df), "ggplot") 14 | }) 15 | 16 | test_that("setting title returns ggplot", { 17 | df = get_test_df() 18 | expect_is(country_choropleth(df, title="test title"), "ggplot") 19 | }) 20 | 21 | test_that("setting legend returns ggplot", { 22 | df = get_test_df() 23 | expect_is(country_choropleth(df, legend="test legend"), "ggplot") 24 | }) 25 | 26 | test_that("continuous scale returns ggplot", { 27 | df = get_test_df() 28 | expect_is(country_choropleth(df, buckets=1), "ggplot") 29 | }) 30 | 31 | test_that("west coast zoom returns ggplot", { 32 | df = get_test_df() 33 | expect_is(country_choropleth(df, buckets=2, zoom=c("united states of america", "mexico", "canada")), "ggplot") 34 | }) 35 | 36 | test_that("error on invalid zoom", { 37 | df = get_test_df() 38 | expect_error(country_choropleth(df, zoom="asdf")) 39 | }) 40 | 41 | test_that("less than full countries emits warning", { 42 | df = get_test_df() 43 | df = df[df$region != "angola", ] 44 | expect_warning(country_choropleth(df)) 45 | }) 46 | 47 | test_that("less than full countries works", { 48 | df = get_test_df() 49 | df = df[df$region != "angola", ] 50 | expect_is(suppressWarnings(country_choropleth(df)), "ggplot") 51 | }) 52 | 53 | ##### 54 | test_that("regions not on map emit warning", { 55 | df = get_test_df() 56 | df = rbind(df, data.frame(region="asdf", value=1)) 57 | expect_warning(country_choropleth(df)) 58 | }) 59 | 60 | test_that("duplicate regions emit error", { 61 | df = get_test_df() 62 | df = rbind(df, data.frame(region="angola", value=1)) 63 | expect_error(country_choropleth(df)) 64 | }) 65 | 66 | -------------------------------------------------------------------------------- /inst/tests/test-county.R: -------------------------------------------------------------------------------- 1 | context("test county_choropleth") 2 | 3 | test_that("default parameters returns ggplot", { 4 | data(df_pop_county) 5 | expect_is(county_choropleth(df_pop_county), "ggplot") 6 | }) 7 | 8 | test_that("setting title returns ggplot", { 9 | data(df_pop_county) 10 | expect_is(county_choropleth(df_pop_county, title="test title"), "ggplot") 11 | }) 12 | 13 | test_that("setting legend returns ggplot", { 14 | data(df_pop_county) 15 | expect_is(county_choropleth(df_pop_county, legend="test legend"), "ggplot") 16 | }) 17 | 18 | test_that("continuous scale returns ggplot", { 19 | data(df_pop_county) 20 | expect_is(county_choropleth(df_pop_county, buckets=1), "ggplot") 21 | }) 22 | 23 | test_that("west coast zoom returns ggplot", { 24 | data(df_pop_county) 25 | expect_is(county_choropleth(df_pop_county, zoom=c("california", "oregon", "washington")), "ggplot") 26 | }) 27 | 28 | test_that("error on invalid zoom", { 29 | data(df_pop_county) 30 | expect_error(county_choropleth(df_pop_county, zoom="asdf")) 31 | }) 32 | 33 | test_that("less than full counties emits warning", { 34 | data(df_pop_county) 35 | df = df_pop_county[df_pop_county$region <= 10000, ] 36 | expect_warning(county_choropleth(df)) 37 | }) 38 | 39 | test_that("less than full states works", { 40 | data(df_pop_county) 41 | df = df_pop_county[df_pop_county$region <= 10000, ] 42 | expect_is(suppressWarnings(county_choropleth(df)), "ggplot") 43 | }) 44 | 45 | -------------------------------------------------------------------------------- /inst/tests/test-num_buckets.R: -------------------------------------------------------------------------------- 1 | context("test buckets") 2 | 3 | test_that("state buckets = 0 throws exception", { 4 | data(df_pop_state, package="choroplethr") 5 | expect_error(state_choropleth(df_pop_state, buckets=0)) 6 | }) 7 | 8 | test_that("state buckets = 10 throws exception", { 9 | data(df_pop_state, package="choroplethr") 10 | expect_error(state_choropleth(df_pop_state, buckets=10)) 11 | }) 12 | 13 | test_that("county float buckets throws exception", { 14 | data(df_pop_state, package="choroplethr") 15 | expect_error(state_choropleth(df_pop_state, buckets=1.5)) 16 | }) 17 | 18 | test_that("zip string buckets throws exception", { 19 | data(df_pop_state, package="choroplethr") 20 | expect_error(state_choropleth(df_pop_state, buckets="hello")) 21 | }) 22 | 23 | test_that("country buckets=1 returns ggplot", { 24 | data(df_pop_state, package="choroplethr") 25 | expect_is(state_choropleth(df_pop_state, buckets=1), "ggplot") 26 | }) 27 | 28 | test_that("county buckets=5 returns ggplot", { 29 | data(df_pop_state, package="choroplethr") 30 | expect_is(state_choropleth(df_pop_state, buckets=1), "ggplot") 31 | }) 32 | -------------------------------------------------------------------------------- /inst/tests/test-state.R: -------------------------------------------------------------------------------- 1 | context("test state_choropleth") 2 | 3 | test_that("default parameters returns ggplot", { 4 | data(df_pop_state) 5 | expect_is(state_choropleth(df_pop_state), "ggplot") 6 | }) 7 | 8 | test_that("setting title returns ggplot", { 9 | data(df_pop_state) 10 | expect_is(state_choropleth(df_pop_state, title="test title"), "ggplot") 11 | }) 12 | 13 | test_that("setting legend returns ggplot", { 14 | data(df_pop_state) 15 | expect_is(state_choropleth(df_pop_state, legend="test legend"), "ggplot") 16 | }) 17 | 18 | test_that("continuous scale returns ggplot", { 19 | data(df_pop_state) 20 | expect_is(state_choropleth(df_pop_state, buckets=1), "ggplot") 21 | }) 22 | 23 | test_that("west coast zoom returns ggplot", { 24 | data(df_pop_state) 25 | expect_is(state_choropleth(df_pop_state, zoom=c("california", "oregon", "washington"), buckets=1), "ggplot") 26 | }) 27 | 28 | test_that("error on invalid zoom", { 29 | data(df_pop_state) 30 | expect_error(state_choropleth(df_pop_state, zoom="asdf")) 31 | }) 32 | 33 | test_that("less than full states emits warning", { 34 | data(df_pop_state) 35 | df = df_pop_state[df_pop_state$region != "new york", ] 36 | expect_warning(state_choropleth(df)) 37 | }) 38 | 39 | test_that("less than full states works", { 40 | data(df_pop_state) 41 | df = df_pop_state[df_pop_state$region != "new york", ] 42 | expect_is( 43 | suppressWarnings(state_choropleth(df)), 44 | "ggplot") 45 | }) 46 | 47 | test_that("any duplicate regions trigger an error", { 48 | data(df_pop_state) 49 | df = rbind(df_pop_state, data.frame(region = "new york", value=1)) 50 | expect_error(state_choropleth(df)) 51 | }) 52 | -------------------------------------------------------------------------------- /inst/tests/test-zip.R: -------------------------------------------------------------------------------- 1 | context("test zip_map") 2 | 3 | test_that("default parameters returns ggplot", { 4 | data(df_pop_zip, package="choroplethr") 5 | expect_is(zip_map(df_pop_zip), "ggplot") 6 | }) 7 | 8 | test_that("setting title returns ggplot", { 9 | data(df_pop_zip, package="choroplethr") 10 | expect_is(zip_map(df_pop_zip, title="test title"), "ggplot") 11 | }) 12 | 13 | test_that("setting legend returns ggplot", { 14 | data(df_pop_zip, package="choroplethr") 15 | expect_is(zip_map(df_pop_zip, legend="test legend"), "ggplot") 16 | }) 17 | 18 | test_that("continuous scale returns ggplot", { 19 | data(df_pop_zip, package="choroplethr") 20 | expect_is(zip_map(df_pop_zip, buckets=1), "ggplot") 21 | }) 22 | 23 | test_that("west coast zoom returns ggplot", { 24 | data(df_pop_zip, package="choroplethr") 25 | expect_is(zip_map(df_pop_zip, zoom=c("california", "oregon", "washington")), "ggplot") 26 | }) 27 | 28 | test_that("error on invalid zoom", { 29 | data(df_pop_zip, package="choroplethr") 30 | expect_error(zip_map(df_pop_zip, zoom="asdf")) 31 | }) 32 | 33 | 34 | -------------------------------------------------------------------------------- /man/Admin1Choropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{Admin1Choropleth} 4 | \alias{Admin1Choropleth} 5 | \title{An R6 object for creating Administration Level 1 choropleths.} 6 | \format{\preformatted{Class 'R6ClassGenerator' 7 | - attr(*, "name")= chr "Admin1Choropleth_generator" 8 | }} 9 | \usage{ 10 | Admin1Choropleth 11 | } 12 | \description{ 13 | An R6 object for creating Administration Level 1 choropleths. 14 | } 15 | \keyword{datasets} 16 | 17 | -------------------------------------------------------------------------------- /man/CountryChoropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{CountryChoropleth} 4 | \alias{CountryChoropleth} 5 | \title{An R6 object for creating country-level choropleths.} 6 | \format{\preformatted{Class 'R6ClassGenerator' 7 | - attr(*, "name")= chr "CountryChoropleth_generator" 8 | }} 9 | \usage{ 10 | CountryChoropleth 11 | } 12 | \description{ 13 | An R6 object for creating country-level choropleths. 14 | } 15 | \keyword{datasets} 16 | 17 | -------------------------------------------------------------------------------- /man/CountyChoropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{CountyChoropleth} 4 | \alias{CountyChoropleth} 5 | \title{Create a county-level choropleth} 6 | \format{\preformatted{Class 'R6ClassGenerator' 7 | - attr(*, "name")= chr "CountyChoropleth_generator" 8 | }} 9 | \usage{ 10 | CountyChoropleth 11 | } 12 | \description{ 13 | Create a county-level choropleth 14 | } 15 | \keyword{datasets} 16 | 17 | -------------------------------------------------------------------------------- /man/CountyZoomChoropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{CountyZoomChoropleth} 4 | \alias{CountyZoomChoropleth} 5 | \title{Create a county-level choropleth that zooms on counties, not states.} 6 | \format{\preformatted{Class 'R6ClassGenerator' 7 | - attr(*, "name")= chr "CountyZoomChoropleth_generator" 8 | }} 9 | \usage{ 10 | CountyZoomChoropleth 11 | } 12 | \description{ 13 | Create a county-level choropleth that zooms on counties, not states. 14 | } 15 | \keyword{datasets} 16 | 17 | -------------------------------------------------------------------------------- /man/StateChoropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{StateChoropleth} 4 | \alias{StateChoropleth} 5 | \title{Create a state-level choropleth} 6 | \format{\preformatted{Class 'R6ClassGenerator' 7 | - attr(*, "name")= chr "StateChoropleth_generator" 8 | }} 9 | \usage{ 10 | StateChoropleth 11 | } 12 | \description{ 13 | Create a state-level choropleth 14 | } 15 | \keyword{datasets} 16 | 17 | -------------------------------------------------------------------------------- /man/USAChoropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{USAChoropleth} 4 | \alias{USAChoropleth} 5 | \title{Normal choropleth that draws Alaska and Hawaii as insets. 6 | In addition to a columns named "region" and "value", also requires a column named "state".} 7 | \format{\preformatted{Class 'R6ClassGenerator' 8 | - attr(*, "name")= chr "USAChoropleth_generator" 9 | }} 10 | \usage{ 11 | USAChoropleth 12 | } 13 | \description{ 14 | Normal choropleth that draws Alaska and Hawaii as insets. 15 | In addition to a columns named "region" and "value", also requires a column named "state". 16 | } 17 | \keyword{datasets} 18 | 19 | -------------------------------------------------------------------------------- /man/ZipMap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{ZipMap} 4 | \alias{ZipMap} 5 | \title{Create a county-level choropleth} 6 | \format{\preformatted{Class 'R6ClassGenerator' 7 | - attr(*, "name")= chr "CountyChoropleth_generator" 8 | }} 9 | \usage{ 10 | ZipMap 11 | } 12 | \description{ 13 | Create a county-level choropleth 14 | } 15 | \keyword{datasets} 16 | 17 | -------------------------------------------------------------------------------- /man/admin1_choropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{admin1_choropleth} 3 | \alias{admin1_choropleth} 4 | \title{Create an admin1-level choropleth for a specified country} 5 | \usage{ 6 | admin1_choropleth(country.name, df, title = "", legend = "", buckets = 7, 7 | zoom = NULL) 8 | } 9 | \arguments{ 10 | \item{country.name}{The name of the country. Must exactly match how the country is named in the "country" 11 | column of ?admin1.regions in the choroplethrAdmin1 package.} 12 | 13 | \item{df}{A data.frame with a column named "region" and a column named "value". Elements in 14 | the "region" column must exactly match how regions are named in the "region" column in ?admin1.regions 15 | in the choroplethrAdmin1 package} 16 | 17 | \item{title}{An optional title for the map.} 18 | 19 | \item{legend}{An optional name for the legend.} 20 | 21 | \item{buckets}{The number of equally sized buckets to places the values in. A value of 1 22 | will use a continuous scale, and a value in [2, 9] will use that many buckets.} 23 | 24 | \item{zoom}{An optional vector of regions to zoom in on. Elements of this vector must exactly 25 | match the names of regions as they appear in the "region" column of ?admin1.regions.} 26 | } 27 | \description{ 28 | The map used comes from ?admin1.map in the choroplethrAdmin1 package. See ?get_admin_countries 29 | and ?get_admin_regions in the choroplethrAdmin1 package for help with the spelling of regions. 30 | } 31 | \examples{ 32 | \dontrun{ 33 | 34 | data(df_japan_census) 35 | head(df_japan_census) 36 | # set the value we want to map to be the 2010 population estimates 37 | df_japan_census$value=df_japan_census$pop_2010 38 | 39 | # default map of all of japan 40 | admin1_choropleth("japan", 41 | df_japan_census, 42 | "2010 Japan Population Estimates", 43 | "Population") 44 | 45 | # zoom in on the Kansai region and use a continuous scale 46 | kansai = c("mie", "nara", "wakayama", "kyoto", "osaka", "hyogo", "shiga") 47 | admin1_choropleth("japan", 48 | df_japan_census, 49 | "2010 Japan Population Estimates", 50 | "Population", 51 | 1, 52 | kansai) 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /man/choroplethr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{choroplethr} 3 | \alias{choroplethr} 4 | \title{Create a choropleth} 5 | \usage{ 6 | choroplethr(...) 7 | } 8 | \arguments{ 9 | \item{...}{All arguments are ignored.} 10 | } 11 | \description{ 12 | This function is deprecated as of choroplether version 2.0.0. Please use ?state_choropleth, 13 | ?county_choropleth, ?zip_map and ?country_choroplethr instead. The last version of choroplethr 14 | in which this function worked was version 1.7.0, which can be downloaded from CRAN 15 | here: http://cran.r-project.org/web/packages/choroplethr/index.html")) 16 | } 17 | 18 | -------------------------------------------------------------------------------- /man/choroplethr_acs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{choroplethr_acs} 3 | \alias{choroplethr_acs} 4 | \title{Create a choropleth from ACS data.} 5 | \usage{ 6 | choroplethr_acs(tableId, map, endyear = 2011, span = 5, buckets = 7, 7 | zoom = NULL) 8 | } 9 | \arguments{ 10 | \item{tableId}{The id of an ACS table} 11 | 12 | \item{map}{A string indicating which map the data is for. Must be "state", "county" or "zip".} 13 | 14 | \item{endyear}{The end year of the survey to use. See acs.fetch (?acs.fetch) and http://1.usa.gov/1geFSSj for details.} 15 | 16 | \item{span}{The span of time to use. See acs.fetch and http://1.usa.gov/1geFSSj for details. 17 | on the same longitude and latitude map to scale. This variable is only checked when the "states" variable is equal to all 50 states.} 18 | 19 | \item{buckets}{The number of equally sized buckets to places the values in. A value of 1 20 | will use a continuous scale, and a value in [2, 9] will use that many buckets.} 21 | 22 | \item{zoom}{An optional list of states to zoom in on. Must come from the "name" column in 23 | ?state.regions.} 24 | } 25 | \value{ 26 | A choropleth. 27 | } 28 | \description{ 29 | Creates a choropleth using the US Census' American Community Survey (ACS) data. 30 | Requires the acs package to be installed, and a Census API Key to be set with 31 | the acs's api.key.install function. Census API keys can be obtained at http://www.census.gov/developers/tos/key_request.html. 32 | } 33 | \examples{ 34 | \dontrun{ 35 | # population of all states, 9 equally sized buckets 36 | choroplethr_acs("B01003", "state") 37 | 38 | # median income, continuous scale, counties in New York, New Jersey and Connecticut 39 | choroplethr_acs("B19301", "county", buckets=1, zoom=c("new york", "new jersey", "connecticut")) 40 | 41 | # median income, all zip codes 42 | choroplethr_acs("B19301", "zip") } 43 | } 44 | \references{ 45 | Uses the acs package created by Ezra Haber Glenn. 46 | } 47 | \seealso{ 48 | \code{api.key.install} in the acs package which sets an Census API key for the acs library 49 | 50 | http://factfinder2.census.gov/faces/help/jsf/pages/metadata.xhtml?lang=en&type=survey&id=survey.en.ACS_ACS 51 | which contains a list of all ACS surveys. 52 | } 53 | \keyword{acs} 54 | \keyword{choropleth,} 55 | 56 | -------------------------------------------------------------------------------- /man/choroplethr_animate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{choroplethr_animate} 3 | \alias{choroplethr_animate} 4 | \title{Animate a list of chropleths} 5 | \usage{ 6 | choroplethr_animate(choropleths) 7 | } 8 | \arguments{ 9 | \item{choropleths}{A list of choropleths represented as ggplot2 objects.} 10 | } 11 | \value{ 12 | Nothing. However, a variable number of files are written to the current working directory. 13 | } 14 | \description{ 15 | Given a list of choropleths, represented as ggplot2 objects 16 | \enumerate{ 17 | \item Save the individual images to the working directory with the naming convention "choropleth_1.png", "choropleth_2.png", etc. 18 | \item Write a file called "animated_choropleth.html" which contains a viewer which animates them. 19 | } 20 | } 21 | \examples{ 22 | \dontrun{ 23 | data(df_president_ts) 24 | ?df_president_ts # time series of all US presidential elections 1789-2012 25 | 26 | # create a list of choropleths of presidential election results for each year 27 | choropleths = list() 28 | for (i in 2:(ncol(df_president_ts))) { 29 | df = df_president_ts[, c(1, i)] 30 | colnames(df) = c("region", "value") 31 | title = paste0("Presidential Election Results: ", colnames(df_president_ts)[i]) 32 | choropleths[[i-1]] = state_choropleth(df, title=title) 33 | } 34 | 35 | # set working directory and animate 36 | setwd("~/Desktop") 37 | choroplethr_animate(choropleths) 38 | } 39 | } 40 | \author{ 41 | Ari Lamstein (R code) and Brian Johnson (JavaScript, HTML and CSS code) 42 | } 43 | \keyword{animation} 44 | \keyword{choropleth} 45 | 46 | -------------------------------------------------------------------------------- /man/choroplethr_wdi.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{choroplethr_wdi} 3 | \alias{choroplethr_wdi} 4 | \title{Create a country-level choropleth using data from the World Bank's World Development Indicators (WDI).} 5 | \usage{ 6 | choroplethr_wdi(code = "SP.POP.TOTL", year = 2012, title = "", 7 | buckets = 7, zoom = NULL) 8 | } 9 | \arguments{ 10 | \item{code}{The WDI code to use.} 11 | 12 | \item{year}{The year of data to use.} 13 | 14 | \item{title}{A title for the map. If not specified, automatically generated to include WDI code and year.} 15 | 16 | \item{buckets}{The number of equally sized buckets to places the values in. A value of 1 17 | will use a continuous scale, and a value in [2, 9] will use that many buckets.} 18 | 19 | \item{zoom}{An optional list of countries to zoom in on. Must come from the "name" column in 20 | ?country.regions.} 21 | } 22 | \value{ 23 | A choropleth. 24 | } 25 | \description{ 26 | Create a country-level choropleth using data from the World Bank's World Development Indicators (WDI). 27 | } 28 | \examples{ 29 | \dontrun{ 30 | # See http://data.worldbank.org/indicator/SP.POP.TOTL 31 | choroplethr_wdi(code="SP.POP.TOTL", year=2012, title="2012 Population Estimates", buckets=1) 32 | 33 | # See http://data.worldbank.org/indicator/SP.DYN.LE00.IN 34 | choroplethr_wdi(code="SP.DYN.LE00.IN", year=2012, title="2012 Life Expectancy Estimates") 35 | 36 | # See http://data.worldbank.org/indicator/NY.GDP.PCAP.CD 37 | choroplethr_wdi(code="NY.GDP.PCAP.CD", year=2012, title="2012 Per Capita Income") 38 | } 39 | } 40 | \references{ 41 | Uses the WDI function from the WDI package by Vincent Arel-Bundock. 42 | } 43 | 44 | -------------------------------------------------------------------------------- /man/country_choropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{country_choropleth} 3 | \alias{country_choropleth} 4 | \title{Create a country-level choropleth} 5 | \usage{ 6 | country_choropleth(df, title = "", legend = "", buckets = 7, 7 | zoom = NULL) 8 | } 9 | \arguments{ 10 | \item{df}{A data.frame with a column named "region" and a column named "value". Elements in 11 | the "region" column must exactly match how regions are named in the "region" column in ?country.map.} 12 | 13 | \item{title}{An optional title for the map.} 14 | 15 | \item{legend}{An optional name for the legend.} 16 | 17 | \item{buckets}{The number of equally sized buckets to places the values in. A value of 1 18 | will use a continuous scale, and a value in [2, 9] will use that many buckets.} 19 | 20 | \item{zoom}{An optional vector of countries to zoom in on. Elements of this vector must exactly 21 | match the names of countries as they appear in the "region" column of ?country.regions} 22 | } 23 | \description{ 24 | The map used is country.map in the choroplethrMaps package. See country.regions for 25 | an object which can help you coerce your regions into the required format. 26 | } 27 | \examples{ 28 | # demonstrate default options 29 | data(df_pop_country) 30 | country_choropleth(df_pop_country, "2012 World Bank Populate Estimates") 31 | 32 | # demonstrate continuous scale 33 | country_choropleth(df_pop_country, "2012 World Bank Populate Estimates", buckets=1) 34 | 35 | # demonstrate zooming 36 | country_choropleth(df_pop_country, 37 | "2012 World Bank Population Estimates", 38 | buckets=1, 39 | zoom=c("united states of america", "canada", "mexico")) 40 | } 41 | 42 | -------------------------------------------------------------------------------- /man/county_choropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{county_choropleth} 3 | \alias{county_choropleth} 4 | \title{Create a choropleth of USA Counties with sensible defaults.} 5 | \usage{ 6 | county_choropleth(df, title = "", legend = "", buckets = 7, zoom = NULL) 7 | } 8 | \arguments{ 9 | \item{df}{A data.frame with a column named "region" and a column named "value". Elements in 10 | the "region" column must exactly match how regions are named in the "region" column in county.map.} 11 | 12 | \item{title}{An optional title for the map.} 13 | 14 | \item{legend}{An optional name for the legend.} 15 | 16 | \item{buckets}{The number of equally sized buckets to places the values in. A value of 1 17 | will use a continuous scale, and a value in [2, 9] will use that many buckets.} 18 | 19 | \item{zoom}{An optional vector of states to zoom in on. Elements of this vector must exactly 20 | match the names of states as they appear in the "region" column of ?state.regions.} 21 | } 22 | \description{ 23 | The map used is county.map in the choroplethrMaps package. See country.regions 24 | in the choroplethrMaps package for an object which can help you coerce your regions 25 | into the required format. 26 | } 27 | \examples{ 28 | \dontrun{ 29 | # demonstrate default parameters - visualization using 7 equally sized buckets 30 | data(df_pop_county) 31 | county_choropleth(df_pop_county, title="US 2012 County Population Estimates", legend="Population") 32 | 33 | #' # demonstrate continuous scale and zoom 34 | data(df_pop_county) 35 | county_choropleth(df_pop_county, 36 | title="US 2012 County Population Estimates", 37 | legend="Population", 38 | buckets=1, 39 | zoom=c("california", "oregon", "washington")) 40 | 41 | # demonstrate how choroplethr handles character and factor values 42 | # demonstrate user creating their own discretization of the input 43 | data(df_pop_county) 44 | df_pop_county$str = "" 45 | for (i in 1:nrow(df_pop_county)) 46 | { 47 | if (df_pop_county[i,"value"] < 1000000) 48 | { 49 | df_pop_county[i,"str"] = "< 1M" 50 | } else { 51 | df_pop_county[i,"str"] = "> 1M" 52 | } 53 | } 54 | df_pop_county$value = df_pop_county$str 55 | county_choropleth(df_pop_county, title="Which counties have more than 1M people?") 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /man/county_zoom_choropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{county_zoom_choropleth} 3 | \alias{county_zoom_choropleth} 4 | \title{Create a choropleth of USA Counties, with sensible defaults, that zooms on counties.} 5 | \usage{ 6 | county_zoom_choropleth(df, title = "", legend = "", buckets = 7, 7 | zoom = NULL) 8 | } 9 | \arguments{ 10 | \item{df}{A data.frame with a column named "region" and a column named "value". Elements in 11 | the "region" column must exactly match how regions are named in the "region" column in county.map.} 12 | 13 | \item{title}{An optional title for the map.} 14 | 15 | \item{legend}{An optional name for the legend. Ignored if zooming in on a single county.} 16 | 17 | \item{buckets}{The number of equally sized buckets to places the values in. A value of 1 18 | will use a continuous scale, and a value in [2, 9] will use that many buckets. Ignored if 19 | zooming in on a single county.} 20 | 21 | \item{zoom}{An optional vector of counties to zoom in on. Elements of this vector must exactly 22 | match the names of counties as they appear in the "region" column of ?county.regions.} 23 | } 24 | \description{ 25 | The map used is county.map in the choroplethrMaps package. See country.regions 26 | in the choroplethrMaps package for an object which can help you coerce your regions 27 | into the required format. If you zoom in on a single county, only an outline of the 28 | county is shown. 29 | } 30 | \examples{ 31 | \dontrun{ 32 | 33 | library(choroplethrMaps) 34 | data(county.regions) 35 | 36 | library(dplyr) 37 | 38 | # show the population of the 5 counties (boroughs) that make up New York City 39 | nyc_county_names=c("kings", "bronx", "new york", "queens", "richmond") 40 | nyc_county_fips = county.regions \%>\% 41 | filter(state.name=="new york" & county.name \%in\% nyc_county_names) \%>\% 42 | select(region) 43 | county_zoom_choropleth(df_pop_county, 44 | title="Population of Counties in New York City", 45 | legend="Population", 46 | buckets=1, 47 | zoom=nyc_county_fips$region) 48 | 49 | # zooming in on a single county shows just an outline. 50 | county_zoom_choropleth(df_pop_county, 51 | title="Zoom of Manhattan", 52 | zoom=36061) # manhattan 53 | 54 | # population of the 9 counties in the san francisco bay area 55 | bay_area_county_names = c("alameda", "contra costa", "marin", "napa", "san francisco", 56 | "san mateo", "santa clara", "solano", "sonoma") 57 | bay_area_county_fips = county.regions \%>\% 58 | filter(state.name=="california" & county.name \%in\% bay_area_county_names) \%>\% 59 | select(region) 60 | county_zoom_choropleth(df_pop_county, 61 | title="Population of Counties in the San Francisco Bay Area", 62 | legend="Population", 63 | buckets=1, 64 | zoom=bay_area_county_fips$region) 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /man/df_japan_census.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{df_japan_census} 4 | \alias{df_japan_census} 5 | \title{A data.frame containing basic demographic information about Japan.} 6 | \usage{ 7 | data(df_japan_census) 8 | } 9 | \description{ 10 | A data.frame containing basic demographic information about Japan. 11 | } 12 | \references{ 13 | Taken from the "Total Population" table from the Statistics Bureau of Japan website 14 | (\url{http://www.stat.go.jp/english/data/nenkan/1431-02.htm}) on 12/1/2014. 15 | } 16 | \keyword{data} 17 | 18 | -------------------------------------------------------------------------------- /man/df_pop_country.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{df_pop_country} 4 | \alias{df_pop_country} 5 | \title{A data.frame containing population estimates for Countries in 2012.} 6 | \usage{ 7 | data(df_pop_country) 8 | } 9 | \description{ 10 | A data.frame containing population estimates for Countries in 2012. 11 | } 12 | \references{ 13 | Taken from the WDI package with code SP.POP.TOTL for year 2012. 14 | } 15 | \keyword{data} 16 | 17 | -------------------------------------------------------------------------------- /man/df_pop_county.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{df_pop_county} 4 | \alias{df_pop_county} 5 | \title{A data.frame containing population estimates for US Counties in 2012.} 6 | \usage{ 7 | data(df_pop_county) 8 | } 9 | \description{ 10 | A data.frame containing population estimates for US Counties in 2012. 11 | } 12 | \references{ 13 | Taken from the US American Community Survey (ACS) 5 year estimates. 14 | } 15 | \keyword{data} 16 | 17 | -------------------------------------------------------------------------------- /man/df_pop_state.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{df_pop_state} 4 | \alias{df_pop_state} 5 | \title{A data.frame containing population estimates for US States in 2012.} 6 | \usage{ 7 | data(df_pop_state) 8 | } 9 | \description{ 10 | A data.frame containing population estimates for US States in 2012. 11 | } 12 | \references{ 13 | Taken from the US American Community Survey (ACS) 5 year estimates. 14 | } 15 | \keyword{data} 16 | 17 | -------------------------------------------------------------------------------- /man/df_pop_zip.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{df_pop_zip} 4 | \alias{df_pop_zip} 5 | \title{A data.frame containing population estimates for US Zip Code Tabulated Areas (ZCTAs) in 2012.} 6 | \usage{ 7 | data(df_pop_zip) 8 | } 9 | \description{ 10 | ZCTAs are intended to be roughly analogous to postal ZIP codes. 11 | } 12 | \examples{ 13 | data(df_pop_zip) 14 | zip_map(df_pop_zip, title="2012 Population Estimates") 15 | } 16 | \references{ 17 | Taken from the US American Community Survey (ACS) 5 year estimates. 18 | ZCTAs, and their realationship to ZIP codes, are explained here \url{https://www.census.gov/geo/reference/zctas.html}. 19 | } 20 | \keyword{data} 21 | 22 | -------------------------------------------------------------------------------- /man/df_president.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{df_president} 4 | \alias{df_president} 5 | \title{A data.frame containing election results from the 2012 US Presidential election.} 6 | \usage{ 7 | data(df_president) 8 | } 9 | \description{ 10 | A data.frame containing election results from the 2012 US Presidential election. 11 | } 12 | \author{ 13 | Ari Lamstein and Richard Careaga 14 | } 15 | \references{ 16 | Taken from the FEC website on 11/21/2014. 17 | } 18 | \keyword{data} 19 | 20 | -------------------------------------------------------------------------------- /man/df_president_ts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \docType{data} 3 | \name{df_president_ts} 4 | \alias{df_president_ts} 5 | \title{A data.frame containing all US presdiential election results from 1789 to 2012} 6 | \usage{ 7 | data(df_president_ts) 8 | } 9 | \description{ 10 | Legend: 11 | \itemize{ 12 | \item R = Republican 13 | \item D = Democratic 14 | \item DR = Democratic-Republican 15 | \item W = Whig 16 | \item F = Federalist 17 | \item GW = George Washington 18 | \item NR = National Republican 19 | \item SD = Southern Democrat 20 | \item PR = Progressive 21 | \item AI = American Independent 22 | \item SR = States' Rights 23 | \item PO = Populist 24 | \item CU = Constitutional Union 25 | \item I = Independent 26 | \item ND = Northern Democrat 27 | \item KN = Know Nothing 28 | \item AM = Anti-Masonic 29 | \item N = Nullifier 30 | \item SP = Split evenly 31 | } 32 | } 33 | \references{ 34 | Taken from \url{http://en.wikipedia.org/wiki/List_of_United_States_presidential_election_results_by_state} 3/20/2014. 35 | } 36 | \keyword{data} 37 | 38 | -------------------------------------------------------------------------------- /man/get_acs_df.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{get_acs_df} 3 | \alias{get_acs_df} 4 | \title{Returns a data.frame representing American Community Survey estimates.} 5 | \usage{ 6 | get_acs_df(tableId, map, endyear = 2012, span = 5, column_idx = -1) 7 | } 8 | \arguments{ 9 | \item{tableId}{The id of an ACS table.} 10 | 11 | \item{map}{The map you want the data to match. Must be one of "state", "county" or "zip".} 12 | 13 | \item{endyear}{The end year of the survey. Defaults to 2012.} 14 | 15 | \item{span}{The span of the survey. Defaults to 5.} 16 | 17 | \item{column_idx}{An optional column index to specify.} 18 | } 19 | \value{ 20 | A data.frame. 21 | } 22 | \description{ 23 | Requires the acs package to be installed, and a Census API Key to be set with the 24 | acs's api.key.install function. Census API keys can be obtained at http://www.census.gov/developers/tos/key_request.html. 25 | } 26 | \examples{ 27 | \dontrun{ 28 | library(Hmisc) # for cut2 29 | # States with greater than 1M residents 30 | df = get_acs_df("B01003", "state") # population 31 | df$value = cut2(df$value, cuts=c(0,1000000,Inf)) 32 | state_choropleth(df, title="States with a population over 1M", legend="Population") 33 | 34 | # Counties with greater than or greater than 1M residents 35 | df = get_acs_df("B01003", "county") # population 36 | df$value = cut2(df$value, cuts=c(0,1000000,Inf)) 37 | county_choropleth(df, title="Counties with a population over 1M", legend="Population") 38 | 39 | # ZIP codes in California where median age is between 20 and 30 40 | df = get_acs_df("B01002", "zip") # median age 41 | df = df[df$value >= 20 & df$value <= 30, ] 42 | df$value = cut2(df$value, g=3) # 3 equally-sized groups 43 | zip_map(df, title="CA Zip Codes by Age", legend="Median Age", zoom="california") 44 | } 45 | } 46 | \seealso{ 47 | http://factfinder2.census.gov/faces/help/jsf/pages/metadata.xhtml?lang=en&type=survey&id=survey.en.ACS_ACS, which lists all ACS Surveys. 48 | } 49 | 50 | -------------------------------------------------------------------------------- /man/state_choropleth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{state_choropleth} 3 | \alias{state_choropleth} 4 | \title{Create a choropleth of US States with sensible defaults.} 5 | \usage{ 6 | state_choropleth(df, title = "", legend = "", buckets = 7, zoom = NULL) 7 | } 8 | \arguments{ 9 | \item{df}{A data.frame with a column named "region" and a column named "value". Elements in 10 | the "region" column must exactly match how regions are named in the "region" column in state.map.} 11 | 12 | \item{title}{An optional title for the map.} 13 | 14 | \item{legend}{An optional name for the legend.} 15 | 16 | \item{buckets}{The number of equally sized buckets to places the values in. A value of 1 17 | will use a continuous scale, and a value in [2, 9] will use that many buckets.} 18 | 19 | \item{zoom}{An optional vector of states to zoom in on. Elements of this vector must exactly 20 | match the names of states as they appear in the "region" column of ?state.regions.} 21 | } 22 | \description{ 23 | The map used is state.map in the package choroplethrMaps. See state.regions in 24 | the choroplethrMaps package for a data.frame that can help you coerce your regions 25 | into the required format. 26 | } 27 | \examples{ 28 | # demonstrate default parameters - visualization using 7 equally sized buckets 29 | data(df_pop_state) 30 | state_choropleth(df_pop_state, title="US 2012 State Population Estimates", legend="Population") 31 | 32 | # demonstrate continuous scale and zoom 33 | data(df_pop_state) 34 | state_choropleth(df_pop_state, 35 | title="US 2012 State Population Estimates", 36 | legend="Population", 37 | buckets=1, 38 | zoom=c("california", "oregon", "washington")) 39 | 40 | # demonstrate how choroplethr handles character and factor values 41 | # demonstrate user creating their own discretization of the input 42 | data(df_pop_state) 43 | df_pop_state$str = "" 44 | for (i in 1:nrow(df_pop_state)) 45 | { 46 | if (df_pop_state[i,"value"] < 1000000) 47 | { 48 | df_pop_state[i,"str"] = "< 1M" 49 | } else { 50 | df_pop_state[i,"str"] = "> 1M" 51 | } 52 | } 53 | df_pop_state$value = df_pop_state$str 54 | state_choropleth(df_pop_state, title="Which states have less than 1M people?") 55 | } 56 | 57 | -------------------------------------------------------------------------------- /man/zip_map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.0.2): do not edit by hand 2 | \name{zip_map} 3 | \alias{zip_map} 4 | \title{Create a map visualizing US ZIP codes with sensible defaults.} 5 | \usage{ 6 | zip_map(df, title = "", legend = "", buckets = 7, zoom = NULL) 7 | } 8 | \arguments{ 9 | \item{df}{A data.frame with a column named "region" and a column named "value". Values of the 10 | "region" column must be valid 5-digit zip codes.} 11 | 12 | \item{title}{An optional title for the map.} 13 | 14 | \item{legend}{An optional name for the legend.} 15 | 16 | \item{buckets}{The number of equally sized buckets to places the values in. A value of 1 17 | will use a continuous scale, and a value in [2, 9] will use that many buckets.} 18 | 19 | \item{zoom}{An optional vector of states to zoom in on. Elements of this vector must exactly 20 | match the names of states as they appear in the "region" column of ?state.regions.} 21 | } 22 | \description{ 23 | ZIPs are rendered as scatterplots against and outline of US States. 24 | } 25 | \note{ 26 | The longitude and latitude of ZIPs come from the "zipcode" package. The state outlines come 27 | from ?state.map. 28 | } 29 | \examples{ 30 | # demonstrate default parameters - visualization using 7 equally sized buckets 31 | data(df_pop_zip) 32 | zip_map(df_pop_zip, title="US 2012 ZCTA Population Estimates", legend="Population") 33 | 34 | # demonstrate continuous scale and zoom 35 | data(df_pop_zip) 36 | zip_map(df_pop_zip, 37 | title="US 2012 ZCTA Population Estimates", 38 | legend="Population", 39 | buckets=1, 40 | zoom=c("california", "oregon", "washington")) 41 | } 42 | 43 | -------------------------------------------------------------------------------- /tests/test-all.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(choroplethr) 3 | 4 | test_package("choroplethr") 5 | -------------------------------------------------------------------------------- /vignettes/a-introduction.Rmd: -------------------------------------------------------------------------------- 1 | 5 | 6 | Introduction 7 | ======================================================== 8 | 9 | ### What is a Choropleth? 10 | 11 | A choropleth is a map which 12 | 13 | 1. Shows geographic boundaries. 14 | 2. Colors those regions based on some metric. 15 | 16 | Choropleths are useful for visualizing data where geographic boundaries are a natural unit of aggregation. For example, here is a choropleth that shows 2012 US State Population Estimates: 17 | 18 | ```{r} 19 | library(choroplethr) 20 | ?df_pop_state 21 | data(df_pop_state) 22 | 23 | state_choropleth(df_pop_state, title="2012 US State Population Estimates", legend="Population") 24 | ``` 25 | 26 | ### What is choroplethr? 27 | 28 | `choroplethr` is an R package that facilitates the creation of choropleth maps in R. It does this in 3 ways. 29 | 30 | 1. It provides ready-made functions for creating choropleths with four different maps. 31 | 2. It provides API connections to interesting data sources for making choropleths. 32 | 3. It provides a framework for creating choropleths from arbitrary shapefiles. 33 | 34 | The remaining vignettes explain these features in more detail. 35 | -------------------------------------------------------------------------------- /vignettes/b-state-choropleth.Rmd: -------------------------------------------------------------------------------- 1 | 5 | 6 | US State Chropleths 7 | === 8 | 9 | You can create a choropleth of US States with the function `state_choropleth`: 10 | 11 | ```{r hold=TRUE} 12 | library(choroplethr) 13 | 14 | ?df_pop_state 15 | data(df_pop_state) 16 | 17 | ?state_choropleth 18 | state_choropleth(df_pop_state) 19 | ``` 20 | 21 | As demonstrated above, the only required parameter to `state_choropleth` is a data.frame. You can see the optional parameters by typing `?state_choropleth`. 22 | 23 | # Data Requirements 24 | 25 | The data.frame that you provide to `state_choropleth` must have one column named "region" and one column named "value". Your entries for "region" must **exactly** match how regions are named in the map which choroplethr uses. These names are defined in the object `state.regions`: 26 | 27 | ```{r} 28 | library(choroplethrMaps) 29 | 30 | ?state.regions 31 | data(state.regions) 32 | head(state.regions) 33 | ``` 34 | 35 | In order to use choroplethr, you must use the naming convention in the "region" column of state.regions. That is, you must use full names in all lowercase letters. 36 | 37 | # Exploring Data 38 | 39 | The `state_choropleth` function provides two parameters to facilitate exploring data: `buckets` and `zoom`. buckets defaults to 7, which means that there are 7 colors, and an equal number of states in each color. Valid values for buckets are integers betwen 1 and 7. If buckets is 1 then a continuous scale will be used. zoom defaults to NULL, which means that all states are shown. You can set it to be a vector of valid regions. 40 | 41 | As an example, here is how you can use choroplethr to show the population of US States on the West Coast. 42 | 43 | ```{r} 44 | state_choropleth(df_pop_state, 45 | title = "2012 Population Estimates", 46 | legend = "Population", 47 | buckets = 1, 48 | zoom = c("california", "washington", "oregon")) 49 | ``` 50 | 51 | # Advanced Options 52 | 53 | Any customization outside the optional parameters presented above will require you to create a `StateChoropleth` object. choroplethr uses [R6](https://github.com/wch/R6) to take advantage of object-oriented programming. Here is an example of using the `ggplot2_scale` on the base Choropleth object to customize the palette used. 54 | 55 | This dataset is the 2012 US Presidential Election results. Normally in this map Democratic states appear blue and Republican states appear red. 56 | 57 | ```{r} 58 | library(ggplot2) 59 | 60 | ?df_president 61 | data(df_president) 62 | 63 | choro = StateChoropleth$new(df_president) 64 | choro$title = "2012 Election Results" 65 | choro$ggplot_scale = scale_fill_manual(name="Candidate", values=c("blue", "red"), drop=FALSE) 66 | choro$render() 67 | ``` 68 | 69 | For additional options on the `StateChoropleth` object, please see the choroplethr [source code](https://github.com/trulia/choroplethr). 70 | 71 | **Note:** Care must be taken when manually setting the scale on `StateChoropleth` objects. In particular, choroplethr uses ggplot2 custom annotations to render Alaska and Hawaii as insets. This means that the scales of the insets and the main map will only be the same if you do the following 72 | 73 | 1. for discrete scales, pass `drop=FALSE` to the scale (as above). 74 | 2. for continuous scales, pass `limits` which encompass the minimum and maximum values for the entire dataset. -------------------------------------------------------------------------------- /vignettes/c-county-choropleth.Rmd: -------------------------------------------------------------------------------- 1 | 5 | 6 | US County Chropleths 7 | === 8 | 9 | You can create a choropleth of US Counties with the function `county_choropleth`: 10 | 11 | ```{r hold=TRUE} 12 | library(choroplethr) 13 | 14 | ?df_pop_county 15 | data(df_pop_county) 16 | 17 | ?county_choropleth 18 | county_choropleth(df_pop_county) 19 | ``` 20 | 21 | As demonstrated above, the only required parameter to `county_choropleth` is a data.frame. You can see the optional parameters by typing `?county_choropleth`. 22 | 23 | # Data Requirements 24 | 25 | The data.frame that you provide to `county_choropleth` must have one column named "region" and one column named "value". Your entries for "region" must **exactly** match how regions are named in the map which choroplethr uses. These names are defined in the object `county.regions`: 26 | 27 | ```{r} 28 | library(choroplethrMaps) 29 | 30 | ?county.regions 31 | data(county.regions) 32 | head(county.regions) 33 | ``` 34 | 35 | In order to use choroplethr, you must use the naming convention in the "region" column of county.regions. That is, you must use the numeric version of the county FIPS code - i.e. you must drop any leading zeroes. 36 | 37 | # Exploring Data 38 | 39 | The `county_choropleth` function provides two parameters to facilitate exploring data: `buckets` and `zoom`. buckets defaults to 7, which means that there are 7 colors, and an equal number of counties in each color. Valid values for buckets are integers betwen 1 and 7. If buckets is 1 then a continuous scale will be used. zoom defaults to NULL, which means that all counties are shown. You can set it to be a vector of states. You must name your states as defined in the "region" column of `?state.regions`. 40 | 41 | As an example, here is how you can use choroplethr to show the population of US Counties on the West Coast. 42 | 43 | ```{r} 44 | county_choropleth(df_pop_county, 45 | title = "2012 Population Estimates", 46 | legend = "Population", 47 | buckets = 1, 48 | zoom = c("california", "washington", "oregon")) 49 | ``` 50 | 51 | If you are interested in zooming in on individual counties, please see the function `?county_zoom_choropleth`. 52 | 53 | # Advanced Options 54 | 55 | Any customization outside the optional parameters presented above will require you to create a `CountyChoropleth` object. choroplethr uses [R6](https://github.com/wch/R6) to take advantage of object-oriented programming. Here is an example of using the `ggplot2_scale` on the base Choropleth object to customize the palette used. 56 | 57 | ```{r} 58 | library(ggplot2) 59 | 60 | choro = CountyChoropleth$new(df_pop_county) 61 | choro$title = "2012 Population Estimates" 62 | choro$ggplot_scale = scale_fill_brewer(name="Population", palette=2, drop=FALSE) 63 | choro$render() 64 | ``` 65 | 66 | **Note:** Care must be taken when manually setting the scale on `CountyChoropleth` objects. In particular, choroplethr uses ggplot2 custom annotations to render Alaska and Hawaii as insets. This means that the scales of the insets and the main map will only be the same if you do the following 67 | 68 | 1. for discrete scales, pass `drop=FALSE` to the scale (as above). 69 | 2. for continuous scales, pass `limits` which encompass the minimum and maximum values for the entire dataset. -------------------------------------------------------------------------------- /vignettes/d-zip-map.Rmd: -------------------------------------------------------------------------------- 1 | 5 | 6 | US ZIP Maps 7 | === 8 | 9 | You can create a visualization of US ZIP codes with the function `zip_map`: 10 | 11 | ```{r hold=TRUE} 12 | library(choroplethr) 13 | 14 | ?df_pop_zip 15 | data(df_pop_zip) 16 | 17 | ?zip_map 18 | zip_map(df_pop_zip) 19 | ``` 20 | 21 | As demonstrated above, the only required parameter to `zip_map` is a data.frame. You can see the optional parameters by typing `?zip_map`. 22 | 23 | Note that this visualization is a scatterplot where the position of each dot represents the longitude and latitude of the zip code and the value is expressed as a color. Also, boundaries of the states are drawn. But because boundaries of the zip codes are not drawn, this visualization is not technically a choropleth. 24 | 25 | # Data Requirements 26 | 27 | The data.frame that you provide to `zip_map` must have one column named "region" and one column named "value". Your entries for "region" must **exactly** match how zip codes are named in the `zipcode` package, which is how choroplethr gets the longitude and latitude of the zip codes: 28 | 29 | ```{r} 30 | library(zipcode) 31 | 32 | ?zipcode 33 | data(zipcode) 34 | head(zipcode) 35 | ``` 36 | 37 | That is, you must use a five digit character representation of the ZIP code. 38 | 39 | # Exploring Data 40 | 41 | The `zip_map` function provides two parameters to facilitate exploring data: `buckets` and `zoom`. buckets defaults to 7, which means that there are 7 colors, and an equal number of counties in each color. Valid values for buckets are integers betwen 1 and 7. If buckets is 1 then a continuous scale will be used. zoom defaults to NULL, which means that all counties are shown. You can set it to be a vector of states. You must name your states as defined in the "region" column of `?state.regions`. 42 | 43 | As an example, here is how you can use choroplethr to show the population of US ZIP codes on the West Coast. 44 | 45 | ```{r} 46 | zip_map(df_pop_zip, 47 | title = "2012 Population Estimates", 48 | legend = "Population", 49 | buckets = 1, 50 | zoom = c("california", "washington", "oregon")) 51 | ``` 52 | 53 | # Advanced Options 54 | 55 | Any customization outside the optional parameters presented above will require you to create a `ZipMap` object. choroplethr uses [R6](https://github.com/wch/R6) to take advantage of object-oriented programming. Here is an example of using the `ggplot2_scale` on the base Choropleth object to customize the palette used. 56 | 57 | ```{r} 58 | library(ggplot2) 59 | 60 | choro = ZipMap$new(df_pop_zip) 61 | choro$title = "2012 Population Estimates" 62 | choro$ggplot_scale = scale_color_brewer(name="Population", palette=2, drop=FALSE) 63 | choro$render() 64 | ``` 65 | 66 | **Note:** Care must be taken when manually setting the scale on `ZipMap` objects. In particular, choroplethr uses ggplot2 custom annotations to render Alaska and Hawaii as insets. This means that the scales of the insets and the main map will only be the same if you do the following 67 | 68 | 1. for discrete scales, pass `drop=FALSE` to the scale (as above). 69 | 2. for continuous scales, pass `limits` which encompass the minimum and maximum values for the entire dataset. -------------------------------------------------------------------------------- /vignettes/e-country-choropleth.Rmd: -------------------------------------------------------------------------------- 1 | 5 | 6 | Country Choropleths 7 | === 8 | 9 | You can create a choropleth of Countries with the function `country_choropleth`: 10 | 11 | ```{r hold=TRUE} 12 | library(choroplethr) 13 | 14 | ?df_pop_country 15 | data(df_pop_country) 16 | 17 | ?country_choropleth 18 | country_choropleth(df_pop_country) 19 | ``` 20 | 21 | As demonstrated above, the only required parameter to `country_choropleth` is a data.frame. You can see the optional parameters by typing `?country_choropleth`. 22 | 23 | This map demonstrates another feature of choroplethr: regions for which no value is provided (what is the population of Antarctica?) appear, by default, as black. 24 | 25 | # Data Requirements 26 | 27 | The data.frame that you provide to `country_choropleth` must have one column named "region" and one column named "value". Your entries for "region" must **exactly** match how regions are named in the map which choroplethr uses. These names are defined in the object `country.regions`: 28 | 29 | ```{r} 30 | library(choroplethrMaps) 31 | 32 | ?country.regions 33 | data(country.regions) 34 | head(country.regions) 35 | ``` 36 | 37 | In order to use choroplethr, you must use the naming convention in the "region" column of country.regions. That is, you must use full names in all lowercase letters. 38 | 39 | # Exploring Data 40 | 41 | The `country_choropleth` function provides two parameters to facilitate exploring data: `buckets` and `zoom`. buckets defaults to 7, which means that there are 7 colors, and an equal number of states in each color. Valid values for buckets are integers betwen 1 and 7. If buckets is 1 then a continuous scale will be used. zoom defaults to NULL, which means that all states are shown. You can set it to be a vector of valid regions. 42 | 43 | As an example, here is how you can use choroplethr to show the population of the US, Canada and Mexico. 44 | 45 | ```{r} 46 | country_choropleth(df_pop_country, 47 | title = "2012 Population Estimates", 48 | legend = "Population", 49 | buckets = 1, 50 | zoom = c("united states of america", "mexico", "canada")) 51 | ``` 52 | 53 | # Advanced Options 54 | 55 | Any customization outside the optional parameters presented above will require you to create a `StateChoropleth` object. choroplethr uses [R6](https://github.com/wch/R6) to take advantage of object-oriented programming. Here is an example of using the `ggplot2_scale` on the base Choropleth object to customize the palette used. 56 | 57 | 58 | ```{r} 59 | library(ggplot2) 60 | 61 | choro = CountryChoropleth$new(df_pop_country) 62 | choro$title = "2012 Population Estimates2012 Election Results" 63 | choro$ggplot_scale = scale_fill_brewer(name="Population", palette=2) 64 | choro$render() 65 | ``` 66 | -------------------------------------------------------------------------------- /vignettes/f-mapping-us-census-data.Rmd: -------------------------------------------------------------------------------- 1 | 5 | 6 | Mapping Census Data 7 | ======================================================== 8 | 9 | choroplethr provides native support for creating choropleths from US Census data. This functionality is available with the `choroplethr_acs` function (`?choroplethr_acs`). The data which choroplethr supports comes from [The American Community Survey (ACS)](https://www.census.gov/acs/www/). To get a feel for this data you might want to view a list of [questions](https://www.census.gov/acs/www/methodology/questionnaire_archive/) asked on it. 10 | 11 | ## How it Works 12 | 13 | choroplethr does not store any data locally. Rather, it uses the R [acs package](http://cran.r-project.org/web/packages/acs/index.html) to get ACS data via the Census API. This means a few things for users of choroplethr 14 | 15 | 2. You must have a [Census API Key](http://www.census.gov/developers/tos/key_request.html) to use this functionality. It's free and easy to get. When you get it type 16 | ``` 17 | library(acs); 18 | api.key.install(''); 19 | ``` 20 | 21 | 1. You will have access to the latest data as soon as it becomes available. 22 | 23 | 3. You only have access to data from 2010 onwards, because the Census Bureau does not provide historic data via its API. 24 | 25 | ## Navigating ACS Data 26 | 27 | 1. [Learn](http://www.census.gov/acs/www/guidance_for_data_users/estimates/) about the difference between the 1, 3 and 5 year estimates. 28 | 29 | 2. [Select](http://factfinder2.census.gov/faces/help/jsf/pages/metadata.xhtml?lang=en&type=survey&id=survey.en.ACS_ACS) a survey to visualize. 30 | 31 | 3. [Select](http://factfinder2.census.gov/faces/help/jsf/pages/metadata.xhtml?lang=en&type=dataset&id=dataset.en.ACS_12_5YR) a table to visualize. When you click thru to a particular survey, you will likely be surprised at just how much data is available. Here are some popular tables to gets you started: 32 | * B01003: total population 33 | * B01002: median age by sex 34 | * B19001: household income in the last 12 months 35 | 36 | ## Example 37 | 38 | Here is how to view population estimates for each state from the 2012 5-year ACS. Notice that the title is automatically created for you from the name of the table. Note that it is commented out because CRAN's servers do not have a US Census API key installed. 39 | 40 | ```{r} 41 | # choroplethr_acs("B01003", "state", endyear=2012, span=5) 42 | ``` 43 | ![](https://raw.githubusercontent.com/trulia/choroplethr/master/wiki-images/v20/acs-example.png) -------------------------------------------------------------------------------- /vignettes/g-world-bank-data.Rmd: -------------------------------------------------------------------------------- 1 | 5 | 6 | Mapping World Bank Data 7 | ======================================================== 8 | 9 | choroplethr provides native support for creating choropleths from data from the World Bank's World Development Indicators (WDI). This functionality is available with the `choroplethr_wdi` function (?choroplethr_wdi). You can learn more about the World Development Indicators [here](http://data.worldbank.org/products/wdi). 10 | 11 | 12 | ### Example: Population 13 | 14 | Here is a choropleth of the population of countries in the world, using a continuous scale. See [here](http://data.worldbank.org/indicator/SP.POP.TOTL) for more information on code SP.POP.TOTL. 15 | 16 | ```{r, hold=TRUE, warning=FALSE, message=FALSE} 17 | library(choroplethr) 18 | library(WDI) 19 | 20 | choroplethr_wdi(code="SP.POP.TOTL", year=2012, title="2012 Population", buckets=1) 21 | ``` 22 | 23 | ### Example: Life Expectancy 24 | 25 | Here is a choropleth of the population of countries in the world. See [here](http://data.worldbank.org/indicator/SP.DYN.LE00.IN) for more information on code SP.DYN.LE00.IN. 26 | 27 | ```{r, hold=TRUE, warning=FALSE, message=FALSE} 28 | choroplethr_wdi(code="SP.DYN.LE00.IN", year=2012, title="2012 Life Expectancy") 29 | ``` 30 | 31 | ### Example: Per Capita Income 32 | 33 | Here is a choropleth of the Per-Capita Income of countries in the world. See [here](http://data.worldbank.org/indicator/NY.GDP.PCAP.CD) for more information on code NY.GDP.PCAP.CD. 34 | 35 | ```{r, hold=TRUE, warning=FALSE, message=FALSE} 36 | choroplethr_wdi(code="NY.GDP.PCAP.CD", year=2012, title="2012 Per Capita Income") 37 | ``` -------------------------------------------------------------------------------- /vignettes/h-animated-choropleths.Rmd: -------------------------------------------------------------------------------- 1 | 5 | 6 | Animated Choropleths 7 | ======================================================== 8 | 9 | Animated choropleths are a useful way to understand how regional values change over time. Consider the US Presidential Election choropleth: it is normally used to show how each state voted in the last presidential election. But what if you want to understand how the results of last election compare to the previous election? Or the election before? In this case an animated choropleth is an effective tool to understand the data. 10 | 11 | ### Example: Historical US Presidential Election Results 12 | choroplethr ships with an example dataset of all US Presidential Election returns. This data is in the variable `df_president_ts`. 13 | 14 | ```{r} 15 | library(choroplethr) 16 | 17 | ?df_president_ts 18 | data(df_president_ts) 19 | 20 | head(df_president_ts, n=1) 21 | ``` 22 | 23 | ### Animating the data 24 | 25 | To animate this data.frame use the `choroplethr_animate` function (?choroplethr_animate). It has one argument, a list of choropleths. Our first task, then, is to convert `df_president_ts` into a list of choropleths: 26 | 27 | ``` 28 | # create a list of choropleths of presidential election results for each year 29 | choropleths = list() 30 | for (i in 2:ncol(df_president_ts)) { 31 | df = df_president_ts[, c(1, i)] 32 | colnames(df) = c("region", "value") 33 | title = paste0("Presidential Election Results: ", colnames(df_president_ts)[i]) 34 | choropleths[[i-1]] = state_choropleth(df, title=title) 35 | } 36 | ``` 37 | 38 | Then call choroplethr_animate with the list of choropleths: 39 | 40 | ``` 41 | choroplethr_animate(choropleths) 42 | ``` 43 | 44 | ### Output 45 | 46 | choroplethr_animate will write each choropleth to your current working directory with the naming convention `choropleth_1.png`, `choropleth_2.png`, etc. It will then write an HTML file named `animated_choropleth.html`. Open that file with a browser - it contains a JavaScript based player that allows you to cycle thru all the images. 47 | 48 | Here is a screenshot of the player. Note that in the upper right hand corner are _play_ and _stop_ buttons. Clicking them will play or stop the animation. There are also _+_ and _-_ buttons which allow you to cycle thru the animation at your own speed. 49 | 50 | ![choroplethr_animate screenshot](https://raw.githubusercontent.com/trulia/choroplethr/10e5e8447c24ef4ca8494eaa35ece8585e091993/wiki-images/animation-screenshot.png) -------------------------------------------------------------------------------- /vignettes/i-creating-your-own-maps.Rmd: -------------------------------------------------------------------------------- 1 | 5 | 6 | Creating Your Own Maps 7 | === 8 | 9 | choroplethr uses object oriented programming to support users creating choropleths with arbitrary maps. If you are interested in this functionality then I recommend you read two articles before proceeding: 10 | 11 | * [Mapmaking for R Programmers](https://github.com/trulia/choroplethr/wiki/Mapmaking-for-R-Programmers). In this page I discuss the basics of acquiring and manipulating shapefiles, as well as importing them into R. If you are interested in creating your own maps, then you should become familiar with this information first. 12 | * [Introduction to R6 Classes](http://rpubs.com/wch/24456). choroplethr uses R6 to implement object-oriented programming. Any map you create should inherit from the base `Choropleth` class. You should understand the basics of what this means. 13 | 14 | ## The Choropleth base class 15 | 16 | A key component of object oriented programming is recognizing common functionality and placing it in a base class. This allows clients to get a lot of common, repetitive behavior "for free". The base class in version 2.0 of the choroplethr package is called Choropleth and has five main functions. If you were to create a choropleth program yourself, you would probably wind up doing (at least) these five steps: 17 | 18 | 1. `initialize(map.df, user.df)`. This is the constructor. map.df is a data.frame representation of a shapefile and needs a column called "region". user.df is the user's data and needs columns called "region" and "value". It does basic error checking on the input. 19 | 20 | 2. `clip()`. This function removes elements from user.df which refer to regions not present on the map. For example, you might have data for the 50 states plus Puerto Rico and Washington, DC. But if the map does not render those regions, you should remove them and warn the user before calling discretize(). 21 | 22 | 3. `discretize()`. You need to take numeric values, such as population counts per state, and turn them into discrete buckets so that they can be rendered. For example, you might want to assign each state to one of seven unique colors based on their population. 23 | 24 | 4. `bind()`. Finally, you need to bind the discretized values to the map. You might also want to warn the user if their data set does not include all values on your map. 25 | 26 | 5. `render()`. The last step is to render the results. Rendering the final result might be easy, or complex. For example, rendering all US 50 States to scale is fairly straightforward. But rendering Alaska and Hawaii as insets can be tricky. 27 | 28 | ## Example: World Map 29 | 30 | Using the base Choropleth functionality, you can easily create a country-level choropleth. Type `data(country.map); ?country.map` for details about the map. 31 | 32 | ```{r hold=TRUE, warning=FALSE, message=FALSE} 33 | library(choroplethr) 34 | library(choroplethrMaps) 35 | library(R6) 36 | library(Hmisc) 37 | library(stringr) 38 | library(dplyr) 39 | library(scales) 40 | library(ggplot2) 41 | 42 | # create the class, inheriting from the base Choropleth object 43 | CountryChoropleth = R6Class("CountryChoropleth", 44 | inherit = choroplethr:::Choropleth, 45 | public = list( 46 | 47 | # initialize with a world map 48 | initialize = function(user.df) 49 | { 50 | data(country.map, package="choroplethrMaps") 51 | super$initialize(country.map, user.df) 52 | } 53 | ) 54 | ) 55 | 56 | # create some sample data and then render it 57 | data(country.regions, package="choroplethrMaps") 58 | df = data.frame(region=country.regions$region, value=sample(1:nrow(country.regions))) 59 | c = CountryChoropleth$new(df) 60 | c$render() 61 | ``` 62 | 63 | In this case, the default behavior of the base class is exactly what we want. We just needed to initialize it with our own map. 64 | 65 | As for rendering it, we just needed to create it with `$new` and render it with `render`. For examples of customizing the map, take a look at the function `country_choropleth`: 66 | 67 | ```{r} 68 | country_choropleth 69 | ``` 70 | 71 | Using the base Choropleth gives you a lot of functionality for free: 72 | 73 | * Error checking on input. 74 | * Ability to zoom in on a subset of regions with the `zoom` parameter. 75 | * Ability to explore the data visually with the `buckets` parameter. 76 | * Easy labelling of the title and legend with the `title` and `legend` parameters. 77 | -------------------------------------------------------------------------------- /vignettes/j-creating-admin1-maps.Rmd: -------------------------------------------------------------------------------- 1 | 6 | 7 | Creating Administrative Level 1 Maps 8 | === 9 | 10 | "Administrative Level 1" is the generic term for the largest subnational administrative unit of a country. This unit has different names depending on the country. For example, in the USA Admin 1 units are called "states", but in Japan they are called "prefectures". choroplethr ships with an Admin 1 map of all countries of the world, and supports creating choropleths of these maps. To learn more about the map type tge following: 11 | 12 | ```{r} 13 | library(choroplethrAdmin1) 14 | ?admin1.map 15 | ``` 16 | 17 | This vignette walks thru an example of using choroplethr to create an Admin 1 choropleth of Japan. The data we will use is 2010 population estimates from the Japanese Census Bureau: 18 | 19 | ```{r} 20 | library(choroplethr) 21 | ?df_japan_census 22 | data(df_japan_census) 23 | head(df_japan_census) 24 | ``` 25 | 26 | # Step 1: Verify that names match 27 | 28 | In order to create a choropleth of our data we first need to understand how names are treated both in the map and in our data. If the names are not the same in both places we will need to make adjustments. (For example if the map says "Tōkyō" but our data says "Tokyo" the map will not render correctly). 29 | 30 | First let's see how the map spells the country: 31 | 32 | ```{r} 33 | head(get_admin1_countries()) 34 | ``` 35 | 36 | The map lists the country as "japan" (all lowercase). Now let's see how the map names the prefectures of Japan: 37 | 38 | ```{r} 39 | head(get_admin1_regions("japan")) 40 | ``` 41 | 42 | They appear in all lower-case without a trailing "-ken". Note that this is exactly the same convention used in our data. So the names match and we can proceed to the next step. 43 | 44 | Note that if you would like to create an Admin 1 map of Japan then type this: 45 | 46 | ```{r} 47 | admin1_map("japan") 48 | ``` 49 | 50 | # Step 2: Prepare our data 51 | 52 | choroplethr requires our data to be in a specific format: a data.frame that contains one column named "region" and one column named "value". `df_japan_census` has a `region` column and several columns of data. But none of them are called `value`. For the purposes of this example, let's copy the `pop_2010` column to the `value` column. 53 | 54 | ```{r} 55 | df_japan_census$value = df_japan_census$pop_2010 56 | ``` 57 | 58 | # Step 3: Explore our data 59 | 60 | Now that our data is prepared for choroplethr, we can view the data with the function `admin1_choropleth`: 61 | 62 | ```{r} 63 | library(choroplethr) 64 | ?admin1_choropleth 65 | admin1_choropleth(country.name = "japan", 66 | df = df_japan_census, 67 | title = "2010 Japan Population Estimates", 68 | legend = "Population", buckets=1) 69 | ``` 70 | 71 | As with all choropleth functions, you can also zoom in to specific regions and change the scale. Here is an example of zooming in on the Kansai region of Japan with a continuous scale: 72 | 73 | ```{r} 74 | kansai = c("mie", "nara", "wakayama", "kyoto", "osaka", "hyogo", "shiga") 75 | admin1_choropleth(country.name = "japan", 76 | df = df_japan_census, 77 | title = "2010 Japan Population Estimates - Kansai Region", 78 | legend = "Population", 79 | buckets = 1, 80 | zoom = kansai) 81 | ``` -------------------------------------------------------------------------------- /wiki-images/animation-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/animation-screenshot.png -------------------------------------------------------------------------------- /wiki-images/choroplethr-acs-state-pop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/choroplethr-acs-state-pop.png -------------------------------------------------------------------------------- /wiki-images/county-pop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/county-pop.png -------------------------------------------------------------------------------- /wiki-images/election-2012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/election-2012.png -------------------------------------------------------------------------------- /wiki-images/r6-examples/country.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/r6-examples/country.png -------------------------------------------------------------------------------- /wiki-images/r6-examples/state-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/r6-examples/state-1.png -------------------------------------------------------------------------------- /wiki-images/r6-examples/state-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/r6-examples/state-2.png -------------------------------------------------------------------------------- /wiki-images/state-pop-1m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/state-pop-1m.png -------------------------------------------------------------------------------- /wiki-images/state-pop-2-buckets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/state-pop-2-buckets.png -------------------------------------------------------------------------------- /wiki-images/state-pop-9-buckets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/state-pop-9-buckets.png -------------------------------------------------------------------------------- /wiki-images/state-pop-boxplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/state-pop-boxplot.png -------------------------------------------------------------------------------- /wiki-images/state-pop-continuous-scale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/state-pop-continuous-scale.png -------------------------------------------------------------------------------- /wiki-images/state-pop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/state-pop.png -------------------------------------------------------------------------------- /wiki-images/v20/acs-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/acs-example.png -------------------------------------------------------------------------------- /wiki-images/v20/country-pop-palette-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/country-pop-palette-2.png -------------------------------------------------------------------------------- /wiki-images/v20/country-pop-zoom-continuous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/country-pop-zoom-continuous.png -------------------------------------------------------------------------------- /wiki-images/v20/country-pop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/country-pop.png -------------------------------------------------------------------------------- /wiki-images/v20/county-pop-palette-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/county-pop-palette-2.png -------------------------------------------------------------------------------- /wiki-images/v20/county-pop-zoom-continuous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/county-pop-zoom-continuous.png -------------------------------------------------------------------------------- /wiki-images/v20/county-pop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/county-pop.png -------------------------------------------------------------------------------- /wiki-images/v20/create-you-own-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/create-you-own-map.png -------------------------------------------------------------------------------- /wiki-images/v20/election-red-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/election-red-blue.png -------------------------------------------------------------------------------- /wiki-images/v20/state-pop-zoom-continuous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/state-pop-zoom-continuous.png -------------------------------------------------------------------------------- /wiki-images/v20/state-pop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/state-pop.png -------------------------------------------------------------------------------- /wiki-images/v20/wdi-life-expect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/wdi-life-expect.png -------------------------------------------------------------------------------- /wiki-images/v20/wdi-per-capita.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/wdi-per-capita.png -------------------------------------------------------------------------------- /wiki-images/v20/wdi-pop-continuous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/wdi-pop-continuous.png -------------------------------------------------------------------------------- /wiki-images/v20/zip-pop-palette-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/zip-pop-palette-2.png -------------------------------------------------------------------------------- /wiki-images/v20/zip-pop-zoom-continuous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/zip-pop-zoom-continuous.png -------------------------------------------------------------------------------- /wiki-images/v20/zip-pop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/v20/zip-pop.png -------------------------------------------------------------------------------- /wiki-images/zip-pop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trulia/choroplethr/4b75fd96dc605710cf6f448fa5d07cbdf0de28fb/wiki-images/zip-pop.png --------------------------------------------------------------------------------