diff --git a/DESCRIPTION b/DESCRIPTION index e936347..2ce39bd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,11 +22,14 @@ Depends: utils Imports: foreach (>= 1.5.1), - devtools (>= 1.10.0) + devtools (>= 1.10.0), + stringr, + dplyr, + Rcpp Suggests: testthat, wruData (>= 0.0.1), -LinkingTo: +LinkingTo: Rcpp, RcppArmadillo, RcppProgress diff --git a/NAMESPACE b/NAMESPACE index 29cd61a..433a6c3 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -14,6 +14,7 @@ export(predict_race_new) export(vec_to_chunk) import(devtools) import(stringr) +import(dplyr) importFrom(Rcpp,evalCpp) importFrom(foreach,"%dopar%") importFrom(foreach,foreach) diff --git a/R/census_geo_api.R b/R/census_geo_api.R index a96bc3d..830b53d 100644 --- a/R/census_geo_api.R +++ b/R/census_geo_api.R @@ -2,13 +2,13 @@ #' #' \code{census_geo_api} retrieves U.S. Census geographic data for a given state. #' -#' This function allows users to download U.S. Census 2010 geographic data, +#' This function allows users to download U.S. Census geographic data (2010 or 2020), #' at either the county, tract, block, or place level, for a particular state. #' #' @param key A required character object. Must contain user's Census API #' key, which can be requested \href{https://api.census.gov/data/key_signup.html}{here}. #' @param state A required character object specifying which state to extract Census data for, -#' e.g., \code{"NJ"}. +#' e.g., \code{"NJ"}. #' @param geo A character object specifying what aggregation level to use. #' Use \code{"county"}, \code{"tract"}, \code{"block"}, or \code{"place"}. #' Default is \code{"tract"}. Warning: extracting block-level data takes very long. @@ -20,10 +20,14 @@ #' sex or not. If \code{FALSE} (default), function will return Pr(Geolocation | Race). #' If \code{TRUE}, function will return Pr(Geolocation, Sex | Race). #' If \code{\var{age}} is also \code{TRUE}, function will return Pr(Geolocation, Age, Sex | Race). +#' @param year A character object specifying the year of U.S. Census data to be downloaded. +#' Use \code{"2010"}, or \code{"2020"}. Default is \code{"2010"}. +#' Warning: 2020 U.S. Census data is downloaded only when \code{\var{age}} and +#' \code{\var{sex}} are both \code{FALSE}. #' @param retry The number of retries at the census website if network interruption occurs. #' @param save_temp File indicating where to save the temporary outputs. -#' Defaults to NULL. If specified, the function will look for an .RData file -#' with the same format as the expected output. +#' Defaults to NULL. If specified, the function will look for an .RData file +#' with the same format as the expected output. #' @return Output will be an object of class \code{list}, indexed by state names. It will #' consist of the original user-input data with additional columns of Census geographic data. #' @@ -31,13 +35,14 @@ #' \dontshow{data(voters)} #' \dontrun{census_geo_api(key = "...", states = c("NJ", "DE"), geo = "block")} #' \dontrun{census_geo_api(key = "...", states = "FL", geo = "tract", age = TRUE, sex = TRUE)} +#' \dontrun{census_geo_api(key = "...", states = "MA", geo = "place", age = FALSE, sex = FALSE, year = "2020")} #' #' @references #' Relies on get_census_api, get_census_api_2, and vec_to_chunk functions authored by Nicholas Nagle, #' available \href{https://rstudio-pubs-static.s3.amazonaws.com/19337_2e7f827190514c569ea136db788ce850.html}{here}. #' #' @export -census_geo_api <- function(key, state, geo = "tract", age = FALSE, sex = FALSE, retry = 0, save_temp = NULL) { +census_geo_api <- function(key, state, geo = "tract", age = FALSE, sex = FALSE, year = "2010", retry = 0, save_temp = NULL) { if (missing(key)) { stop('Must enter U.S. Census API key, which can be requested at https://api.census.gov/data/key_signup.html.') @@ -51,9 +56,32 @@ census_geo_api <- function(key, state, geo = "tract", age = FALSE, sex = FALSE, state.fips <- fips.codes[fips.codes$State == state, "FIPS"] state.fips <- ifelse(nchar(state.fips) == 1, paste0("0", state.fips), state.fips) + # if (age == F & sex == F) { + # num <- ifelse(3:10 != 10, paste("0", 3:10, sep = ""), "10") + # vars <- paste("P0050", num, sep = "") + # } + + # assign variable values based on the year of the census data + if (year == "2010"){ + vars <- c( + pop_white = 'P005003', pop_black = 'P005004', + pop_aian = 'P005005', pop_asian = 'P005006', + pop_nhpi = 'P005007', pop_other = 'P005008', + pop_two = 'P005009', pop_hisp = 'P005010' + ) + } + else if (year == "2020") { + vars <- c( + pop_white = 'P2_005N', pop_black = 'P2_006N', + pop_aian = 'P2_007N', pop_asian = 'P2_008N', + pop_nhpi = 'P2_009N', pop_other = 'P2_010N', + pop_two = 'P2_011N', pop_hisp = 'P2_002N' + ) + } + if (age == F & sex == F) { - num <- ifelse(3:10 != 10, paste("0", 3:10, sep = ""), "10") - vars <- paste("P0050", num, sep = "") + vars <- vars[c("pop_white", "pop_black", "pop_aian", "pop_asian", + "pop_nhpi", "pop_other", "pop_two", "pop_hisp")] } if (age == F & sex == T) { @@ -83,16 +111,24 @@ census_geo_api <- function(key, state, geo = "tract", age = FALSE, sex = FALSE, } } + # set the census data url links + if (year == "2010") { + census_data_url = "https://api.census.gov/data/2010/dec/sf1?" + } + else if (year == "2020") { + census_data_url = "https://api.census.gov/data/2020/dec/pl?" + } + if (geo == "place") { geo.merge <- c("state", "place") region <- paste("for=place:*&in=state:", state.fips, sep = "") - census <- get_census_api("https://api.census.gov/data/2010/dec/sf1?", key = key, vars = vars, region = region, retry) + census <- get_census_api(census_data_url, key = key, vars = vars, region = region, retry) } if (geo == "county") { geo.merge <- c("state", "county") region <- paste("for=county:*&in=state:", state.fips, sep = "") - census <- get_census_api("https://api.census.gov/data/2010/dec/sf1?", key = key, vars = vars, region = region, retry) + census <- get_census_api(census_data_url, key = key, vars = vars, region = region, retry) } if (geo == "tract") { @@ -100,7 +136,7 @@ census_geo_api <- function(key, state, geo = "tract", age = FALSE, sex = FALSE, geo.merge <- c("state", "county", "tract") region_county <- paste("for=county:*&in=state:", state.fips, sep = "") - county_df <- get_census_api("https://api.census.gov/data/2010/dec/sf1?", key = key, vars = vars, region = region_county, retry) + county_df <- get_census_api(census_data_url, key = key, vars = vars, region = region_county, retry) county_list <- county_df$county census <- NULL temp <- check_temp_save(county_list, save_temp, census) @@ -110,7 +146,7 @@ census_geo_api <- function(key, state, geo = "tract", age = FALSE, sex = FALSE, for (c in 1:length(county_list)) { print(paste("County ", c, " of ", length(county_list), ": ", county_list[c], sep = "")) region_county <- paste("for=tract:*&in=state:", state.fips, "+county:", county_list[c], sep = "") - census.temp <- get_census_api("https://api.census.gov/data/2010/dec/sf1?", key = key, vars = vars, region = region_county, retry) + census.temp <- get_census_api(census_data_url, key = key, vars = vars, region = region_county, retry) census <- rbind(census, census.temp) if (!is.null(save_temp)) { save(census, file = save_temp) @@ -124,7 +160,7 @@ census_geo_api <- function(key, state, geo = "tract", age = FALSE, sex = FALSE, geo.merge <- c("state", "county", "tract", "block") region_county <- paste("for=county:*&in=state:", state.fips, sep = "") - county_df <- get_census_api("https://api.census.gov/data/2010/dec/sf1?", key = key, vars = vars, region = region_county, retry) + county_df <- get_census_api(census_data_url, key = key, vars = vars, region = region_county, retry) county_list <- county_df$county census <- NULL temp <- check_temp_save(county_list, save_temp, census) @@ -136,14 +172,14 @@ census_geo_api <- function(key, state, geo = "tract", age = FALSE, sex = FALSE, region_tract <- paste("for=tract:*&in=state:", state.fips, "+county:", county_list[c], sep = "") print(region_tract) - tract_df <- get_census_api("https://api.census.gov/data/2010/dec/sf1?", key = key, vars = vars, region = region_tract, retry) + tract_df <- get_census_api(census_data_url, key = key, vars = vars, region = region_tract, retry) tract_list <- tract_df$tract for (t in 1:length(tract_list)) { print(paste("Tract ", t, " of ", length(tract_list), ": ", tract_list[t], sep = "")) region_block <- paste("for=block:*&in=state:", state.fips, "+county:", county_list[c], "+tract:", tract_list[t], sep = "") - census.temp <- get_census_api("https://api.census.gov/data/2010/dec/sf1?", key = key, vars = vars, region = region_block, retry) + census.temp <- get_census_api(census_data_url, key = key, vars = vars, region = region_block, retry) census <- rbind(census, census.temp) } if (!is.null(save_temp)) { @@ -157,14 +193,25 @@ census_geo_api <- function(key, state, geo = "tract", age = FALSE, sex = FALSE, census$state <- state + # if (age == F & sex == F) { + # + # ## Calculate Pr(Geolocation | Race) + # census$r_whi <- census$P005003 / sum(census$P005003) #Pr(Tract|White) + # census$r_bla <- census$P005004 / sum(census$P005004) #Pr(Tract|Black) + # census$r_his <- census$P005010 / sum(census$P005010) #Pr(Tract|Latino) + # census$r_asi <- (census$P005006 + census$P005007) / (sum(census$P005006) + sum(census$P005007)) #Pr(Tract | Asian or NH/PI) + # census$r_oth <- (census$P005005 + census$P005008 + census$P005009) / (sum(census$P005005) + sum(census$P005008) + sum(census$P005009)) #Pr(Tract | AI/AN, Other, or Mixed) + # + # } + if (age == F & sex == F) { ## Calculate Pr(Geolocation | Race) - census$r_whi <- census$P005003 / sum(census$P005003) #Pr(Tract|White) - census$r_bla <- census$P005004 / sum(census$P005004) #Pr(Tract|Black) - census$r_his <- census$P005010 / sum(census$P005010) #Pr(Tract|Latino) - census$r_asi <- (census$P005006 + census$P005007) / (sum(census$P005006) + sum(census$P005007)) #Pr(Tract | Asian or NH/PI) - census$r_oth <- (census$P005005 + census$P005008 + census$P005009) / (sum(census$P005005) + sum(census$P005008) + sum(census$P005009)) #Pr(Tract | AI/AN, Other, or Mixed) + census$r_whi <- census[, vars["pop_white"]] / sum(census[, vars["pop_white"]]) #Pr(Geo|White) + census$r_bla <- census[, vars["pop_black"]] / sum(census[, vars["pop_black"]]) #Pr(Geo|Black) + census$r_his <- census[, vars["pop_hisp"]] / sum(census[, vars["pop_hisp"]]) #Pr(Geo|Latino) + census$r_asi <- (census[, vars["pop_asian"]] + census[, vars["pop_nhpi"]]) / (sum(census[, vars["pop_asian"]]) + sum(census[, vars["pop_nhpi"]])) #Pr(Geo | Asian or NH/PI) + census$r_oth <- (census[, vars["pop_aian"]] + census[, vars["pop_other"]] + census[, vars["pop_two"]]) / (sum(census[, vars["pop_aian"]]) + sum(census[, vars["pop_other"]]) + sum(census[, vars["pop_two"]])) #Pr(Geo | AI/AN, Other, or Mixed) } diff --git a/R/census_helper.R b/R/census_helper.R index 0cc394a..bf409fd 100644 --- a/R/census_helper.R +++ b/R/census_helper.R @@ -3,9 +3,9 @@ #' \code{census_helper} links user-input dataset with Census geographic data. #' #' This function allows users to link their geocoded dataset (e.g., voter file) -#' with U.S. Census 2010 data. The function extracts Census Summary File data -#' at the county, tract, or block level using the 'UScensus2010' package. Census data -#' calculated are Pr(Geolocation | Race) where geolocation is county, tract, or block. +#' with U.S. Census data (2010 or 2020). The function extracts Census Summary File data +#' at the county, tract, block, or place level. Census data calculated are +#' Pr(Geolocation | Race) where geolocation is county, tract, block, or place. #' #' @param key A required character object. Must contain user's Census API #' key, which can be requested \href{https://api.census.gov/data/key_signup.html}{here}. @@ -19,7 +19,7 @@ #' Census data for, e.g. \code{c("NJ", "NY")}. Default is \code{"all"}, which extracts #' Census data for all states contained in user-input data. #' @param geo A character object specifying what aggregation level to use. -#' Use \code{"county"}, \code{"tract"}, or \code{"block"}. Default is \code{"tract"}. +#' Use \code{"county"}, \code{"tract"}, \code{"block"} or \code{"place"}. Default is \code{"tract"}. #' Warning: extracting block-level data takes very long. #' @param age A \code{TRUE}/\code{FALSE} object indicating whether to condition on #' age or not. If \code{FALSE} (default), function will return Pr(Geolocation | Race). @@ -29,12 +29,19 @@ #' sex or not. If \code{FALSE} (default), function will return Pr(Geolocation | Race). #' If \code{TRUE}, function will return Pr(Geolocation, Sex | Race). #' If \code{\var{age}} is also \code{TRUE}, function will return Pr(Geolocation, Age, Sex | Race). +#' @param year A character object specifying the year of U.S. Census data to be downloaded. +#' Use \code{"2010"}, or \code{"2020"}. Default is \code{"2010"}. +#' Warning: 2020 U.S. Census data is downloaded only when \code{\var{age}} and +#' \code{\var{sex}} are both \code{FALSE}. #' @param census.data A optional census object of class \code{list} containing #' pre-saved Census geographic data. Can be created using \code{get_census_data} function. #' If \code{\var{census.data}} is provided, the \code{\var{age}} element must have the same value #' as the \code{\var{age}} option specified in this function (i.e., \code{TRUE} in both or #' \code{FALSE} in both). Similarly, the \code{\var{sex}} element in the object provided in #' \code{\var{census.data}} must have the same value as the \code{\var{sex}} option here. +#' Moreover, the \code{\var{year}} element in the object provided in \code{\var{census.data}} +#' must have the same value as the \code{\var{year}} option in the function (i.e., \code{"2010"} +#' in both or \code{"2020"} in both). #' If \code{\var{census.data}} is missing, Census geographic data will be obtained via Census API. #' @param retry The number of retries at the census website if network interruption occurs. #' @return Output will be an object of class \code{data.frame}. It will @@ -46,9 +53,11 @@ #' \dontrun{census_helper(key = "...", voter.file = voters, states = "nj", geo = "block")} #' \dontrun{census_helper(key = "...", voter.file = voters, states = "all", geo = "tract", #' age = TRUE, sex = TRUE)} +#' \dontrun{census_helper(key = "...", voter.file = voters, states = "all", geo = "county", +#' age = FALSE, sex = FALSE, year = "2020")} #' #' @export -census_helper <- function(key, voter.file, states = "all", geo = "tract", age = FALSE, sex = FALSE, census.data = NA, retry = 0) { +census_helper <- function(key, voter.file, states = "all", geo = "tract", age = FALSE, sex = FALSE, year = "2010", census.data = NA, retry = 0) { if (is.na(census.data) || (typeof(census.data) != "list")) { toDownload = TRUE @@ -76,8 +85,8 @@ census_helper <- function(key, voter.file, states = "all", geo = "tract", age = if (geo == "place") { geo.merge <- c("place") - if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { - census <- census_geo_api(key, state, geo = "place", age, sex, retry) + if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex) || (census.data[[state]]$year != year)) { + census <- census_geo_api(key, state, geo = "place", age, sex, year, retry) } else { census <- census.data[[toupper(state)]]$place } @@ -85,8 +94,8 @@ census_helper <- function(key, voter.file, states = "all", geo = "tract", age = if (geo == "county") { geo.merge <- c("county") - if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { - census <- census_geo_api(key, state, geo = "county", age, sex, retry) + if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex) || (census.data[[state]]$year != year)) { + census <- census_geo_api(key, state, geo = "county", age, sex, year, retry) } else { census <- census.data[[toupper(state)]]$county } @@ -94,8 +103,8 @@ census_helper <- function(key, voter.file, states = "all", geo = "tract", age = if (geo == "tract") { geo.merge <- c("county", "tract") - if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { - census <- census_geo_api(key, state, geo = "tract", age, sex, retry) + if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex) || (census.data[[state]]$year != year)) { + census <- census_geo_api(key, state, geo = "tract", age, sex, year, retry) } else { census <- census.data[[toupper(state)]]$tract } @@ -103,8 +112,8 @@ census_helper <- function(key, voter.file, states = "all", geo = "tract", age = if (geo == "block") { geo.merge <- c("county", "tract", "block") - if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { - census <- census_geo_api(key, state, geo = "block", age, sex, retry) + if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex) || (census.data[[state]]$year != year)) { + census <- census_geo_api(key, state, geo = "block", age, sex, year, retry) } else { census <- census.data[[toupper(state)]]$block } @@ -140,16 +149,50 @@ census_helper <- function(key, voter.file, states = "all", geo = "tract", age = voter.file$agecat <- ifelse(voter.file$age >= 85, 23, voter.file$agecat) } + # if (age == F & sex == F) { + # + # ## Calculate Pr(Geolocation | Race) + # census$r_whi <- census$P005003 / sum(census$P005003) #Pr(Tract|White) + # census$r_bla <- census$P005004 / sum(census$P005004) #Pr(Tract|Black) + # census$r_his <- census$P005010 / sum(census$P005010) #Pr(Tract|Latino) + # census$r_asi <- (census$P005006 + census$P005007) / (sum(census$P005006) + sum(census$P005007)) #Pr(Tract | Asian or NH/PI) + # census$r_oth <- (census$P005005 + census$P005008 + census$P005009) / (sum(census$P005005) + sum(census$P005008) + sum(census$P005009)) #Pr(Tract | AI/AN, Other, or Mixed) + # + # drop <- c(grep("state", names(census)), grep("P005", names(census))) + # voters.census <- merge(voter.file[toupper(voter.file$state) == toupper(states[s]), ], census[, -drop], by = geo.merge, all.x = T) + # + # } + if (age == F & sex == F) { - + ## Calculate Pr(Geolocation | Race) - census$r_whi <- census$P005003 / sum(census$P005003) #Pr(Tract|White) - census$r_bla <- census$P005004 / sum(census$P005004) #Pr(Tract|Black) - census$r_his <- census$P005010 / sum(census$P005010) #Pr(Tract|Latino) - census$r_asi <- (census$P005006 + census$P005007) / (sum(census$P005006) + sum(census$P005007)) #Pr(Tract | Asian or NH/PI) - census$r_oth <- (census$P005005 + census$P005008 + census$P005009) / (sum(census$P005005) + sum(census$P005008) + sum(census$P005009)) #Pr(Tract | AI/AN, Other, or Mixed) + if (year == "2010") { + geoPopulations <- rowSums(census[,grepl("P00", names(census))]) + vars <- c( + pop_white = 'P005003', pop_black = 'P005004', + pop_aian = 'P005005', pop_asian = 'P005006', + pop_nhpi = 'P005007', pop_other = 'P005008', + pop_two = 'P005009', pop_hisp = 'P005010' + ) + drop <- c(grep("state", names(census)), grep("P005", names(census))) + } + else if (year == "2020") { + geoPopulations <- rowSums(census[,grepl("P2_", names(census))]) + vars <- c( + pop_white = 'P2_005N', pop_black = 'P2_006N', + pop_aian = 'P2_007N', pop_asian = 'P2_008N', + pop_nhpi = 'P2_009N', pop_other = 'P2_010N', + pop_two = 'P2_011N', pop_hisp = 'P2_002N' + ) + drop <- c(grep("state", names(census)), grep("P2_", names(census))) + } + + census$r_whi <- census[, vars["pop_white"]] / sum(census[, vars["pop_white"]]) #Pr(Geo | White) + census$r_bla <- census[, vars["pop_black"]] / sum(census[, vars["pop_black"]]) #Pr(Geo | Black) + census$r_his <- census[, vars["pop_hisp"]] / sum(census[, vars["pop_hisp"]]) #Pr(Geo | Latino) + census$r_asi <- (census[, vars["pop_asian"]] + census[, vars["pop_nhpi"]]) / (sum(census[, vars["pop_asian"]]) + sum(census[, vars["pop_nhpi"]])) #Pr(Geo | Asian or NH/PI) + census$r_oth <- (census[, vars["pop_aian"]] + census[, vars["pop_other"]] + census[, vars["pop_two"]]) / (sum(census[, vars["pop_aian"]]) + sum(census[, vars["pop_other"]]) + sum(census[, vars["pop_two"]])) #Pr(Geo | AI/AN, Other, or Mixed) - drop <- c(grep("state", names(census)), grep("P005", names(census))) voters.census <- merge(voter.file[toupper(voter.file$state) == toupper(states[s]), ], census[, -drop], by = geo.merge, all.x = T) } diff --git a/R/census_helper_v2.R b/R/census_helper_v2.R index d160d25..32485a8 100644 --- a/R/census_helper_v2.R +++ b/R/census_helper_v2.R @@ -1,11 +1,11 @@ #' Census helper function. #' -#' \code{census_helper_v2} links user-input dataset with Census geographic data. +#' \code{census_helper_new} links user-input dataset with Census geographic data. #' #' This function allows users to link their geocoded dataset (e.g., voter file) -#' with U.S. Census 2010 data. The function extracts Census Summary File data -#' at the county, tract, or block level using the 'UScensus2010' package. Census data -#' calculated are Pr(Geolocation | Race) where geolocation is county, tract, or block. +#' with U.S. Census data (2010 or 2020). The function extracts Census Summary File data +#' at the county, tract, block, or place level. Census data calculated are +#' Pr(Geolocation | Race) where geolocation is county, tract, block, or place. #' #' @param key A required character object. Must contain user's Census API #' key, which can be requested \href{https://api.census.gov/data/key_signup.html}{here}. @@ -19,22 +19,17 @@ #' Census data for, e.g. \code{c("NJ", "NY")}. Default is \code{"all"}, which extracts #' Census data for all states contained in user-input data. #' @param geo A character object specifying what aggregation level to use. -#' Use \code{"county"}, \code{"tract"}, or \code{"block"}. Default is \code{"tract"}. -#' Warning: extracting block-level data takes very long. -#' @param age A \code{TRUE}/\code{FALSE} object indicating whether to condition on -#' age or not. If \code{FALSE} (default), function will return Pr(Geolocation | Race). -#' If \code{TRUE}, function will return Pr(Geolocation, Age | Race). -#' If \code{\var{sex}} is also \code{TRUE}, function will return Pr(Geolocation, Age, Sex | Race). -#' @param sex A \code{TRUE}/\code{FALSE} object indicating whether to condition on -#' sex or not. If \code{FALSE} (default), function will return Pr(Geolocation | Race). -#' If \code{TRUE}, function will return Pr(Geolocation, Sex | Race). -#' If \code{\var{age}} is also \code{TRUE}, function will return Pr(Geolocation, Age, Sex | Race). +#' Use \code{"county"}, \code{"tract"}, \code{"block"}, or \code{"place"}. +#' Default is \code{"tract"}. Warning: extracting block-level data takes very long. +#' @param year A character object specifying the year of U.S. Census data to be downloaded. +#' Use \code{"2010"}, or \code{"2020"}. Default is \code{"2010"}. #' @param census.data A optional census object of class \code{list} containing #' pre-saved Census geographic data. Can be created using \code{get_census_data} function. -#' If \code{\var{census.data}} is provided, the \code{\var{age}} element must have the same value -#' as the \code{\var{age}} option specified in this function (i.e., \code{TRUE} in both or -#' \code{FALSE} in both). Similarly, the \code{\var{sex}} element in the object provided in -#' \code{\var{census.data}} must have the same value as the \code{\var{sex}} option here. +#' If \code{\var{census.data}} is provided, the \code{\var{year}} element must +#' have the same value as the \code{\var{year}} option specified in this function +#' (i.e., \code{"2010"} in both or \code{"2020"} in both). +#' If \code{\var{census.data}} is provided, the \code{\var{age}} and the \code{\var{sex}} +#' elements must be \code{FALSE}. This corresponds to the defaults of \code{census_geo_api}. #' If \code{\var{census.data}} is missing, Census geographic data will be obtained via Census API. #' @param retry The number of retries at the census website if network interruption occurs. #' @return Output will be an object of class \code{data.frame}. It will @@ -43,12 +38,12 @@ #' #' @examples #' \dontshow{data(voters)} -#' \dontrun{census_helper(key = "...", voter.file = voters, states = "nj", geo = "block")} -#' \dontrun{census_helper(key = "...", voter.file = voters, states = "all", geo = "tract", -#' age = TRUE, sex = TRUE)} +#' \dontrun{census_helper_new(key = "...", voter.file = voters, states = "nj", geo = "block")} +#' \dontrun{census_helper_new(key = "...", voter.file = voters, states = "all", geo = "tract")} +#' \dontrun{census_helper_new(key = "...", voter.file = voters, states = "all", geo = "place", year = "2020")} #' #' @export -census_helper_new <- function(key, voter.file, states = "all", geo = "tract", age = FALSE, sex = FALSE, census.data = NA, retry = 0) { +census_helper_new <- function(key, voter.file, states = "all", geo = "tract", year = "2010", census.data = NA, retry = 0) { if (is.na(census.data) || (typeof(census.data) != "list")) { toDownload = TRUE @@ -76,8 +71,8 @@ census_helper_new <- function(key, voter.file, states = "all", geo = "tract", ag if (geo == "place") { geo.merge <- c("place") - if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { - census <- census_geo_api(key, state, geo = "place", age, sex, retry) + if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$year != year) || (census.data[[state]]$age != FALSE) || (census.data[[state]]$sex != FALSE)) {#} || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { + census <- census_geo_api(key, state, geo = "place", age = FALSE, sex = FALSE, year, retry) } else { census <- census.data[[toupper(state)]]$place } @@ -85,8 +80,8 @@ census_helper_new <- function(key, voter.file, states = "all", geo = "tract", ag if (geo == "county") { geo.merge <- c("county") - if ((toDownload) || (is.null(census.data[[state]]))) {#} || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { - census <- census_geo_api(key, state, geo = "county", age, sex, retry) + if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$year != year) || (census.data[[state]]$age != FALSE) || (census.data[[state]]$sex != FALSE)) {#} || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { + census <- census_geo_api(key, state, geo = "county", age = FALSE, sex = FALSE, year, retry) } else { census <- census.data[[toupper(state)]]$county } @@ -94,8 +89,8 @@ census_helper_new <- function(key, voter.file, states = "all", geo = "tract", ag if (geo == "tract") { geo.merge <- c("county", "tract") - if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { - census <- census_geo_api(key, state, geo = "tract", age, sex, retry) + if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$year != year) || (census.data[[state]]$age != FALSE) || (census.data[[state]]$sex != FALSE)) {#} || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { + census <- census_geo_api(key, state, geo = "tract", age = FALSE, sex = FALSE, year, retry) } else { census <- census.data[[toupper(state)]]$tract } @@ -103,8 +98,8 @@ census_helper_new <- function(key, voter.file, states = "all", geo = "tract", ag if (geo == "block") { geo.merge <- c("county", "tract", "block") - if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { - census <- census_geo_api(key, state, geo = "block", age, sex, retry) + if ((toDownload) || (is.null(census.data[[state]])) || (census.data[[state]]$year != year) || (census.data[[state]]$age != FALSE) || (census.data[[state]]$sex != FALSE)) {#} || (census.data[[state]]$age != age) || (census.data[[state]]$sex != sex)) { + census <- census_geo_api(key, state, geo = "block", age = FALSE, sex = FALSE, year, retry) } else { census <- census.data[[toupper(state)]]$block } @@ -112,20 +107,54 @@ census_helper_new <- function(key, voter.file, states = "all", geo = "tract", ag census$state <- state - if (age == F & sex == F) { + # if (age == F & sex == F) { + # + # ## Calculate Pr(Geolocation | Race) + # geoPopulations <- rowSums(census[,grepl("P00", names(census))]) + # census$r_whi <- (0.5 + census$P005003) / (geoPopulations + 2.5)#Pr(White | Geo) + # census$r_bla <- (0.5 + census$P005004) / (geoPopulations + 2.5)#Pr(Black | Geo) + # census$r_his <- (0.5 + census$P005010) / (geoPopulations + 2.5)#Pr(Latino | Geo) + # census$r_asi <- (0.5 + census$P005006 + census$P005007) / (geoPopulations + 2.5) #Pr(Asian or NH/PI | Geo) + # census$r_oth <- (0.5 + census$P005005 + census$P005008 + census$P005009) / (geoPopulations + 2.5) #Pr(AI/AN, Other, or Mixed | Geo) + # + # drop <- c(grep("state", names(census)), grep("P005", names(census))) + # voters.census <- merge(voter.file[toupper(voter.file$state) == toupper(states[s]), ], census[, -drop], by = geo.merge, all.x = T) + # + # } + + # if (age == F & sex == F) { - ## Calculate Pr(Geolocation | Race) + ## Calculate Pr(Geolocation | Race) + if (year == "2010") { geoPopulations <- rowSums(census[,grepl("P00", names(census))]) - census$r_whi <- (0.5 + census$P005003) / (geoPopulations + 2.5)#Pr(White | Geo) - census$r_bla <- (0.5 + census$P005004) / (geoPopulations + 2.5)#Pr(Black | Geo) - census$r_his <- (0.5 + census$P005010) / (geoPopulations + 2.5)#Pr(Latino | Geo) - census$r_asi <- (0.5 + census$P005006 + census$P005007) / (geoPopulations + 2.5) #Pr(Asian or NH/PI | Geo) - census$r_oth <- (0.5 + census$P005005 + census$P005008 + census$P005009) / (geoPopulations + 2.5) #Pr(AI/AN, Other, or Mixed | Geo) - + vars <- c( + pop_white = 'P005003', pop_black = 'P005004', + pop_aian = 'P005005', pop_asian = 'P005006', + pop_nhpi = 'P005007', pop_other = 'P005008', + pop_two = 'P005009', pop_hisp = 'P005010' + ) drop <- c(grep("state", names(census)), grep("P005", names(census))) - voters.census <- merge(voter.file[toupper(voter.file$state) == toupper(states[s]), ], census[, -drop], by = geo.merge, all.x = T) - } + else if (year == "2020") { + geoPopulations <- rowSums(census[,grepl("P2_", names(census))]) + vars <- c( + pop_white = 'P2_005N', pop_black = 'P2_006N', + pop_aian = 'P2_007N', pop_asian = 'P2_008N', + pop_nhpi = 'P2_009N', pop_other = 'P2_010N', + pop_two = 'P2_011N', pop_hisp = 'P2_002N' + ) + drop <- c(grep("state", names(census)), grep("P2_", names(census))) + } + + census$r_whi <- (0.5 + census[, vars["pop_white"]]) / (geoPopulations + 2.5) #Pr(White | Geo) + census$r_bla <- (0.5 + census[, vars["pop_black"]]) / (geoPopulations + 2.5) #Pr(Black | Geo) + census$r_his <- (0.5 + census[, vars["pop_hisp"]]) / (geoPopulations + 2.5) #Pr(Latino | Geo) + census$r_asi <- (0.5 + census[, vars["pop_asian"]] + census[, vars["pop_nhpi"]]) / (geoPopulations + 2.5) #Pr(Asian or NH/PI | Geo) + census$r_oth <- (0.5 + census[, vars["pop_aian"]] + census[, vars["pop_other"]] + census[, vars["pop_two"]]) / (geoPopulations + 2.5) #Pr(AI/AN, Other, or Mixed | Geo) + + voters.census <- merge(voter.file[toupper(voter.file$state) == toupper(states[s]), ], census[, -drop], by = geo.merge, all.x = T) + + # } keep.vars <- c(names(voter.file)[names(voter.file) != "agecat"], paste("r", c("whi", "bla", "his", "asi", "oth"), sep = "_")) diff --git a/R/get_census_data.R b/R/get_census_data.R index 2c6d49f..bb8d2e8 100644 --- a/R/get_census_data.R +++ b/R/get_census_data.R @@ -15,6 +15,10 @@ #' sex or not. If \code{FALSE} (default), function will return Pr(Geolocation | Race). #' If \code{TRUE}, function will return Pr(Geolocation, Sex | Race). #' If \code{\var{age}} is also \code{TRUE}, function will return Pr(Geolocation, Age, Sex | Race). +#' @param year A character object specifying the year of U.S. Census data to be downloaded. +#' Use \code{"2010"}, or \code{"2020"}. Default is \code{"2010"}. +#' Warning: 2020 U.S. Census data is downloaded only when \code{\var{age}} and +#' \code{\var{sex}} are both \code{FALSE}. #' @param census.geo An optional character vector specifying what level of #' geography to use to merge in U.S. Census 2010 geographic data. Currently #' \code{"county"}, \code{"tract"}, \code{"block"}, and \code{"place"} are supported. @@ -26,8 +30,10 @@ #' #' @export #' -#' @examples \dontrun{get_census_data(key = "...", states = c("NJ", "NY"), age = TRUE, sex = FALSE)} -get_census_data <- function(key, states, age = FALSE, sex = FALSE, census.geo = "block", retry = 0) { +#' @examples +#' \dontrun{get_census_data(key = "...", states = c("NJ", "NY"), age = TRUE, sex = FALSE)} +#' \dontrun{get_census_data(key = "...", states = "MN", age = FALSE, sex = FALSE, year = "2020")} +get_census_data <- function(key, states, age = FALSE, sex = FALSE, year = "2010", census.geo = "block", retry = 0) { if (missing(key)) { stop('Must enter valid Census API key, which can be requested at https://api.census.gov/data/key_signup.html.') @@ -37,21 +43,21 @@ get_census_data <- function(key, states, age = FALSE, sex = FALSE, census.geo = CensusObj <- NULL for (s in states) { - CensusObj[[s]] <- list(state = s, age = age, sex = sex) + CensusObj[[s]] <- list(state = s, age = age, sex = sex, year = year) if (census.geo == "place") { - place <- census_geo_api(key, s, geo = "place", age, sex, retry) + place <- census_geo_api(key, s, geo = "place", age, sex, year, retry) CensusObj[[s]]$place <- place } if (census.geo == "block") { - block <- census_geo_api(key, s, geo = "block", age, sex, retry) + block <- census_geo_api(key, s, geo = "block", age, sex, year, retry) CensusObj[[s]]$block <- block } if ((census.geo == "block") || (census.geo == "tract")) { - tract <- census_geo_api(key, s, geo = "tract", age, sex, retry) + tract <- census_geo_api(key, s, geo = "tract", age, sex, year, retry) CensusObj[[s]]$tract <- tract } if ((census.geo == "block") || (census.geo == "tract") || (census.geo == "county")) { - county <- census_geo_api(key, s, geo = "county", age, sex, retry) + county <- census_geo_api(key, s, geo = "county", age, sex, year, retry) CensusObj[[s]]$county <- county } } diff --git a/R/merge_names.R b/R/merge_names.R index 049da15..cb634fa 100644 --- a/R/merge_names.R +++ b/R/merge_names.R @@ -33,6 +33,16 @@ #' Other options are \code{"last, first"}, indicating that both last and first names will be #' used, and \code{"last, first, middle"}, indicating that last, first, and middle names will all #' be used. +#' @param use.census.surnames A \code{TRUE}/\code{FALSE} object indicating whether +#' to use an alternative surname dictionary. If \code{TRUE}, the surname dictionary +#' should be passed to \code{\var{census.surnames}}. Default is \code{FALSE}. +#' @param census.surnames An object of class \code{data.frame} provided by the +#' users as an alternative surname dictionary. It will consist of a list of +#' U.S. surnames, along with the associated probabilities P(name | ethnicity) +#' for ethnicities: white, Black, Hispanic, Asian, and other. Default is \code{NULL}. +#' (\code{\var{last_name}} for U.S. surnames, \code{\var{p_whi_last}} for White, +#' \code{\var{p_bla_last}} for Black, \code{\var{p_his_last}} for Hispanic, +#' \code{\var{p_asi_last}} for Asian, \code{\var{p_oth_last}} for other). #' @param clean.names A \code{TRUE}/\code{FALSE} object. If \code{TRUE}, #' any surnames in \code{\var{voter.file}} that cannot initially be matched #' to the database will be cleaned, according to U.S. Census specifications, @@ -54,7 +64,7 @@ #' merge_names(voters) #' #' @export -merge_names <- function(voter.file, namesToUse, use.census.surnames, census.surnames=NULL, clean.names = T) { +merge_names <- function(voter.file, namesToUse='last', use.census.surnames=F, census.surnames=NULL, clean.names = T) { # check the names if(namesToUse == 'last') { @@ -221,7 +231,7 @@ merge_names <- function(voter.file, namesToUse, use.census.surnames, census.surn ## For unmatched names, just fill with a NA - require(dplyr) + # require(dplyr) warning(paste(paste(sum(is.na(df$p_whi_last)), " (", round(100*mean(is.na(df$p_whi_last)), 1), "%) indivduals' last names were not matched.", sep = ""))) if(grepl('first', namesToUse)) { warning(paste(paste(sum(is.na(df$p_whi_first)), " (", round(100*mean(is.na(df$p_whi_first)), 1), "%) indivduals' first names were not matched.", sep = ""))) diff --git a/R/predict_race.R b/R/predict_race.R index e10eb6f..f88ce42 100644 --- a/R/predict_race.R +++ b/R/predict_race.R @@ -20,7 +20,7 @@ #' See below for other optional fields. #' @param census.surname A \code{TRUE}/\code{FALSE} object. If \code{TRUE}, #' function will call \code{merge_surnames} to merge in Pr(Race | Surname) -#' from U.S. Census Surname List (2000 or 2010) and Spanish Surname List. +#' from U.S. Census Surname List (2000, 2010, or 2020) and Spanish Surname List. #' If \code{FALSE}, \code{voter.file} object must contain additional fields specifying #' Pr(Race | Surname), named as follows: \code{\var{p_whi}} for Whites, #' \code{\var{p_bla}} for Blacks, \code{\var{p_his}} for Hispanics/Latinos, @@ -31,9 +31,9 @@ #' @param surname.year A number to specify the year of the census surname statistics. #' These surname statistics is stored in the data, and will be automatically loaded. #' The default value is \code{2010}, which means the surname statistics from the -#' 2010 census will be used. Currently, the other available choice is \code{2000}. +#' 2010 census will be used. Currently, the other available choices are \code{2000} and \code{2020}. #' @param census.geo An optional character vector specifying what level of -#' geography to use to merge in U.S. Census 2010 geographic data. Currently +#' geography to use to merge in U.S. Census geographic data. Currently #' \code{"county"}, \code{"tract"}, \code{"block"}, and \code{"place"} are supported. #' Note: sufficient information must be in user-defined \code{\var{voter.file}} object. #' If \code{\var{census.geo} = "county"}, then \code{\var{voter.file}} @@ -63,6 +63,8 @@ #' May only be set to \code{TRUE} if \code{census.geo} option is specified. #' If \code{TRUE}, \code{\var{voter.file}} should include a numerical variable \code{\var{sex}}, #' where \code{\var{sex}} is coded as 0 for males and 1 for females. +#' @param year An optional character vector specifying the year of U.S. Census geographic +#' data to be downloaded. Use \code{"2010"}, or \code{"2020"}. Default is \code{"2010"}. #' @param party An optional character object specifying party registration field #' in \code{\var{voter.file}}, e.g., \code{\var{party} = "PartyReg"}. #' If specified, race/ethnicity predictions will be conditioned @@ -86,6 +88,7 @@ #' \dontrun{predict_race(voter.file = voters, census.geo = "tract", census.key = "...")} #' \dontrun{predict_race(voter.file = voters, census.geo = "tract", census.key = "...", age = T)} #' \dontrun{predict_race(voter.file = voters, census.geo = "place", census.key = "...", sex = T)} +#' \dontrun{predict_race(voter.file = voters, census.geo = "place", census.key = "...", year = "2020")} #' \dontrun{CensusObj <- get_census_data("...", state = c("NY", "DC", "NJ")); #' predict_race(voter.file = voters, census.geo = "tract", census.data = CensusObj, party = "PID")} #' \dontrun{CensusObj2 <- get_census_data(key = "...", state = c("NY", "DC", "NJ"), age = T, sex = T); @@ -97,7 +100,13 @@ ## Race Prediction Function predict_race <- function(voter.file, census.surname = TRUE, surname.only = FALSE, surname.year = 2010, name.data = NULL, - census.geo, census.key, census.data = NA, age = FALSE, sex = FALSE, party, retry = 0, impute.missing = FALSE) { + census.geo, census.key, census.data = NA, age = FALSE, sex = FALSE, year = "2010", + party, retry = 0, impute.missing = FALSE) { + + # warning: 2020 census data only support prediction when both age and sex are equal to FALSE + if ((sex == TRUE || age == TRUE) && (year == "2020")) { + stop('Warning: only predictions with both age and sex equal to FALSE are supported when using 2020 census data.') + } if (!missing(census.geo) && (census.geo == "precinct")) { # geo <- "precinct" @@ -144,8 +153,8 @@ predict_race <- function(voter.file, ## Merge in Pr(Race | Surname) if necessary if (census.surname) { - if (!(surname.year %in% c(2000,2010, 2021))) { - stop(paste(surname.year, "is not a valid surname.year. It should be 2000, 2010 (default) or 2021.")) + if (!(surname.year %in% c(2000,2010,2020))) { + stop(paste(surname.year, "is not a valid surname.year. It should be 2000, 2010 (default) or 2020.")) } voter.file <- merge_surnames(voter.file, surname.year = surname.year, name.data = name.data, impute.missing = impute.missing) } else { @@ -182,6 +191,7 @@ predict_race <- function(voter.file, geo = "place", age = age, sex = sex, + year = year, census.data = census.data, retry = retry) } @@ -195,6 +205,7 @@ predict_race <- function(voter.file, geo = "block", age = age, sex = sex, + year = year, census.data = census.data, retry = retry) } @@ -213,6 +224,7 @@ predict_race <- function(voter.file, geo = "tract", age = age, sex = sex, + year = year, census.data = census.data, retry = retry) } @@ -226,6 +238,7 @@ predict_race <- function(voter.file, geo = "county", age = age, sex = sex, + year = year, census.data = census.data, retry = retry) } diff --git a/R/predict_race_v2.R b/R/predict_race_v2.R index ca2e265..df7c4c6 100644 --- a/R/predict_race_v2.R +++ b/R/predict_race_v2.R @@ -21,13 +21,13 @@ #' County is three characters (e.g., \code{"031"} not \code{"31"}), #' tract is six characters, and block is four characters. Place is five characters. #' See below for other optional fields. -#' #' @param namesToUse A character vector identifying which names to use for the prediction. +#' @param namesToUse A character vector identifying which names to use for the prediction. #' The default value is \code{"last"}, indicating that only the last name will be used. #' Other options are \code{"last, first"}, indicating that both last and first names will be #' used, and \code{"last, first, middle"}, indicating that last, first, and middle names will all #' be used. #' @param census.geo An optional character vector specifying what level of -#' geography to use to merge in U.S. Census 2010 geographic data. Currently +#' geography to use to merge in U.S. Census geographic data. Currently #' \code{"county"}, \code{"tract"}, \code{"block"}, and \code{"place"} are supported. #' Note: sufficient information must be in user-defined \code{\var{voter.file}} object. #' If \code{\var{census.geo} = "county"}, then \code{\var{voter.file}} @@ -40,12 +40,21 @@ #' must have column named \code{place}. #' Specifying \code{\var{census.geo}} will call \code{census_helper} function #' to merge Census geographic data at specified level of geography. +#' @param census.surnames An object of class \code{data.frame} provided by the +#' users as an alternative surname dictionary. It will consist of a list of +#' U.S. surnames, along with the associated probabilities P(name | ethnicity) +#' for ethnicities: White, Black, Hispanic, Asian, and other. Default is \code{NULL}. +#' (\code{\var{last_name}} for U.S. surnames, \code{\var{p_whi_last}} for White, +#' \code{\var{p_bla_last}} for Black, \code{\var{p_his_last}} for Hispanic, +#' \code{\var{p_asi_last}} for Asian, \code{\var{p_oth_last}} for other). #' @param census.key A character object specifying user's Census API #' key. Required if \code{\var{census.geo}} is specified, because #' a valid Census API key is required to download Census geographic data. #' @param census.data A list indexed by two-letter state abbreviations, #' which contains pre-saved Census geographic data. #' Can be generated using \code{get_census_data} function. +#' @param year An optional character vector specifying the year of U.S. Census geographic +#' data to be downloaded. Use \code{"2010"}, or \code{"2020"}. Default is \code{"2010"}. #' @param retry The number of retries at the census website if network interruption occurs. #' @return Output will be an object of class \code{data.frame}. It will #' consist of the original user-input data with additional columns with @@ -58,22 +67,21 @@ #' #' @examples #' data(voters) -#' predict_race(voters, surname.only = TRUE) -#' predict_race(voter.file = voters, surname.only = TRUE) -#' \dontrun{predict_race(voter.file = voters, census.geo = "tract", census.key = "...")} -#' \dontrun{predict_race(voter.file = voters, census.geo = "tract", census.key = "...", age = T)} -#' \dontrun{predict_race(voter.file = voters, census.geo = "place", census.key = "...", sex = T)} +#' predict_race_new(voters, namesToUse = 'last') +#' predict_race_new(voter.file = voters, namesToUse = 'last') +#' \dontrun{predict_race_new(voter.file = voters, census.geo = "tract", census.key = "...")} +#' \dontrun{predict_race_new(voter.file = voters, census.geo = "place", census.key = "...", year = "2020")} #' \dontrun{CensusObj <- get_census_data("...", state = c("NY", "DC", "NJ")); -#' predict_race(voter.file = voters, census.geo = "tract", census.data = CensusObj, party = "PID")} -#' \dontrun{CensusObj2 <- get_census_data(key = "...", state = c("NY", "DC", "NJ"), age = T, sex = T); -#' predict_race(voter.file = voters, census.geo = "tract", census.data = CensusObj2, age = T, sex = T)} +#' predict_race_new(voter.file = voters, census.geo = "tract", census.data = CensusObj)} +#' \dontrun{CensusObj2 <- get_census_data(key = "...", state = c("NY", "DC", "NJ"), year = "2020"); +#' predict_race_new(voter.file = voters, census.geo = "tract", census.data = CensusObj2, year = "2020")} #' \dontrun{CensusObj3 <- get_census_data(key = "...", state = c("NY", "DC", "NJ"), census.geo = "place"); -#' predict_race(voter.file = voters, census.geo = "place", census.data = CensusObj3)} +#' predict_race_new(voter.file = voters, census.geo = "place", census.data = CensusObj3)} #' @export ## Race Prediction Function predict_race_new <- function(voter.file, namesToUse = 'last', census.geo, census.surnames = NULL, census.key, - census.data = NA, retry = 0) { + census.data = NA, year = "2010", retry = 0) { # check the geography if (!missing(census.geo) && (census.geo == "precinct")) { @@ -147,6 +155,7 @@ predict_race_new <- function(voter.file, namesToUse = 'last', census.geo, census voter.file = voter.file, states = "all", geo = "place", + year = year, census.data = census.data, retry = retry) } @@ -158,6 +167,7 @@ predict_race_new <- function(voter.file, namesToUse = 'last', census.geo, census voter.file = voter.file, states = "all", geo = "block", + year = year, census.data = census.data, retry = retry) } @@ -174,6 +184,7 @@ predict_race_new <- function(voter.file, namesToUse = 'last', census.geo, census voter.file = voter.file, states = "all", geo = "tract", + year = year, census.data = census.data, retry = retry) } @@ -185,6 +196,7 @@ predict_race_new <- function(voter.file, namesToUse = 'last', census.geo, census voter.file = voter.file, states = "all", geo = "county", + year = year, census.data = census.data, retry = retry) } diff --git a/data/voters.RData b/data/voters.RData index e7cfd64..ffe9973 100644 Binary files a/data/voters.RData and b/data/voters.RData differ