├── DESCRIPTION ├── MD5 ├── NAMESPACE ├── R └── acs.R ├── README.md ├── cleanup ├── configure ├── data ├── cpi.rda ├── datalist ├── fips.american.indian.area.rda ├── fips.county.rda ├── fips.county.subdivision.rda ├── fips.place.rda ├── fips.school.rda ├── fips.state.rda ├── kansas07.rda ├── kansas09.rda └── lawrence10.rda └── man ├── acs-class.Rd ├── acs-package.Rd ├── acs.fetch.Rd ├── acs.lookup-class.Rd ├── acs.lookup.Rd ├── acs.tables.install.Rd ├── api.key.install.Rd ├── api.key.migrate.Rd ├── cbind.acs.Rd ├── confint.acs.Rd ├── cpi.Rd ├── currency.convert.Rd ├── currency.year.Rd ├── divide.acs.Rd ├── endyear.Rd ├── fips.state.Rd ├── flatten.geo.set.Rd ├── geo.lookup.Rd ├── geo.make.Rd ├── geo.set-class.Rd ├── geography.Rd ├── kansas07.Rd ├── kansas09.Rd ├── lawrence10.Rd ├── plot-methods.Rd ├── prompt.acs.Rd ├── rbind.acs.Rd ├── read.acs.Rd └── sum-methods.Rd /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: acs 2 | Type: Package 3 | Title: Download, Manipulate, and Present American Community Survey and 4 | Decennial Data from the US Census 5 | Version: 2.1.4 6 | Date: 2019-02-14 7 | Authors@R: c(person("Ezra Haber", "Glenn", role = c("aut", "cre"), 8 | email = "eglenn@mit.edu")) 9 | Author: Ezra Haber Glenn [aut, cre] 10 | Maintainer: Ezra Haber Glenn 11 | URL: http://dusp.mit.edu/faculty/ezra-glenn, 12 | http://eglenn.scripts.mit.edu/citystate/, 13 | http://mailman.mit.edu/mailman/listinfo/acs-r 14 | Description: Provides a general toolkit for downloading, managing, 15 | analyzing, and presenting data from the U.S. Census 16 | (), including 17 | SF1 (Decennial short-form), SF3 (Decennial long-form), and the 18 | American Community Survey (ACS). Confidence intervals provided with 19 | ACS data are converted to standard errors to be bundled with 20 | estimates in complex acs objects. Package provides new methods to 21 | conduct standard operations on acs objects and present/plot data in 22 | statistically appropriate ways. 23 | Suggests: 24 | Imports: graphics, stats, plyr, utils, httr 25 | Depends: R (>= 2.10), stringr, methods, XML 26 | License: GPL-3 27 | LazyData: yes 28 | LazyLoad: yes 29 | NeedsCompilation: no 30 | Packaged: 2019-02-19 20:08:11 UTC; eglenn 31 | Repository: CRAN 32 | Date/Publication: 2019-02-19 21:40:14 UTC 33 | -------------------------------------------------------------------------------- /MD5: -------------------------------------------------------------------------------- 1 | f4c1cff0250c15b84011f1ce97e5de7c *DESCRIPTION 2 | 4f15110e915b80356709373c434dfabe *NAMESPACE 3 | 291b865b8f7ba78e13deba645760c1ef *R/acs.R 4 | 154c52bb6c2233be16a21e83506f3417 *README.md 5 | dd35bf844195fa5db407951264fb40da *cleanup 6 | a56efe2530d38fee0cb013131d617121 *configure 7 | 0c882426fe734fab43fa441ac1444fd5 *data/cpi.rda 8 | 7d5c416d2a74cf236c9958fcaf1b219c *data/datalist 9 | 160031a63a4a2cc66685f5b3334d5b84 *data/fips.american.indian.area.rda 10 | 2346dd5a7e41575efc82a52d004f78f2 *data/fips.county.rda 11 | 2c4a6d3f7d6efaef9db04d747d050f16 *data/fips.county.subdivision.rda 12 | b45477310a4c0f95fe02bb6917973b88 *data/fips.place.rda 13 | e2b5ea844e28ad1fdfcef4d1197728cc *data/fips.school.rda 14 | 84b57a40d38f1bc145a3ae317dd4f594 *data/fips.state.rda 15 | 4846090d987ac4553c2c03caa98d946e *data/kansas07.rda 16 | a54a32b48b127b43d36d5e0902aa91b2 *data/kansas09.rda 17 | 2d0c3c2ce87f22d2a00ba74125910372 *data/lawrence10.rda 18 | a515d9c4869d71a917d2ba853109e9e6 *man/acs-class.Rd 19 | de2184d681342cd0100b5897c61cd74e *man/acs-package.Rd 20 | 87127c8d224459c265858349321b9ffe *man/acs.fetch.Rd 21 | 4f736709a2a6fa7a80014eaf956b90bf *man/acs.lookup-class.Rd 22 | 05d23c2c80678cef26b2fcec9eaf0d4c *man/acs.lookup.Rd 23 | 0010d6441b306331fc20af2e910bec38 *man/acs.tables.install.Rd 24 | cb1d217b3dfe1d4e085d221daa2a2000 *man/api.key.install.Rd 25 | 92fe80fad68597a995ed242691c46ab1 *man/api.key.migrate.Rd 26 | 89b38d86fff1d2adb469e04f95d924f0 *man/cbind.acs.Rd 27 | cc7ae2dbc9308bbd8b1eab4b17e1823a *man/confint.acs.Rd 28 | 0f3a9b59ea81c4ca66585970ff919789 *man/cpi.Rd 29 | fe5121ce9564a5e5755f413f50f77c64 *man/currency.convert.Rd 30 | e04af15072ac51242918215aa521da6c *man/currency.year.Rd 31 | 6d8aef6787edd3deb7f23dd9db169935 *man/divide.acs.Rd 32 | 43db36635a3cfe7da6534442e58c7e9b *man/endyear.Rd 33 | 9196abb0c902adc7e0d5403801e2c946 *man/fips.state.Rd 34 | e6952a347f8278bf4e484111777b2c9b *man/flatten.geo.set.Rd 35 | c94c9d2ff3188f802b2e1c3e6cf11f10 *man/geo.lookup.Rd 36 | fef00e7ab51256ee6d2fc0bb169d637c *man/geo.make.Rd 37 | 6b9a1eedd51e9cc31266726e3d49a5ed *man/geo.set-class.Rd 38 | 2c31d5612ba91846cc514c82dce446f9 *man/geography.Rd 39 | 3784ca40a81e713a0a7ffd7a0377cc28 *man/kansas07.Rd 40 | 1adfd7b2340b0f244cbce818b1f457c2 *man/kansas09.Rd 41 | 3c55c687a816f5a45e06b156da1353ec *man/lawrence10.Rd 42 | 562f688540af9fd683b4838eeb9024cd *man/plot-methods.Rd 43 | c7ce14c39756c1ebc9af839191a2fd03 *man/prompt.acs.Rd 44 | 053138a0adb1ac61e97f6b17345ce8d6 *man/rbind.acs.Rd 45 | 86b75c0ae03ac68250125afff2c2cbb1 *man/read.acs.Rd 46 | 7bd6e3b55cde056f807fc4c5ee1b7840 *man/sum-methods.Rd 47 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | exportPattern("^[[:alpha:]]+") 2 | exportMethods( 3 | "acs.colnames<-", 4 | "acs.colnames", 5 | "acs.units<-", 6 | "acs.units", 7 | "api.for", 8 | "api.in", 9 | "apply", 10 | "-", 11 | "/", 12 | "[<-", 13 | "[", 14 | "[[", 15 | "*", 16 | "+", 17 | "c", 18 | "combine<-", 19 | "combine", 20 | "combine.term<-", 21 | "combine.term", 22 | "currency.year<-", 23 | "currency.year", 24 | "endyear<-", 25 | "endyear", 26 | "estimate", 27 | "geography<-", 28 | "geography", 29 | "geo.list", 30 | "length", 31 | "modified", 32 | "name", 33 | "plot", 34 | "results", 35 | "show", 36 | "span<-", 37 | "span", 38 | "standard.error", 39 | "sum", 40 | "summary" 41 | ) 42 | S3method(confint,acs) 43 | S3method(dim,acs) 44 | S3method(length,acs) 45 | S3method(prompt,acs) 46 | S3method(cbind,acs) 47 | S3method(rbind,acs) 48 | exportClasses( 49 | "acs", 50 | "acs.lookup", 51 | "geo", 52 | "geo.set" 53 | ) 54 | import(XML) 55 | import(methods) 56 | # import(plyr) 57 | import(stringr) 58 | importFrom(utils,prompt) 59 | importFrom("graphics", "abline", "axis", "lines", "par", "points") 60 | importFrom("plyr", "rbind.fill") 61 | importFrom("stats", "confint", "dnorm", "qnorm") 62 | importFrom("httr", "http_error", "GET") 63 | importFrom("utils", "data", "file_test", "head", "read.csv", "tail", "unzip", "download.file") 64 | -------------------------------------------------------------------------------- /R/acs.R: -------------------------------------------------------------------------------- 1 | # library(stringr) 2 | # library(plyr) 3 | # library(XML) 4 | 5 | # fips.state=read.csv("./data/FIPS_state_file.txt", sep="|", stringsAsFactors=F) 6 | # fips.county=read.csv("./data/FIPS_county_file.txt", sep=",", stringsAsFactors=F) 7 | 8 | ## this file needs extra help, due to commas in some of the subdiv 9 | ## names, which goofs up the read.csv import 10 | # fips.county.subdivision=read.csv("./data/FIPS_countysubdivision_file.txt", sep=",", stringsAsFactors=F) 11 | # correct some problem with commas in names 12 | # index=nchar(fips.county.subdivision$FUNCSTAT)>1 13 | # fips.county.subdivision$COUSUBNAME[index]=paste(fips.county.subdivision$COUSUBNAME[index], fips.county.subdivision$FUNCSTAT[index], sep=":") 14 | # fips.county.subdivision$FUNCSTAT[index]="N" 15 | # fips.county.subdivision=fips.county.subdivision[!is.na(fips.county.subdivision$STATEFP),] 16 | 17 | # fips.place=read.csv("./data/FIPS_place_file.txt", sep="|", stringsAsFactors=F) 18 | 19 | # .acs.unit.levels 20 | # 21 | # includes all valid types of units for acs estimates 22 | 23 | .acs.unit.levels=c("count","dollars","proportion", "ratio", "other") 24 | 25 | 26 | # .acs.dimnames() 27 | # 28 | # ensures that a returned acs object includes proper row (geography) 29 | # and column (col.names) labels 30 | 31 | .acs.dimnames=function(acs.obj){ 32 | dimnames(acs.obj@estimate)=list(acs.obj@geography[[1]],acs.obj@acs.colnames) 33 | dimnames(acs.obj@standard.error)=list(acs.obj@geography[[1]],acs.obj@acs.colnames) 34 | acs.obj} 35 | 36 | # .acs.combine.headers() 37 | # 38 | # create metadata and row/column names for operations that merge two 39 | # acs units into one 40 | 41 | .acs.combine.headers=function(e1, e2, operator) { 42 | if (endyear(e1)==endyear(e2)) 43 | ENDYEAR=endyear(e1) 44 | else 45 | ENDYEAR=NA_integer_ 46 | if (currency.year(e1)==currency.year(e2)) 47 | CURRENCY.YEAR=currency.year(e1) 48 | else 49 | CURRENCY.YEAR=NA_integer_ 50 | if (span(e1)==span(e2)) 51 | SPAN=span(e1) 52 | else 53 | SPAN=NA_integer_ 54 | if (identical(geography(e1), geography(e2))) GEOGRAPHY=geography(e1) 55 | else { 56 | GEOGRAPHY=geography(e1) 57 | for (i in 1:length(geography(e1))){ 58 | if (!identical(geography(e1)[[i]], geography(e2)[[i]])) 59 | GEOGRAPHY[[i]]=paste("(", GEOGRAPHY[[i]], operator, geography(e2)[[i]], ")", sep=" ") 60 | } 61 | } 62 | if (identical(acs.colnames(e1), acs.colnames(e2))) 63 | {ACS.COLNAMES=acs.colnames(e1) 64 | ACS.UNITS=acs.units(e1)} 65 | else 66 | {ACS.COLNAMES=paste("(", acs.colnames(e1), operator, acs.colnames(e2), ")", sep=" ") 67 | ACS.UNITS=factor("other", levels=.acs.unit.levels) 68 | } 69 | header=list(endyear=ENDYEAR, span=SPAN, currency.year=CURRENCY.YEAR , geography=GEOGRAPHY, 70 | acs.colnames=ACS.COLNAMES, acs.units=ACS.UNITS) 71 | header 72 | } 73 | 74 | 75 | # .acs.identify.units() 76 | # 77 | # used to set units in acs object; initially assumes all units are 78 | # "counts", then changes some to "dollars" is the word "dollars" 79 | # matches in colnames. 80 | 81 | .acs.identify.units=function(acs.colnames) 82 | { 83 | acs.units=rep("count", length(acs.colnames)) 84 | dollar.index=grep(pattern="dollars",x=acs.colnames, fixed=T) 85 | acs.units[dollar.index]="dollars" 86 | factor(acs.units, levels=.acs.unit.levels) 87 | } 88 | 89 | 90 | # .acs.make.constant.object() 91 | # 92 | # use this to create an acs object with some constant value in the 93 | # estimate and 0 for all the standard errors -- helpful, for example, 94 | # to add a certain number to every value. 95 | 96 | .acs.make.constant.object=function(value, template){ 97 | acs.obj=template 98 | # if given a vector, replaces by row, not by column 99 | acs.obj@estimate[,]=value 100 | acs.obj@standard.error[,]=0 101 | acs.obj@acs.colnames[1:length(acs.colnames(acs.obj))]=as.character(value) 102 | acs.obj=.acs.dimnames(acs.obj) 103 | acs.obj 104 | } 105 | 106 | # an internal function to generate urls variables look like 107 | # c("B21003_001E","B21003_001M") geo.call should have "for" and "in" 108 | # "for" is pairlist, like pairlist(county=05) or c("block+group"="*") 109 | # "in" is pairlist including none or more of: state, county, tract, 110 | # each either number or "*" 111 | 112 | # 9/2017: fixing to enforce leading zeroes, e.g. CA=06, etc. 113 | # need to do for all fips types 114 | # need to prevent zeroes on wildcard!!! 115 | api.url.maker=function(endyear, span, key, variables, dataset, geo.call) { 116 | variables=paste0(variables, collapse=",") 117 | if(span==0) {span=""} 118 | api.for.names=names(api.for(geo.call)) 119 | api.for.values=api.for(geo.call) 120 | if(api.for.values!="*") # only add leading zeroes when not wildcard 121 | { 122 | if(api.for.names=="state") {api.for.values=sprintf("%02d",as.numeric(api.for.values))} 123 | if(api.for.names=="county") {api.for.values=sprintf("%03d",as.numeric(api.for.values))} 124 | if(api.for.names=="county+subdivision") {api.for.values=sprintf("%05d",as.numeric(api.for.values))} 125 | if(api.for.names=="place") {api.for.values=sprintf("%05d",as.numeric(api.for.values))} 126 | if(api.for.names=="school+district+(unified)" | api.for.names=="school+district+(elementary)" | api.for.names=="school+district+(secondary)") 127 | {api.for.values=sprintf("%05d",as.numeric(api.for.values))} 128 | } 129 | api.for=paste0("for=",paste(api.for.names, api.for.values, sep=":")) 130 | 131 | api.in.names=names(api.in(geo.call)) 132 | api.in.values=api.in(geo.call) 133 | notwild=api.in.values!="*" # index to avoid altering wildcards 134 | api.in.values[api.in.names=="state" & notwild]=sprintf("%02d",as.numeric(api.in.values[api.in.names=="state" & notwild])) 135 | api.in.values[api.in.names=="county" & notwild]=sprintf("%03d",as.numeric(api.in.values[api.in.names=="county" & notwild])) 136 | api.in.values[api.in.names=="county+subdivision" & notwild]=sprintf("%05d",as.numeric(api.in.values[api.in.names=="county+subdivision" & notwild])) 137 | api.in.values[api.in.names=="place" & notwild]=sprintf("%05d",as.numeric(api.in.values[api.in.names=="place" & notwild])) 138 | api.in=paste0(paste(api.in.names, api.in.values, sep=":"), collapse="+") 139 | 140 | if (!identical(api.in, "")) api.in=paste0("&in=",api.in) 141 | api.url=paste0("https://api.census.gov/data/", endyear, "/acs/" , dataset, span, "?key=", key, "&get=", variables, ",NAME&", api.for, api.in) 142 | if (endyear==2009 && dataset=="acs") {api.url=paste0("https://api.census.gov/data/", endyear, "/" , dataset, span, "?key=", key, "&get=", variables, ",NAME&", api.for, api.in)} 143 | if (span==3 && dataset=="acs") {api.url=paste0("https://api.census.gov/data/", endyear, "/" , dataset, span, "?key=", key, "&get=", variables, ",NAME&", api.for, api.in)} 144 | api.url 145 | } 146 | 147 | # a function to install a users key for use in this and future 148 | # sessions 149 | # writes to package extdata directory 150 | 151 | api.key.install=function(key, file="key.rda") { 152 | dir.create(paste(system.file(package="acs"), "extdata", sep="/"), showWarnings=F) 153 | save(key, file=paste(system.file("extdata", package="acs"), file, sep="/")) 154 | } 155 | 156 | # a function to migrate a previously installed api.key after package update 157 | # writes to package extdata directory 158 | 159 | api.key.migrate=function() { 160 | key.path=system.file("../key-holder.rda", package="acs") 161 | if(file.exists(key.path)) { 162 | dir.create(paste(system.file(package="acs"), "extdata", sep="/"), showWarnings=F) 163 | file.copy(from=key.path, to=paste(system.file("extdata", package="acs"), "key.rda", sep="/"), overwrite=T) 164 | } else {warning("No archived key found;\n try api.key.install with new key.")} 165 | } 166 | 167 | 168 | # a function to download XML variable lookup files, 169 | # to speed up future acs.lookup calls. 170 | 171 | acs.tables.install=function() { 172 | filelist=readLines("http://web.mit.edu/eglenn/www/acs/acs-variables/filelist.txt") 173 | dir.create(paste(system.file(package="acs"), "extdata", sep="/"), showWarnings=F) 174 | for (i in filelist) { 175 | download.file(url=paste("http://web.mit.edu/eglenn/www/acs/acs-variables/", i, sep=""), destfile=paste(system.file("extdata/", package="acs"), i, sep=""))} 176 | } 177 | 178 | setClass(Class="acs", representation = 179 | representation(endyear="integer", span="integer", 180 | geography="data.frame", acs.colnames="character", modified="logical" 181 | , acs.units="factor", currency.year="integer", estimate="matrix", 182 | standard.error="matrix"), prototype(endyear=NA_integer_, 183 | span=NA_integer_, acs.units=factor(levels=.acs.unit.levels), 184 | currency.year=NA_integer_, modified=F)) 185 | 186 | is.acs=function(object){ 187 | if (class(object)=="acs") {TRUE} 188 | else{FALSE}} 189 | 190 | globalVariables(c("fips.state","fips.school","fips.county.subdivision", "fips.american.indian.area","fips.county", "fips.place")) 191 | 192 | 193 | setClass(Class="geo", representation = 194 | representation(api.for="list", api.in="list", name="character", sumlev="numeric"), prototype()) 195 | 196 | is.geo=function(object){ 197 | if (class(object)=="geo") {TRUE} 198 | else{FALSE}} 199 | 200 | if (!isGeneric("api.for")) { 201 | setGeneric("api.for", def=function(object){standardGeneric("api.for")})}else{} 202 | setMethod("api.for", "geo", function(object) object@api.for) 203 | 204 | if (!isGeneric("api.in")) { 205 | setGeneric("api.in", def=function(object){standardGeneric("api.in")})}else{} 206 | setMethod("api.in", "geo", function(object) object@api.in) 207 | 208 | if (!isGeneric("name")) { 209 | setGeneric("name", def=function(object){standardGeneric("name")})}else{} 210 | setMethod("name", "geo", function(object) object@name) 211 | 212 | if (!isGeneric("sumlev")) { 213 | setGeneric("sumlev", def=function(object){standardGeneric("sumlev")})}else{} 214 | setMethod("sumlev", "geo", function(object) object@sumlev) 215 | 216 | setClass(Class="geo.set", representation = 217 | representation(geo.list="list", combine="logical", combine.term="character"), 218 | prototype(combine=T, combine.term="aggregate")) 219 | is.geo.set=function(object){ 220 | if (class(object)=="geo.set") {TRUE} 221 | else{FALSE}} 222 | if (!isGeneric("combine")) { 223 | setGeneric("combine", def=function(object){standardGeneric("combine")})}else{} 224 | setMethod("combine", "geo.set", function(object) object@combine) 225 | if (!isGeneric("combine.term")) { 226 | setGeneric("combine.term", def=function(object){standardGeneric("combine.term")})}else{} 227 | setMethod("combine.term", "geo.set", function(object) object@combine.term) 228 | if (!isGeneric("geo.list")) { 229 | setGeneric("geo.list", def=function(object){standardGeneric("geo.list")})}else{} 230 | 231 | setMethod("geo.list", "geo.set", function(object) { 232 | if(length(object@geo.list)==1) object@geo.list[[1]] 233 | else object@geo.list}) 234 | 235 | setMethod("show", signature(object = "geo"), function(object) { 236 | cat("\"geo\" object: ") 237 | print(object@name) 238 | }) 239 | 240 | # setMethod("show", signature(object = "geo.set"), function(object) { 241 | # cat("An object of class \"geo.list\"\n\n") 242 | # cat("Slot \"geo.list\":\n") 243 | # print(lapply(X=object@geo.list, FUN=name)) 244 | # cat("Slot \"combine\":\n") 245 | # print(object@combine) 246 | # cat("Slot \"combine.term\":\n") 247 | # print(object@combine.term) 248 | # }) 249 | 250 | 251 | # method to combine geos and geo.sets 252 | setMethod("+", signature(e1 = "geo", e2 = "geo"), function(e1, e2) { 253 | geo.set.obj=new(Class="geo.set", 254 | combine=FALSE, 255 | geo.list=c(e1, e2)) 256 | geo.set.obj 257 | }) 258 | setMethod("+", signature(e1 = "geo.set", e2 = "geo"), function(e1, e2) { 259 | geo.set.obj=new(Class="geo.set", 260 | combine=combine(e1), 261 | geo.list=c(geo.list(e1), e2)) 262 | geo.set.obj 263 | }) 264 | setMethod("+", signature(e1 = "geo", e2 = "geo.set"), function(e1, e2) { 265 | geo.set.obj=new(Class="geo.set", 266 | combine=combine(e2), 267 | geo.list=c(e1, geo.list(e2))) 268 | geo.set.obj 269 | }) 270 | 271 | # Note on "+" 272 | # if geo.list(e1), geo.list(e2) are geo.sets, then take the geolists of them, recusively; 273 | # should always yield flattend set. 274 | 275 | setMethod("+", signature(e1 = "geo.set", e2 = "geo.set"), function(e1, e2) { 276 | if(is.geo(geo.list(e2))) combine=combine(e1) else 277 | if(is.geo(geo.list(e1))) combine=combine(e2) else 278 | combine=F 279 | geo.set.obj=flatten.geo.set(c(e1,e2)) 280 | combine(geo.set.obj)=combine 281 | combine.term(geo.set.obj)=paste(combine.term(e1), " + ", combine.term(e2)) 282 | geo.set.obj 283 | }) 284 | 285 | flatten.geo.set=function(x) { 286 | if (!is.geo.set(x)) return(NA) 287 | if (length(x)==1){ 288 | if (is.geo(geo.list(x))) { 289 | return(x)} 290 | if (is.geo.set(geo.list(x))) { 291 | return(flatten.geo.set(geo.list(x[1])))} 292 | } 293 | if (length(x)>1){ 294 | a=flatten.geo.set(x[1]) 295 | b=flatten.geo.set(x[2:length(x)]) 296 | new(Class="geo.set", combine=combine(x), 297 | combine.term=combine.term(x), geo.list=c(geo.list(a), geo.list(b))) 298 | } 299 | } 300 | 301 | setMethod("c", signature(x = "geo.set"), function(x, y, ..., combine=F, combine.term="aggregate", recursive = FALSE) { 302 | if (recursive) { 303 | if (missing(y)) geo.set.obj=x 304 | else geo.set.obj=x+c(y, ..., recursive=T) 305 | geo.set.obj@combine=combine 306 | geo.set.obj@combine.term=combine.term 307 | } else { 308 | if (missing(y)) {geo.set.obj=x} else { 309 | if (length(y)==1) { 310 | geo.set.obj=c((x+geo.list(y)),...) 311 | geo.set.obj@combine=combine 312 | geo.set.obj@combine.term=combine.term 313 | } 314 | else { 315 | geo.set.obj=new(Class="geo.set", combine=combine, combine.term=combine.term, geo.list=list(x,y, ...))}} 316 | } 317 | geo.set.obj 318 | }) 319 | 320 | # NOTE: changed this to prevent extra nesting when only one 321 | # geo.set is subsetted 322 | 323 | setMethod(f="[", signature="geo.set", definition=function(x,i,j,...,drop=FALSE){ 324 | if (missing(i)) i=j 325 | if (missing(j)) j=i 326 | if (length(i)==1 && is.geo.set(x@geo.list[[i]])) return(x@geo.list[[i]]) 327 | else 328 | new(Class="geo.set", 329 | geo.list=x@geo.list[i], combine=combine(x), 330 | combine.term=paste(combine.term(x), "(partial)", sep=" "))}) 331 | 332 | setMethod(f="[[", signature="geo.set", definition=function(x,i,j,...,drop=FALSE){ 333 | if (missing(i)) i=j 334 | if (missing(j)) j=i 335 | x@geo.list[[i]]}) 336 | 337 | # need to work on to allow to change combine values -- seem to not like when you replace more than one 338 | setReplaceMethod(f="[", signature="geo.set", 339 | definition=function(x,i,j,value){ 340 | if (missing(i)) i=j 341 | if (missing(j)) j=i 342 | if (length(i)==1){ 343 | x@geo.list[i]=value 344 | validObject(x) 345 | return(x)} 346 | else { 347 | for (a in i) { 348 | x@geo.list[i]=value@geo.list[a] 349 | } 350 | validObject(x) 351 | return(x) 352 | } 353 | }) 354 | 355 | setReplaceMethod(f="[[", signature="geo.set", 356 | definition=function(x,i,j,value){ 357 | if (missing(i)) i=j 358 | if (missing(j)) j=i 359 | x@geo.list[i]=value 360 | validObject(x) 361 | return(x)}) 362 | 363 | 364 | ## for some reason, can't declare new generic for "length" 365 | # if (!isGeneric("length")) { 366 | # setGeneric("length", def=function(x){standardGeneric("length")})}else{} 367 | 368 | setMethod("length", "geo.set", function(x) length(x@geo.list)) 369 | 370 | if (!isGeneric("combine<-")) { 371 | setGeneric("combine<-", def=function(object, value){standardGeneric("combine<-")})}else{} 372 | 373 | setReplaceMethod(f="combine", signature="geo.set", 374 | definition=function(object,value){ 375 | object@combine=value 376 | validObject(object) 377 | return(object) 378 | }) 379 | 380 | if (!isGeneric("combine.term<-")) { 381 | setGeneric("combine.term<-", def=function(object, value){standardGeneric("combine.term<-")})}else{} 382 | 383 | setReplaceMethod(f="combine.term", signature="geo.set", 384 | definition=function(object,value){ 385 | object@combine.term=value 386 | validObject(object) 387 | return(object) 388 | }) 389 | 390 | geo.lookup=function(state, county, county.subdivision, place, american.indian.area, school.district, school.district.elementary, school.district.secondary, school.district.unified) { 391 | # first deal with american indian areas -- only one with no state 392 | if (!missing(american.indian.area)) { 393 | if (nargs()>1) {warning("american indian area selected; no other options allowed; \n returning NA") 394 | return(NA)} 395 | if(is.character(american.indian.area)){ 396 | fips.american.indian.area=fips.american.indian.area[grepl(paste(american.indian.area, collapse="|"), fips.american.indian.area$American.Indian.Area.Name), ]} 397 | else { 398 | fips.american.indian.area=fips.american.indian.area[fips.american.indian.area$American.Indian.Area.Code %in% american.indian.area]} 399 | american.indian.area=fips.american.indian.area[,1] 400 | american.indian.area.name=fips.american.indian.area[,2] 401 | results=data.frame(american.indian.area, american.indian.area.name, stringsAsFactors=F) 402 | return(results) 403 | } 404 | # all remaining need state 405 | state.name=NA 406 | if (missing(state)){warning("state required for geo.lookup with these options; \n returning NA") 407 | return(NA)} 408 | for (i in 1:length(state)){ 409 | if (is.character(state[i])){ 410 | if (nchar(state[i])==2) { 411 | state[i]=fips.state[fips.state$STUSAB==state[i],1]} 412 | else { 413 | state[i]=fips.state[grep(paste("^", state[i], sep=""), fips.state$STATE_NAME),1]} 414 | } 415 | } 416 | state=state[state %in% fips.state$STATE] # remove non-matches 417 | state.name=fips.state[fips.state$STATE %in% state ,3] 418 | if (length(state)==0) { 419 | warning("No valid state names match search string;\n returning NA") 420 | return(NA)} 421 | if(length(state) > 1){ 422 | state=as.integer(state) 423 | a=geo.lookup(state=state[1], county=county, county.subdivision=county.subdivision, place=place, school.district=school.district, school.district.elementary=school.district.elementary, school.district.secondary=school.district.secondary, school.district.unified=school.district.unified) 424 | b=geo.lookup(state=state[2:length(state)], county=county, county.subdivision=county.subdivision, place=place, school.district=school.district, school.district.elementary=school.district.elementary, school.district.secondary=school.district.secondary, school.district.unified=school.district.unified) 425 | return(rbind.fill(a,b))} 426 | results=data.frame(state=state, state.name=state.name, stringsAsFactors=F) 427 | # check counties 428 | fips.county.sub=fips.county.subdivision[fips.county.subdivision$STATEFP==state,] 429 | if (!missing(county)) { 430 | fips.county=fips.county[fips.county$State.ANSI==state,] 431 | if(is.character(county)){ 432 | fips.county=fips.county[grepl(paste(county, collapse="|"), fips.county$County.Name), ]} 433 | else { 434 | fips.county=fips.county[fips.county$County.ANSI %in% county, ] 435 | } 436 | county=fips.county[,3] 437 | # need to fix for when county is numeric vector, here and below 438 | # else {county=county[county %in% fips.county$County.ANSI]} 439 | county.name=fips.county[, 4] 440 | if(length(county)>0){ 441 | results=rbind.fill(results, data.frame(state, state.name, county, county.name, stringsAsFactors=F))}} 442 | # check subdivisions, when no county given; state still required 443 | if (missing(county) && !missing(county.subdivision)){ 444 | if(is.character(county.subdivision)){ 445 | fips.county.sub=fips.county.sub[grepl(paste(county.subdivision, 446 | collapse="|"), fips.county.sub$COUSUBNAME) , ]} 447 | else { 448 | fips.county.sub=fips.county.sub[fips.county.sub$COUSUBFP %in% county.subdivision , ]} 449 | county.subdivision=fips.county.sub[,5] 450 | subdivision.name=fips.county.sub[ , 6] 451 | this.county=fips.county.sub[ , 3] 452 | this.county.name=fips.county.sub[ , 4] 453 | if(length(county.subdivision)>0){ 454 | results=rbind.fill(results, data.frame(state, state.name, county=this.county, county.name=this.county.name, county.subdivision, county.subdivision.name=subdivision.name, stringsAsFactors=F))}} 455 | # check subdivisions, when county is given 456 | if (!missing(county) && !missing(county.subdivision)){ 457 | if(is.character(county.subdivision)){ 458 | fips.county.sub=fips.county.sub[grepl(paste(county.subdivision, collapse="|"), fips.county.sub$COUSUBNAME) & fips.county.sub$COUNTYFP %in% county, ]} 459 | else { 460 | fips.county.sub=fips.county.sub[fips.county.sub$COUSUBFP %in% county.subdivision & fips.county.sub$COUNTYFP %in% county ,]} 461 | county.subdivision=fips.county.sub[,5] 462 | subdivision.name=fips.county.sub[ , 6] 463 | this.county=fips.county.sub[ , 3] 464 | this.county.name=fips.county.sub[ , 4] 465 | if(length(county.subdivision)>0){ 466 | results=rbind.fill(results, data.frame(state, state.name, county=this.county, county.name=this.county.name, county.subdivision, county.subdivision.name=subdivision.name, stringsAsFactors=F))}} 467 | # check place 468 | if (!missing(place)){ 469 | fips.place=fips.place[fips.place$STATEFP==state,] 470 | if(is.character(place)) { 471 | fips.place=fips.place[grepl(paste(place, collapse="|"), fips.place$PLACENAME), ]} 472 | else fips.place=fips.place[fips.place$PLACEFP %in% place,] 473 | place=fips.place[,3] 474 | place.name=fips.place[, 4] 475 | this.county.name=fips.place[, 7] 476 | if(length(place)>0){ 477 | results=rbind.fill(results, data.frame(state, state.name, county.name=this.county.name, place, place.name, stringsAsFactors=F))}} 478 | # check schools 479 | ## elementary 480 | if (!missing(school.district.elementary)){ 481 | fips.school.elementary=fips.school[fips.school$STATEFP==state & fips.school$TYPE=="Elementary",] 482 | if(is.character(school.district.elementary)) { 483 | fips.school.elementary=fips.school.elementary[grepl(paste(school.district.elementary, collapse="|"), fips.school.elementary$SDNAME), ]} 484 | else fips.school.elementary=fips.school.elementary[fips.school.elementary$LEA %in% school.district.elementary,] 485 | school.district.elementary=fips.school.elementary[,3] # fips code 486 | school.district.elementary.name=fips.school.elementary[, 4] # name 487 | school.district.elementary.type=fips.school.elementary[, 5] # type (elem, secondary, unified) 488 | if(length(school.district.elementary)>0){ 489 | results=rbind.fill(results, data.frame(state, state.name, school.district.elementary, school.district.elementary.name, school.district.elementary.type, stringsAsFactors=F))}} 490 | ## secondary 491 | if (!missing(school.district.secondary)){ 492 | fips.school.secondary=fips.school[fips.school$STATEFP==state & fips.school$TYPE=="Secondary",] 493 | if(is.character(school.district.secondary)) { 494 | fips.school.secondary=fips.school.secondary[grepl(paste(school.district.secondary, collapse="|"), fips.school.secondary$SDNAME), ]} 495 | else fips.school.secondary=fips.school.secondary[fips.school.secondary$LEA %in% school.district.secondary,] 496 | school.district.secondary=fips.school.secondary[,3] # fips code 497 | school.district.secondary.name=fips.school.secondary[, 4] # name 498 | school.district.secondary.type=fips.school.secondary[, 5] # type (elem, secondary, unified) 499 | if(length(school.district.secondary)>0){ 500 | results=rbind.fill(results, data.frame(state, state.name, school.district.secondary, school.district.secondary.name, school.district.secondary.type, stringsAsFactors=F))}} 501 | ## unified 502 | if (!missing(school.district.unified)){ 503 | fips.school.unified=fips.school[fips.school$STATEFP==state & fips.school$TYPE=="Unified",] 504 | if(is.character(school.district.unified)) { 505 | fips.school.unified=fips.school.unified[grepl(paste(school.district.unified, collapse="|"), fips.school.unified$SDNAME), ]} 506 | else fips.school.unified=fips.school.unified[fips.school.unified$LEA %in% school.district.unified,] 507 | school.district.unified=fips.school.unified[,3] # fips code 508 | school.district.unified.name=fips.school.unified[, 4] # name 509 | school.district.unified.type=fips.school.unified[, 5] # type (elem, secondary, unified) 510 | if(length(school.district.unified)>0){ 511 | results=rbind.fill(results, data.frame(state, state.name, school.district.unified, school.district.unified.name, school.district.unified.type, stringsAsFactors=F))}} 512 | ## any type 513 | if (!missing(school.district)){ 514 | fips.school.any=fips.school[fips.school$STATEFP==state,] 515 | if(is.character(school.district)) { 516 | fips.school.any=fips.school.any[grepl(paste(school.district, collapse="|"), fips.school.any$SDNAME), ]} 517 | else fips.school.any=fips.school.any[fips.school.any$LEA %in% school.district,] 518 | school.district=fips.school.any[,3] # fips code 519 | school.district.name=fips.school.any[, 4] # name 520 | school.district.type=fips.school.any[, 5] # type (elem, secondary, unified) 521 | if(length(school.district)>0){ 522 | results=rbind.fill(results, data.frame(state, state.name, school.district, school.district.name, school.district.type, stringsAsFactors=F))}} 523 | results 524 | } 525 | 526 | 527 | geo.make=function(us, region, division, state, county, county.subdivision, place, tract, 528 | block.group, msa, csa, necta, urban.area, congressional.district, state.legislative.district.upper, state.legislative.district.lower, puma, zip.code, american.indian.area, school.district.elementary, school.district.secondary, school.district.unified, combine=F, combine.term="aggregate", check=FALSE, key="auto") { 529 | .geo.unit.make=function(us, region, division, state, county, county.subdivision, place, tract, 530 | block.group, msa, csa, necta, urban.area, congressional.district, state.legislative.district.upper, state.legislative.district.lower, puma, zip.code, american.indian.area, school.district.elementary, school.district.secondary, school.district.unified) { 531 | geo.obj=NA 532 | nargs=nargs() 533 | ## geos with only one argument: sumlev 010, 020, 030, 350, 400, 860 534 | # sumlev 010 -- all US 535 | if (!missing(us) && (us==1 || us=="*" || us==TRUE)) { 536 | if (nargs>1) {warning("entire U.S. selected; no other geographic arguments allowed;\n returning NA") 537 | return(NA)} 538 | if (us==TRUE) us=1 539 | geo.obj=new(Class="geo", api.for=list("us"=us), api.in=list(), name="US", sumlev=10) 540 | return(geo.obj) 541 | } 542 | # sumlev 020 -- region 543 | if (!missing(region)) { 544 | if (nargs>1) {warning("region selected; ; no other geographic arguments allowed;\n returning NA") 545 | return(NA)} 546 | geo.obj=new(Class="geo", api.for=list("region"=region), api.in=list(), name=paste("Region ", region, sep=""), sumlev=20) 547 | return(geo.obj) 548 | } 549 | # sumlev 030 -- division 550 | if (!missing(division)) { 551 | if (nargs>1) {warning("division selected; no other geographic arguments allowed;\n returning NA") 552 | return(NA)} 553 | geo.obj=new(Class="geo", api.for=list("division"=division), api.in=list(), name=paste("Division ", division, sep=""), sumlev=30) 554 | return(geo.obj) 555 | } 556 | # sumlev 250 -- american indian area/alaska native area/hawaiian home land 557 | ## check for american indian area names and convert to codes 558 | if (!missing(american.indian.area) && is.character(american.indian.area) && american.indian.area !="*"){ 559 | american.indian.area=fips.american.indian.area[grepl(paste("^", american.indian.area, sep=""), fips.american.indian.area$American.Indian.Area.Name), 1] 560 | if (length(american.indian.area)>1){ 561 | warning("More than one American Indian area/Alaska Native area/Hawaiian Home Land name matches search string;\n returning NA;\n Perhaps try 'geo.lookup()...?") 562 | return(NA)} 563 | if (length(american.indian.area)==0){ 564 | warning("No American Indian area/Alaska Native area/Hawaiian Home Land name matches search string;\n returning NA;\n Perhaps try 'geo.lookup()...?") 565 | return(NA)} 566 | } 567 | ## deal with wildcards 568 | if (hasArg(american.indian.area) && american.indian.area!="*") 569 | american.indian.area.name=fips.american.indian.area[fips.american.indian.area$American.Indian.Area.Code==american.indian.area, 2] 570 | else american.indian.area.name="All American Indian/Alaska Native/Hawaiian Home Land areas" # later, not used unless hasArg(county) 571 | ## make geo for sumlev 250 572 | if (!missing(american.indian.area)) { 573 | if (nargs>1) {warning("american.indian.area selected; \n no other geographic arguments allowed;\n returning NA") 574 | return(NA)} 575 | geo.obj=new(Class="geo", api.for=list("american+indian+area/alaska+native+area/hawaiian+home+land"=american.indian.area), api.in=list(), name=american.indian.area.name, sumlev=250) 576 | return(geo.obj) 577 | } 578 | # sumlev 310 -- metropolitan statistical area/micropolitan statistical area **NO STATE** 579 | if (!missing(msa) && missing(state)) { 580 | if (nargs>1) {warning("msa selected; ignoring all other geographic arguments")} 581 | geo.obj=new(Class="geo", api.for=list("metropolitan+statistical+area/micropolitan+statistical+area"=msa), api.in=list(), name=paste("MSA ", msa, sep=""), sumlev=310) 582 | return(geo.obj) 583 | } 584 | # sumlev 330 -- combined statistical area **NO STATE** 585 | if (!missing(csa) && missing(state)) { 586 | if (nargs>1) {warning("csa selected; ignoring all other geographic arguments")} 587 | geo.obj=new(Class="geo", api.for=list("combined+statistical+area"=csa), api.in=list(), name=paste("CSA ", csa, sep=""), sumlev=330) 588 | return(geo.obj) 589 | } 590 | # sumlev 350 -- new england city and town area 591 | if (!missing(necta)) { 592 | if (nargs>1) {warning("necta selected; no other geographic arguments allowed;\n returning NA") 593 | return(NA)} 594 | geo.obj=new(Class="geo", api.for=list("new+england+city+and+town+area"=necta), api.in=list(), name=paste("NECTA ", necta, sep=""), sumlev=350) 595 | return(geo.obj) 596 | } 597 | # sumlev 400 -- urban area 598 | if (!missing(urban.area)) { 599 | if (nargs>1) {warning("urban.area selected; no other geographic arguments allowed;\n returning NA") 600 | return(NA)} 601 | geo.obj=new(Class="geo", api.for=list("urban+area"=urban.area), api.in=list(), name=paste("Urban Area ", urban.area, sep=""), sumlev=400) 602 | return(geo.obj) 603 | } 604 | # sumlev 860 -- zip.code 605 | if (!missing(zip.code)) { 606 | if (nargs>1) {warning("zip.code selected, no other geographic arguments allowed;\n returning NA") 607 | return(NA)} 608 | geo.obj=new(Class="geo", api.for=list("zip+code+tabulation+area"=zip.code), api.in=list(), name=paste("Zip Code Tabulation Area ", zip.code, sep=""), sumlev=860) 609 | return(geo.obj) 610 | } 611 | # all other geos need a valid state 612 | if(missing(state)) { 613 | warning("state required") 614 | return(NA)} 615 | # check for state abbreviations/text names and convert to codes 616 | if (is.character(state) && state !="*"){ 617 | if (nchar(state)==2) state=fips.state[fips.state$STUSAB==state,1] 618 | else state=fips.state[grep(paste("^", state, sep=""), fips.state$STATE_NAME),1] 619 | if (length(state)==0) { 620 | warning("No valid state names match search string;\n returning NA") 621 | return(NA)} 622 | if (length(state)>1) { 623 | warning("More than one state name matches search string;\n returning NA;\n Perhaps try 'geo.lookup()...?") 624 | return(NA)} 625 | } 626 | # check for county names and convert to codes 627 | if (!missing(county) && is.character(county) && county !="*"){ 628 | county=fips.county[grepl(paste("^", county, sep=""), fips.county$County.Name) & (fips.county$State.ANSI==state), 3] 629 | if (length(county)>1){ 630 | warning("More than one county name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 631 | return(NA)} 632 | if (length(county)==0){ 633 | warning("No county name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 634 | return(NA)} 635 | } 636 | # check for county subdivision names and convert to codes 637 | if (!missing(county.subdivision) && is.character(county.subdivision) && county.subdivision !="*"){ 638 | county.subdivision=fips.county.subdivision[grepl(paste("^", county.subdivision, sep=""), fips.county.subdivision$COUSUBNAME) & (fips.county.subdivision$STATEFP==state) , 5] 639 | if (length(county.subdivision)>1){ 640 | warning("More than one county subdivision name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 641 | return(NA)} 642 | if (length(county.subdivision)==0){ 643 | warning("No county subdivision name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 644 | return(NA)} 645 | } 646 | # check for place names and convert to codes 647 | if (!missing(place) && is.character(place) && place !="*"){ 648 | place=fips.place[grepl(paste("^", place, sep=""), fips.place$PLACENAME) & (fips.place$STATEFP==state), 3] 649 | if (length(place)>1){ 650 | if(isTRUE(all.equal(max(place),min(place))) 651 | && isTRUE(all.equal(max(place), min(place)))) # i.e., all match same place # 652 | { 653 | place=place[1] 654 | } else { 655 | warning("More than one place name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 656 | return(NA)} 657 | } 658 | if (length(place)==0){ 659 | warning("No place name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 660 | return(NA)} 661 | } 662 | # check for school district names and convert to codes 663 | ## elementary 664 | if (!missing(school.district.elementary) && is.character(school.district.elementary) && school.district.elementary !="*"){ 665 | school.district.elementary=fips.school[grepl(paste("^", school.district.elementary, sep=""), fips.school$SDNAME) & (fips.school$STATEFP==state) & (fips.school$TYPE=="Elementary"), 3] 666 | if (length(school.district.elementary)>1){ 667 | warning("More than one elementary school district name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 668 | return(NA)} 669 | if (length(school.district.elementary)==0){ 670 | warning("No elementary school district name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 671 | return(NA)} 672 | } 673 | ## secondary 674 | if (!missing(school.district.secondary) && is.character(school.district.secondary) && school.district.secondary !="*"){ 675 | school.district.secondary=fips.school[grepl(paste("^", school.district.secondary, sep=""), fips.school$SDNAME) & (fips.school$STATEFP==state) & (fips.school$TYPE=="Secondary"), 3] 676 | if (length(school.district.secondary)>1){ 677 | warning("More than one secondary school district name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 678 | return(NA)} 679 | if (length(school.district.secondary)==0){ 680 | warning("No secondary school district name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 681 | return(NA)} 682 | } 683 | ## unified 684 | if (!missing(school.district.unified) && is.character(school.district.unified) && school.district.unified !="*"){ 685 | school.district.unified=fips.school[grepl(paste("^", school.district.unified, sep=""), fips.school$SDNAME) & (fips.school$STATEFP==state) & (fips.school$TYPE=="Unified"), 3] 686 | if (length(school.district.unified)>1){ 687 | warning("More than one unified school district name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 688 | return(NA)} 689 | if (length(school.district.unified)==0){ 690 | warning("No unified school district name matches search string in state ", state,";\n returning NA;\n Perhaps try 'geo.lookup()...?") 691 | return(NA)} 692 | } 693 | # deal with names for wildcards 694 | if (state != "*") state.name=fips.state[fips.state$STATE==state,3] else state.name="All states" 695 | if (hasArg(county) && county !="*") 696 | county.name=fips.county[fips.county$County.ANSI==county & fips.county$State.ANSI==state, 4] 697 | else county.name="All counties" # later, not used unless hasArg(county) 698 | if (hasArg(place) && place !="*") { 699 | place.name=fips.place[fips.place$PLACEFP==place & 700 | fips.place$STATEFP==state, 4] 701 | if(length(place.name)>1) place.name=place.name[1]} 702 | else place.name="All places" # later, not used unless hasArg(place) 703 | if (hasArg(county.subdivision) && county.subdivision !="*") 704 | subdivision.name=fips.county.subdivision[fips.county.subdivision$COUSUBFP==county.subdivision & fips.county.subdivision$STATEFP==state, 6] 705 | else subdivision.name="All subdivisions" # later, not used unless hasArg(county.subdivision) 706 | if (hasArg(school.district.elementary) && school.district.elementary!="*") 707 | school.district.elementary.name=fips.school[fips.school$LEA==school.district.elementary & fips.school$STATEFP==state, 4] 708 | else school.district.elementary.name="All elementary school districts" # later, not used unless hasArg(county) 709 | if (hasArg(school.district.secondary) && school.district.secondary!="*") 710 | school.district.secondary.name=fips.school[fips.school$LEA==school.district.secondary & fips.school$STATEFP==state, 4] 711 | else school.district.secondary.name="All secondary school districts" # later, not used unless hasArg(county) 712 | if (hasArg(school.district.unified) && school.district.unified!="*") 713 | school.district.unified.name=fips.school[fips.school$LEA==school.district.unified & fips.school$STATEFP==state, 4] 714 | else school.district.unified.name="All unified school districts" # later, not used unless hasArg(county) 715 | # done with looking up names and codes 716 | # sumlev 40 (state) 717 | if (nargs==1 && hasArg(state)) 718 | geo.obj=new(Class="geo", api.for=list(state=state), api.in=list(), name=state.name, sumlev=40) 719 | # sumlev 50 (state-county) 720 | if (nargs==2 && hasArg(county)) 721 | geo.obj=new(Class="geo", api.for=list(county=county), api.in=list(state=state), name=paste(county.name, state.name, sep=", "), sumlev=50) 722 | # sumlev 160 (state-place) -- only sumlev with place 723 | if (hasArg(place)) { 724 | if(nargs>2) warning("Using sumlev 160 (state-place)\n Other levels not supported by census api at this time") 725 | geo.obj=new(Class="geo", api.for=list(place=place), api.in=list(state=state), name=paste(place.name, state.name, sep=", "), sumlev=160) } 726 | # sumlev 60 (state-county-county.subdivision) 727 | if (nargs==3 && hasArg(county) && hasArg(county.subdivision)) 728 | geo.obj=new(Class="geo", api.for=list("county+subdivision"=county.subdivision), api.in=list(state=state, county=county), name=paste(subdivision.name, county.name, state.name, sep=", "), sumlev=60) 729 | # sumlev 140 (state-county-tract) 730 | if (nargs==3 && hasArg(county) && hasArg(tract)) 731 | geo.obj=new(Class="geo", api.for=list(tract=tract), api.in=list(state=state, county=county), name=paste("Tract ", tract, ", ", county.name, ", ", state.name, sep=""), sumlev=140) 732 | # sumlev 150 (state-county-tract-block.group) 733 | if (nargs==4 && hasArg(county) && hasArg(tract) && hasArg(block.group)) 734 | geo.obj=new(Class="geo", api.for=list("block+group"=block.group), api.in=list(state=state, county=county, tract=tract), name=paste("Tract ", tract, ", Blockgroup ", block.group, ", ", county.name, ", ", state.name, sep=""), sumlev=150) 735 | # sumlev 320 (state-msa) 736 | if (nargs==2 && hasArg(msa)) 737 | geo.obj=new(Class="geo", api.for=list("metropolitan+statistical+area/micropolitan+statistical+area"=msa), api.in=list(state=state), name=paste("MSA ", msa, ", ", state.name, sep=""), sumlev=320) 738 | # sumlev 340 (state-csa) 739 | if (nargs==2 && hasArg(csa)) 740 | geo.obj=new(Class="geo", api.for=list("combined+statistical+area"=csa), api.in=list(state=state), name=paste("CSA ", csa, ", ", state.name, sep=""), sumlev=340) 741 | # sumlev 500 (state-congressional.district) 742 | if (nargs==2 && hasArg(congressional.district)) 743 | geo.obj=new(Class="geo", api.for=list("congressional+district"=congressional.district), api.in=list(state=state), name=paste("Congressional District ", congressional.district, ", ", state.name, sep=""), sumlev=500) 744 | # sumlev 510 (state-congressional.district-county) 745 | if (nargs==3 && hasArg(county) && hasArg(congressional.district)) 746 | geo.obj=new(Class="geo", api.for=list("county"=county), api.in=list(state=state, "congressional+district"=congressional.district), name=paste(county.name, ", Congressional District ", congressional.district, ", ", state.name, sep=""), sumlev=510) 747 | # sumlev 610 (state-state.leg.upper) 748 | if (nargs==2 && hasArg(state.legislative.district.upper)) { 749 | # turn to string exactly three characters long 750 | if (state.legislative.district.upper !="*") state.legislative.district.upper=str_sub(paste("000",state.legislative.district.upper,sep=""), -3,-1) 751 | geo.obj=new(Class="geo", api.for=list("state+legislative+district+(upper+chamber)"=state.legislative.district.upper), api.in=list(state=state), name=paste("State Legislative District (upper chamber) ", state.legislative.district.upper, ", ", state.name, sep=""), sumlev=610)} 752 | # sumlev 620 (state-state.leg.lower) 753 | if (nargs==2 && hasArg(state.legislative.district.lower)) { 754 | # turn to string exactly three characters long 755 | if (state.legislative.district.lower !="*") state.legislative.district.lower=str_sub(paste("000",state.legislative.district.lower,sep=""), -3,-1) 756 | geo.obj=new(Class="geo", api.for=list("state+legislative+district+(lower+chamber)"=state.legislative.district.lower), api.in=list(state=state), name=paste("State Legislative District (lower chamber) ", state.legislative.district.lower, ", ", state.name, sep=""), sumlev=620)} 757 | # sumlev 795 (state-puma) 758 | if (nargs==2 && hasArg(puma)) 759 | geo.obj=new(Class="geo", api.for=list("public+use+microdata+area"=puma), api.in=list(state=state), name=paste("Public Use Microdata Area ", puma, ", ", state.name, sep=""), sumlev=795) 760 | # sumlev 950 (state-school.elementary) 761 | if (nargs==2 && hasArg(school.district.elementary)) 762 | geo.obj=new(Class="geo", api.for=list("school+district+(elementary)"=school.district.elementary), api.in=list(state=state), name=paste(school.district.elementary.name, ", ", state.name, sep=""), sumlev=950) 763 | # sumlev 960 (state-school.secondary) 764 | if (nargs==2 && hasArg(school.district.secondary)) 765 | geo.obj=new(Class="geo", api.for=list("school+district+(secondary)"=school.district.secondary), api.in=list(state=state), name=paste(school.district.secondary.name, ", ", state.name, sep=""), sumlev=960) 766 | # sumlev 970 (state-school.unified) 767 | if (nargs==2 && hasArg(school.district.unified)) 768 | geo.obj=new(Class="geo", api.for=list("school+district+(unified)"=school.district.unified), api.in=list(state=state), name=paste(school.district.unified.name, ", ", state.name, sep=""), sumlev=970) 769 | # fail if still no match 770 | if (!is.geo(geo.obj)) { 771 | warning("No valid geography from these arguments; returning NA\n Perhaps add or drop levels from this request?") 772 | } 773 | geo.obj 774 | } 775 | ## after here is actual function to recur through more complex 776 | ## requests 777 | # recycle! 778 | if (key=="auto" && check==T) load(system.file("extdata/key.rda", package="acs")) 779 | arglist=as.list(environment()) 780 | missing.args=unlist(lapply(arglist, is.symbol)) 781 | arglist=arglist[!missing.args] 782 | arglist=arglist[names(arglist)!="combine"] 783 | arglist=arglist[names(arglist)!="combine.term"] 784 | arglist=arglist[names(arglist)!="key"] 785 | arglist=arglist[names(arglist)!="check"] 786 | max.length=max(sapply(arglist, length)) 787 | arglist=lapply(arglist, rep, length=max.length) 788 | if(max.length==1) { 789 | geo.obj=do.call(.geo.unit.make, arglist) 790 | geo.set.obj=new(Class="geo.set", geo.list=list(geo.obj), combine=combine, combine.term=combine.term) 791 | } else { 792 | geo.a=do.call(.geo.unit.make, lapply(arglist, head, 1)) 793 | geo.b=do.call(geo.make, lapply(arglist, tail, -1)) 794 | geo.set.obj=geo.a+geo.b 795 | } 796 | if(is.geo.set(geo.set.obj)) { 797 | geo.set.obj@combine=combine 798 | geo.set.obj@combine.term=combine.term} 799 | if (check==T){ 800 | for (i in 1:length(geo.set.obj)){ 801 | cat(paste("Testing geography item ", i,": ", name(geo.list(geo.set.obj[i])), " .... ", sep="")) 802 | obj.test=acs.fetch(endyear=2014, geography=geo.set.obj[i], key=key, variable="B01001_001", lookup=F) 803 | cat("OK.\n") 804 | } 805 | } 806 | geo.set.obj 807 | } 808 | 809 | setClass(Class="acs.lookup", representation = 810 | representation(endyear="numeric", span="numeric", args="list", results="data.frame")) 811 | if (!isGeneric("endyear")) { 812 | setGeneric("endyear", def=function(object){standardGeneric("endyear")})}else{} 813 | setMethod("endyear", "acs.lookup", function(object) object@endyear) 814 | if (!isGeneric("span")) { 815 | setGeneric("span", def=function(object){standardGeneric("span")})}else{} 816 | setMethod("span", "acs.lookup", function(object) object@span) 817 | if (!isGeneric("results")) { 818 | setGeneric("results", def=function(object){standardGeneric("results")})}else{} 819 | setMethod("results", "acs.lookup", function(object) object@results) 820 | # could add other slots, plus "show" method 821 | 822 | setMethod("show", "acs.lookup", function(object) { 823 | cat("An object of class \"acs.lookup\"\n") 824 | cat("endyear=", endyear(object)," ; span=", span(object), "\n\n") 825 | cat("results:\n") 826 | print(results(object)) 827 | cat("\n") 828 | }) 829 | 830 | 831 | is.acs.lookup=function(object){ 832 | if (class(object)=="acs.lookup") {TRUE} 833 | else {FALSE}} 834 | 835 | setMethod("+", signature(e1 = "acs.lookup", e2 = "acs.lookup"), function(e1, e2) { 836 | e3=rbind(e1@results, e2@results) 837 | new(Class="acs.lookup", endyear=e1@endyear, args=list(e1@args, e2@args), span=e1@span, results=e3)}) 838 | 839 | setMethod("c", signature(x = "acs.lookup" ), function(x, y, ..., 840 | recursive = FALSE) { 841 | if(missing(y)) x 842 | else x + c(y, ...)}) 843 | 844 | setMethod(f="[", signature="acs.lookup", definition=function(x,i,j,...,drop=FALSE){ 845 | if (missing(i)) i=j 846 | if (missing(j)) j=i 847 | new(Class="acs.lookup", endyear=x@endyear, args=x@args, span=x@span, results=x@results[i,])}) 848 | 849 | acs.lookup=function(endyear, span=5, dataset="acs", keyword, table.name, table.number, case.sensitive=T) { 850 | arglist=as.list(environment()) 851 | # next line is a kludge/patch to deal with problem with XML tables after 2015 852 | if (endyear>2015) {warning(paste("acs.lookup for endyear>2015: using 2015 variable codes to access ", endyear," data.\n (See ?acs.lookup for details)", sep="")) 853 | endyear=2015} 854 | if (!missing(table.number)){ 855 | if (!missing(table.name)) warning("Cannot specify both table.name and table.number; using table.number") 856 | # in future?: consider changing next line to table.name="", and let table.number drive the train 857 | if(endyear!=1990){table.name=paste(table.number, ".", sep="")} else {table.name=table.number} 858 | } 859 | if (missing(table.name) && missing(keyword)) { 860 | warning("No search terms provided; returning NA") 861 | return(NA)} 862 | if (!missing(keyword) && sum(unlist(lapply(X=keyword, FUN=grepl, "Margin Of Error For", ignore.case=T)))>0) { 863 | warning("'keyword' marching string 'Margin Of Error For' not permitted\n Returning NA") 864 | return(NA)} 865 | if (!case.sensitive) { 866 | if (!missing(table.name)) table.name=tolower(table.name) 867 | if (!missing(keyword)) keyword=tolower(keyword)} 868 | else {insensitive=F} 869 | # find correct XML variables 870 | # new way / updated for v2.0 871 | # doc.string is xml file name when saved locally or on eglenn archive 872 | # doc.url is path to census file for XML variables 873 | if(dataset=="acs") { 874 | doc.string=paste(dataset,"_", span,"yr_", endyear,"_var.xml.gz", sep="") 875 | doc.url=paste("https://api.census.gov/data/", endyear,"/acs/acs",span,"/subject/variables.xml", sep="") 876 | # next line to correct change in url for variables 2016 and later 877 | if(span==3){ 878 | doc.url=paste("https://api.census.gov/data/", endyear,"/acs",span,"/variables.xml", sep="") 879 | } 880 | if(endyear==2009){ 881 | doc.url=paste("https://api.census.gov/data/", endyear,"/acs",span,"/variables.xml", sep="") 882 | } 883 | if(endyear<2015 && span==1){ 884 | doc.url=paste("https://api.census.gov/data/", endyear,"/acs",span,"/variables.xml", sep="") 885 | } 886 | } 887 | if(dataset=="sf1" | dataset=="sf3"){ 888 | doc.string=paste(dataset,"_", endyear,".xml.gz", sep="") 889 | doc.url=paste("https://api.census.gov/data/", endyear, "/", dataset, "/variables.xml", sep="") 890 | span=0 891 | } 892 | # first look for XML table internally 893 | if(file.exists(system.file(paste("extdata/", doc.string, sep=""), package="acs"))) 894 | { 895 | doc=xmlInternalTreeParse(system.file(paste("extdata/", doc.string, sep=""), package="acs")) 896 | } 897 | # next check online at census site 898 | # needed to comment this out in 2.1.4 -- was causing trouble! 899 | # else if(!http_error(doc.url)) 900 | # { 901 | # temp <- GET(doc.url) 902 | # doc=xmlInternalTreeParse(temp) 903 | # } 904 | # finally, check personal eglenn archive 905 | else if(!http_error(paste("http://web.mit.edu/eglenn/www/acs/acs-variables/", doc.string, sep=""))) 906 | { 907 | # since only here is issues, give some advice 908 | warning(paste("temporarily downloading and using archived XML variable lookup files;\n since this is *much* slower, recommend running\n acs.tables.install()"), sep="") 909 | doc.download=tempfile() 910 | download.file(url=paste("http://web.mit.edu/eglenn/www/acs/acs-variables/", doc.string, sep=""), destfile=doc.download) 911 | doc=xmlInternalTreeParse(doc.download) 912 | unlink(doc.download) 913 | } 914 | # if found nowhere, issue warning and return NA 915 | else { 916 | warning("As of the date of this version of the acs package\n no variable lookup tables were available\n for this dataset/endyear/span combination;\n perhaps try a different combination...?\n Returning NA;") 917 | return(NA) 918 | } 919 | 920 | if (!missing(keyword)){ 921 | if (!case.sensitive) {str.a="contains(translate(@label, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'"} 922 | else {str.a="contains(@label, '"} 923 | str.b=paste(str.a,keyword,"')", sep="") 924 | str.c=paste(str.b, collapse=" and ") 925 | keyword=str.c 926 | } else {keyword=""} 927 | 928 | if (!missing(table.name)) { 929 | if (!case.sensitive) {str.a="contains(translate(@concept, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'"} 930 | else {str.a="contains(@concept, '"} 931 | str.b=paste(str.a,table.name,"')", sep="") 932 | str.c=paste(str.b, collapse=" and ") 933 | table.name=str.c 934 | if(endyear==1990){table.name=gsub(table.name, pattern="@concept", replacement="@xml:id")} 935 | } else {table.name=""} 936 | 937 | ## # add in stanza using table number for 2016+ / broken! 938 | ## if (endyear>2015 && !missing(table.number)) { 939 | ## if (!case.sensitive) {str.a="contains(translate(@group, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'"} 940 | ## else {str.a="contains(@group, '"} 941 | ## str.b=paste(str.a,table.number,"')", sep="") 942 | ## str.c=paste(str.b, collapse=" and ") 943 | ## table.name=str.c 944 | ## } 945 | 946 | # add in stanza using table number for 2016+ NEW 947 | if (endyear>2015 && !missing(table.number)) { 948 | if (!case.sensitive) { 949 | table.number=toupper(table.number) 950 | } 951 | str.a="@group='" 952 | str.b=paste(str.a,table.number,"'", sep="") 953 | str.c=paste(str.b, collapse=" or ") 954 | table.name=str.c 955 | } 956 | 957 | # add in stanza using table numbers for <2016 NEW 958 | if (endyear<2016 && !missing(table.number)) { 959 | if (!case.sensitive) { 960 | table.number=toupper(table.number) 961 | } 962 | str.a="contains(@concept, '" 963 | str.b=paste(str.a,table.number,".')", sep="") 964 | str.c=paste(str.b, collapse=" or ") 965 | table.name=str.c 966 | } 967 | 968 | if(identical(table.name, "")){ 969 | STRING=paste0("//ns:var[", keyword, "]") 970 | } 971 | else if(identical(keyword,"")){ 972 | STRING=paste0("//ns:var[", table.name, "]") 973 | } 974 | else { 975 | STRING=paste0("//ns:var[", paste(table.name, keyword, sep=" and "), "]") 976 | } 977 | # get variable codegs ("id") 978 | names=suppressWarnings(xpathSApply(doc, STRING, namespaces="ns", xmlGetAttr, "xml:id")) 979 | names=gsub("!!!!"," ",names) 980 | names=gsub("!!"," ",names) 981 | my.index=order(names) # added for 2012, since data not sorted 982 | names=names[my.index] # added for 2012, since data not sorted 983 | names=gsub("E$", "", names) # remove "E" from variable name 984 | if(dataset=="acs" && length(names)>0){ 985 | if(endyear>2015) {names=names[seq(1,length(names),4)]} # only every forth (no EA,MA,M) 986 | else {names=names[seq(1,length(names),2)]}} # only want every other 987 | 988 | # get table names 989 | table.names=suppressWarnings(xpathSApply(doc, STRING, namespaces="ns", xmlGetAttr, "concept")) 990 | table.names=gsub("!!!!"," ",table.names) 991 | table.names=gsub("!!"," ",table.names) 992 | table.numbers=regmatches(table.names, m=regexpr(table.names, pattern="^.*\\.")) # find table numbers 993 | if(endyear==1990){ 994 | table.numbers=substr(names, 1, 5) 995 | table.numbers=gsub(x=table.numbers, pattern="0$", replacement="") 996 | table.numbers=gsub(x=table.numbers, pattern="$", replacement=".") 997 | } 998 | if(endyear>2015){ 999 | table.numbers=suppressWarnings(xpathSApply(doc, STRING, namespaces="ns", xmlGetAttr, "group")) 1000 | } 1001 | table.names=gsub(x=table.names, pattern="^.*\\. ", replacement="") # remove table numbers from names 1002 | table.names=gsub(x=table.names, pattern="* \\[.*\\]$", replacement="") # remove bracketed variable counts from SF1/SF3 tables 1003 | table.names=table.names[my.index] # added for 2012, since data not sorted 1004 | if(dataset=="acs" && length(table.names)>0) {table.names=table.names[seq(1,length(table.names),2)]} # only want every other 1005 | 1006 | # get table numbers 1007 | if(endyear<2015){table.numbers=substr(table.numbers, 1, unlist(lapply(table.numbers, nchar))-1)} # remove trailing period 1008 | if(dataset=="acs"){ # sf1/sf3 table.numbers have already been reordered! 1009 | table.numbers=table.numbers[my.index] 1010 | } # added for 2012, since data not sorted 1011 | if(dataset=="acs" && length(table.numbers)>0) { 1012 | if(endyear>2015){table.numbers=table.numbers[seq(1,length(table.numbers),4)]} # only want every fourth 1013 | else {table.numbers=table.numbers[seq(1,length(table.numbers),2)]}} # only want every other 1014 | 1015 | # get variable names 1016 | values=suppressWarnings(xpathSApply(doc, STRING, namespaces="ns", xmlGetAttr, "label")) 1017 | values=gsub("!!!!"," ",values) 1018 | values=gsub("!!"," ",values) 1019 | values=gsub(x=values, pattern="*\\[.*\\]", replacement=":") # remove bracketed variable counts from SF1/SF3 tables 1020 | values=values[my.index] # added for 2012, since data not sorted 1021 | if(dataset=="acs" && length(values)>0) { 1022 | if(endyear>2015){values=values[seq(1,length(values),4)]} # every fourth 1023 | else {values=values[seq(1,length(values),2)]}} # only want every other 1024 | 1025 | if (length(names)==0){ 1026 | warning("Sorry, no tables/keyword meets your search.\n Suggestions:\n try with 'case.sensitive=F',\n remove search terms,\n change 'keyword' to 'table.name' in search (or vice-versa)") 1027 | return(NA)} 1028 | free(doc) 1029 | rm(doc) 1030 | gc() 1031 | new(Class="acs.lookup", endyear=endyear, span=span, args=arglist, 1032 | results=data.frame(variable.code=names, 1033 | table.number=table.numbers, table.name=table.names, variable.name=values, 1034 | stringsAsFactors=F)) 1035 | } 1036 | 1037 | read.acs=function(filename, endyear="auto", span="auto", 1038 | col.names="auto", acs.units="auto", geocols="auto", skip="auto") 1039 | { 1040 | # Attempt to automatically determine endyear from filename if 1041 | # necessary. 1042 | 1043 | if (endyear=="auto") 1044 | { # try to guess end year from filename 1045 | endyear=2000+as.integer(str_extract(str_extract(filename, "ACS_[0-9][0-9]_"), "[0-9][0-9]")) 1046 | if(is.na(endyear)) endyear=as.integer(str_extract(filename, "200[0-9]")) 1047 | if (is.na(endyear) | endyear<2000 | endyear>2012) 1048 | { 1049 | warning("Can't determine endyear from filename;\nplease set manually before proceeding.\nSetting endyear to default of 2010.\nOperations with this acs object may not be reliable...") 1050 | endyear=2010} 1051 | else { 1052 | warning("Guessing endyear of " , endyear, " based on filename...", call.=F) 1053 | } 1054 | } 1055 | # Attempt to automatically determine span from filename if 1056 | # necessary. 1057 | 1058 | if (span=="auto") 1059 | { 1060 | span=as.integer(str_extract(str_extract(filename, "_[0-9]YR"), "[0-9]")) 1061 | if (is.na(span)) span=as.integer(substr(str_extract(filename, "[0-9]yr"),1,1)) 1062 | if (is.na(span) | span>5) { 1063 | warning("Can't determine span from filename;\nplease set manually before proceeding.\nSetting span to default of 1.\nOperations with this acs object may not be reliable...") 1064 | span=1 1065 | } 1066 | else 1067 | { 1068 | warning("Guessing span of ", span, " based on filename...", call.=F) 1069 | } 1070 | } 1071 | span=as.integer(span) 1072 | endyear=as.integer(endyear) 1073 | if (span > 5 | span < 1){ 1074 | warning("Span out of range; returning NA") 1075 | return(NA)} 1076 | # set geocols 1077 | if (identical(geocols, "auto")) 1078 | {geocols=3:1 1079 | warning("Using first three columns as geographic headers.", call.=F) 1080 | } 1081 | 1082 | if (identical(str_sub(filename, start=-4), ".zip")) { 1083 | zip.filename=filename 1084 | contents=unzip(zip.filename, list=T) 1085 | acs.filename=grep(pattern="with_ann.csv", x=contents[[1]], value=T) 1086 | if(length(acs.filename)==0) 1087 | acs.filename=grep(pattern="[0-9].csv", x=contents[[1]], value=T) 1088 | make.con=function(){unz(description=zip.filename, filename=acs.filename) 1089 | } 1090 | } else {make.con=function(){file(description=filename) 1091 | } 1092 | } 1093 | # figure out how many rows to skip -- only call if skip="auto" 1094 | figure.skip=function(){ 1095 | con=make.con() 1096 | open(con) 1097 | i=0 1098 | while(str_sub(scan(con, what="", nlines=1, quiet=T), end=1)[1]==","){ 1099 | i=i+1 1100 | } 1101 | close(con) 1102 | i+1 # need to add one more to skip extra column header; most ACS files have two rows for headers 1103 | } 1104 | if (identical(skip, "auto")){ 1105 | skip=figure.skip() 1106 | } 1107 | 1108 | # figure out column names based on headers 1109 | get.colnames=function(geocols, skip){ 1110 | con=make.con() 1111 | open(con) 1112 | headers=read.csv(con, nrows=skip+1, header=F) # add one to include "header" row 1113 | headers=headers[,-geocols] 1114 | headers=apply(headers, FUN="paste", MARGIN=2, collapse=".") 1115 | headers=headers[seq(1,length(headers),2)] 1116 | close(con) 1117 | headers 1118 | } 1119 | if (identical(col.names, "auto")) { 1120 | col.names=get.colnames(geocols, skip) 1121 | } 1122 | # helper function to read and clean data 1123 | get.acs=function(geocols, skip) { 1124 | con=make.con() 1125 | open(con) 1126 | in.data=read.csv(con, skip=skip, na.strings=c("-", "**", 1127 | "***", "(X)", "N"), stringsAsFactors=F) 1128 | # trick to get geocols to be first columns 1129 | datacols=1:length(in.data) 1130 | datacols=datacols[-geocols] 1131 | in.data=in.data[,c(geocols,datacols)] 1132 | in.data[in.data=="*****"]=0 1133 | in.data[in.data=="-999999999"]=NA 1134 | in.data[in.data=="-888888888"]=NA 1135 | in.data[in.data=="-666666666"]=NA 1136 | in.data[in.data=="-555555555"]=0 1137 | in.data[in.data=="-333333333"]=NA 1138 | in.data[in.data=="-222222222"]=NA 1139 | for (i in (length(geocols)+1):length(in.data)) { 1140 | in.data[[i]]=gsub(",", "", in.data[[i]]) 1141 | in.data[[i]]=as.numeric(in.data[[i]]) 1142 | } 1143 | colnames(in.data)[-geocols]=col.names 1144 | close(con) 1145 | in.data 1146 | } 1147 | 1148 | in.data=get.acs(geocols=geocols, skip=skip) 1149 | acs.colnames=unname(col.names) 1150 | # acs.colnames=sub(colnames(in.data[seq((length(geocols)+1),length(in.data),2)]), pattern="..Estimate.", replacement="") 1151 | # create new acs object 1152 | if (acs.units=="auto") { 1153 | # try to guess variable types from filename 1154 | acs.units=.acs.identify.units(acs.colnames) 1155 | } 1156 | acs.units=factor(acs.units, levels=.acs.unit.levels) 1157 | acs.obj=new(Class="acs", 1158 | endyear=endyear, 1159 | span=span, 1160 | geography=as.data.frame(in.data[,1:length(geocols)]), 1161 | acs.colnames=acs.colnames, 1162 | acs.units=acs.units, 1163 | currency.year=endyear, 1164 | standard.error=as.matrix(in.data[,seq((length(geocols)+2),length(in.data), 2)]), 1165 | modified=F, 1166 | estimate=as.matrix(in.data[,seq((length(geocols)+1),length(in.data), 2)] 1167 | ) 1168 | ) 1169 | 1170 | # convert 90% MOE into standard error, correct for 2005 flaw 1171 | if (endyear(acs.obj)<=2005) 1172 | acs.obj@standard.error=acs.obj@standard.error/1.65 1173 | else 1174 | acs.obj@standard.error=acs.obj@standard.error/1.645 1175 | acs.obj=.acs.dimnames(acs.obj) 1176 | acs.obj 1177 | } 1178 | 1179 | acs.fetch=function(endyear, span=5, geography, table.name, 1180 | table.number, variable, keyword, dataset="acs", key, col.names="auto", ...) 1181 | { 1182 | var.max=40 # most var for acs call; keep even; 1183 | # check some basic stuff about arguments 1184 | if (missing(key)){ 1185 | if (file_test("-f", system.file("extdata/key.rda", package="acs"))) { 1186 | load(system.file("extdata/key.rda", package="acs")) 1187 | } else { 1188 | warning("'key' required to access Census API site for download;\n See http://www.census.gov/developers/ to request a key\n and/or use 'key=' (or run 'api.key.install()') to avoid this error.") 1189 | return(NA) } 1190 | } 1191 | if (missing(endyear)) { 1192 | warning("No endyear provided\n As of version 2.0, endyear must be explicit.\n Returning NA.") 1193 | return(NA) 1194 | } 1195 | endyear=as.integer(endyear) 1196 | span=as.integer(span) 1197 | if (span < 0 | span > 5) 1198 | { 1199 | warning("span must be 1, 3, or 5 (or 0, for decennial census)") 1200 | } 1201 | if(dataset=="sf1" | dataset=="sf3") {span=as.integer(0)} 1202 | if (missing(keyword) && missing(table.name) && missing(table.number) && missing(variable)) { 1203 | warning("No search terms provided; returning NA") 1204 | return(NA)} 1205 | if (!missing(variable)){ 1206 | if (!missing(keyword) || !missing(table.name) || !missing(table.number)) { 1207 | warning("Cannot specify both 'variable' and 'keyword/table.name/table.number'.\n Using 'variable' and ignoring others.")} 1208 | } 1209 | # when variable is NOT provided 1210 | if (missing(variable)) { 1211 | arglist=as.list(environment()) 1212 | missing.args=unlist(lapply(arglist, is.symbol)) 1213 | arglist=arglist[!missing.args] 1214 | # arglist$dataset="acs" 1215 | arglist=arglist[names(arglist)!="variable"] 1216 | arglist=arglist[names(arglist)!="geography"] 1217 | arglist=arglist[names(arglist)!="key"] 1218 | arglist=arglist[names(arglist)!="col.names"] 1219 | arglist=arglist[names(arglist)!="var.max"] 1220 | # return(arglist) 1221 | variable=do.call(acs.lookup, arglist) 1222 | if(!isS4(variable) && is.na(variable)){return(NA)}} 1223 | # when variable is provided 1224 | if (is.acs.lookup(variable)) { 1225 | variables.xml=results(variable) 1226 | variables=variables.xml$variable.code 1227 | # next "if" added to allow for sf1/sf3 fetching 1228 | if(dataset=="acs") {variables=paste(rep(variables, each=2), c("E","M"), sep="")} 1229 | } 1230 | if (!is.acs.lookup(variable)) { 1231 | if (variable[1]=="recur") { 1232 | variables=variable[2:length(variable)]} 1233 | else { 1234 | if(dataset=="acs") {variables=paste(rep(variable, each=2), c("E","M"), sep="")} 1235 | if(dataset=="sf1" | dataset=="sf3"){variables=variable} 1236 | } 1237 | if (variable[1]=="") { 1238 | variables.xml=acs.lookup(keyword=keyword, table.name=table.name, endyear=endyear, dataset=dataset, ...) 1239 | if (!identical(NA, variables.xml)){ 1240 | variables.xml=results(variables.xml) 1241 | variables=variables.xml$variable.code 1242 | } 1243 | else {warning("No results found;\n perhaps try acs.lookup()...?") 1244 | return(NA)} 1245 | } 1246 | } 1247 | if (length(variables)==1 && is.na(variable)) return(NA) 1248 | # pretty option to pull descriptive names from XML lookup results; only take every other, since these are the headers for estimates, not MOEs 1249 | if (identical(col.names, "pretty")) { 1250 | if (!is.acs.lookup(variable)) { 1251 | warning("\"pretty\" col.names not available when variable codes provided.\n Using standard variable code names for columns.") 1252 | col.names="auto"} 1253 | else { 1254 | col.names=paste(variables.xml$table.name, variables.xml$variable.name, sep=": ") 1255 | }} 1256 | # if (identical(acs.units, "auto")) acs.units=rep("auto",(length(variables)/2)) 1257 | if (identical(col.names, "auto") & dataset=="acs") col.names=rep("auto",(length(variables)/2)) 1258 | if (identical(col.names, "auto") & (dataset=="sf1" | dataset=="sf3")) col.names=rep("auto",length(variables)) 1259 | # deal with too many variables -- API currently limits to < 50 1260 | # note two versions: acs datasets have doubled variables 1261 | if (length(variables) > var.max & dataset=="acs") { 1262 | acs.obj=cbind(acs.fetch(endyear=endyear, span=span, geography=geography, variable=c("recur", variables[1:(var.max-2)]), key=key, dataset=dataset, col.names=col.names[1:((var.max-2)/2)]), acs.fetch(endyear=endyear, span=span, geography=geography, variable=c("recur", variables[(var.max-1):length(variables)]), col.names=col.names[(1+((var.max-2)/2)):length(col.names)], key=key, dataset=dataset)) 1263 | return(acs.obj) 1264 | } 1265 | # note two versions:sf1/sf3 datasets have single variables, since no E and M types 1266 | if (length(variables) > var.max & (dataset=="sf1" | dataset=="sf3")) { 1267 | acs.obj=cbind(acs.fetch(endyear=endyear, span=span, geography=geography, variable=c("recur", variables[1:(var.max-2)]), key=key, dataset=dataset, col.names=col.names[1:(var.max-2)]), acs.fetch(endyear=endyear, span=span, geography=geography, variable=c("recur", variables[(var.max-1):length(variables)]), col.names=col.names[(var.max-1):length(col.names)], key=key, dataset=dataset)) 1268 | return(acs.obj) 1269 | } 1270 | 1271 | # next deal with complex geographies 1272 | if (is.geo.set(geography) && length(geography)>1){ 1273 | acs.obj=rbind(acs.fetch(endyear=endyear, span=span, geography=geography[1], variable=c("recur", variables), key=key, dataset=dataset, col.names=col.names), acs.fetch(endyear=endyear, span=span, geography=geography[2:length(geography)], variable=c("recur", variables), dataset=dataset, key=key, col.names=col.names)) 1274 | if(combine(geography)){ 1275 | acs.obj=apply(acs.obj, FUN=sum, MARGIN=1, 1276 | agg.term=combine.term(geography), ...) 1277 | acs.obj@acs.units=.acs.identify.units(acs.colnames(acs.obj)) 1278 | } 1279 | return(acs.obj) 1280 | } 1281 | if (is.geo.set(geography) && length(geography)==1) { 1282 | acs.obj=acs.fetch(endyear=endyear, span=span, geography=geography[[1]], variable=c("recur", variables), key=key, dataset=dataset, col.names=col.names) 1283 | if (combine(geography)) { 1284 | acs.obj=apply(acs.obj, FUN=sum, MARGIN=1, 1285 | agg.term=combine.term(geography), ...) 1286 | acs.obj@acs.units=.acs.identify.units(acs.colnames(acs.obj)) 1287 | } 1288 | return(acs.obj) 1289 | } 1290 | # after this point, geography should be always be a single geo 1291 | api.url=api.url.maker(endyear=endyear, span=span, key=key, variables=variables, dataset=dataset, geo.call=geography) 1292 | geo.length=length(api.in(geography))+2 1293 | # adding check to stop bad url / maybe do this later 1294 | if(http_error(api.url)) { 1295 | warning(call.=F, paste("No data found at:\n ", api.url, sep="")) 1296 | } 1297 | in.data=suppressWarnings(read.csv(api.url, na.strings=c("-", "**", "***", "(X)", "N", "null"), stringsAsFactors=F)) 1298 | in.data=in.data[,-length(in.data)] # remove junk NA columns 1299 | # set geocols 1300 | geocols=(length(in.data)-geo.length+1):length(in.data) 1301 | ## col.names=names(in.data)[seq(1,(length(in.data)-geo.length), 2)] 1302 | ## col.names[1]=gsub("X..","",col.names[1]) 1303 | if (identical(col.names[1], "auto")) { # check this! 1304 | if(dataset=="acs"){ 1305 | col.names=names(in.data)[seq(1,(length(in.data)-geo.length), 2)] 1306 | } else if(dataset=="sf1" | dataset=="sf3") { 1307 | col.names=names(in.data)[1:(length(in.data)-geo.length)] 1308 | } 1309 | col.names[1]=gsub("X..","",col.names[1]) 1310 | col.names=gsub(pattern="E$", x=col.names, replacement="") 1311 | 1312 | } 1313 | datacols=1:(length(in.data)-geo.length) 1314 | in.data[in.data=="*****"]=0 1315 | in.data[in.data=="-999999999"]=NA 1316 | in.data[in.data=="-888888888"]=NA 1317 | in.data[in.data=="-666666666"]=NA 1318 | in.data[in.data=="-555555555"]=0 1319 | in.data[in.data=="-333333333"]=NA 1320 | in.data[in.data=="-222222222"]=NA 1321 | in.data[[1]]=gsub("[","",in.data[[1]], fixed=T ) 1322 | in.data[[length(in.data)]]=gsub("]","",in.data[[length(in.data)]], fixed=T ) 1323 | # clean brackets 1324 | for (i in 1:length(datacols)) { 1325 | in.data[[i]]=gsub(",", "", in.data[[i]]) 1326 | in.data[[i]]=as.numeric(in.data[[i]]) 1327 | } 1328 | # create new acs object 1329 | # if (identical(acs.units[1], "auto")) { 1330 | # try to guess variable types from filename 1331 | # acs.units=.acs.identify.units(col.names) 1332 | # } 1333 | # acs.units=factor(acs.units, levels=.acs.unit.levels) 1334 | GEOGRAPHY=as.data.frame(in.data[,geocols]) 1335 | names(GEOGRAPHY)=gsub(".", "", names(GEOGRAPHY), fixed=T) # remove strange trailing period 1336 | if(dataset=="acs"){ 1337 | acs.obj=new(Class="acs", 1338 | endyear=endyear, 1339 | span=span, 1340 | geography=GEOGRAPHY, 1341 | acs.colnames=col.names, 1342 | acs.units=.acs.identify.units(col.names), 1343 | currency.year=endyear, 1344 | standard.error=as.matrix(in.data[,seq(2,(length(in.data)-geo.length), 2)]), 1345 | modified=F, 1346 | estimate=as.matrix(in.data[,seq(1,(length(in.data)-geo.length), 2)]) 1347 | )} 1348 | if(dataset=="sf1" | dataset=="sf3"){ 1349 | acs.obj=new(Class="acs", 1350 | endyear=endyear, 1351 | span=span, 1352 | geography=GEOGRAPHY, 1353 | acs.colnames=col.names, 1354 | acs.units=.acs.identify.units(col.names), 1355 | currency.year=endyear, 1356 | standard.error=as.matrix(0*(in.data[1:(length(in.data)-geo.length)])), 1357 | modified=F, 1358 | estimate=as.matrix(in.data[1:(length(in.data)-geo.length)]) 1359 | ) 1360 | } 1361 | # convert 90% MOE into standard error, correct for 2005 flaw 1362 | if (endyear(acs.obj)<=2005) 1363 | acs.obj@standard.error=acs.obj@standard.error/1.65 1364 | else 1365 | acs.obj@standard.error=acs.obj@standard.error/1.645 1366 | acs.obj=.acs.dimnames(acs.obj) 1367 | # if (obj.combine) {acs.obj=apply(acs.obj, FUN=sum, MARGIN=1)} 1368 | acs.obj 1369 | } 1370 | 1371 | if (!isGeneric("endyear")) { 1372 | setGeneric("endyear", def=function(object){standardGeneric("endyear")})}else{} 1373 | setMethod("endyear", "acs", function(object) object@endyear) 1374 | 1375 | if (!isGeneric("span")) { 1376 | setGeneric("span", def=function(object){standardGeneric("span")})}else{} 1377 | setMethod("span", "acs", function(object) object@span) 1378 | 1379 | if (!isGeneric("geography")) { 1380 | setGeneric("geography", def=function(object){standardGeneric("geography")})}else{} 1381 | setMethod("geography", "acs", function(object) object@geography) 1382 | 1383 | if (!isGeneric("acs.colnames")) { 1384 | setGeneric("acs.colnames", def=function(object){standardGeneric("acs.colnames")})}else{} 1385 | setMethod("acs.colnames", "acs", function(object) object@acs.colnames) 1386 | 1387 | if (!isGeneric("currency.year")) { 1388 | setGeneric("currency.year", def=function(object){standardGeneric("currency.year")})}else{} 1389 | setMethod("currency.year", "acs", function(object) object@currency.year) 1390 | 1391 | if (!isGeneric("modified")) { 1392 | setGeneric("modified", def=function(object){standardGeneric("modified")})}else{} 1393 | setMethod("modified", "acs", function(object) object@modified) 1394 | 1395 | if (!isGeneric("acs.units")) { 1396 | setGeneric("acs.units", def=function(object){standardGeneric("acs.units")})}else{} 1397 | setMethod("acs.units", "acs", function(object) object@acs.units) 1398 | 1399 | if (!isGeneric("estimate")) { 1400 | setGeneric("estimate", def=function(object, which, conf.lev, ...){standardGeneric("estimate")})}else{} 1401 | setMethod("estimate", "acs", function(object) object@estimate) 1402 | 1403 | if (!isGeneric("standard.error")) { 1404 | setGeneric("standard.error", def=function(object){standardGeneric("standard.error")})}else{} 1405 | setMethod("standard.error", "acs", function(object) object@standard.error) 1406 | 1407 | setMethod(f="[", signature="acs", definition=function(x,i,j,...,drop=FALSE){ 1408 | if (missing(i)) i=1:dim(x@estimate)[1] 1409 | if (missing(j)) j=1:dim(x@estimate)[2] 1410 | new(Class="acs", 1411 | endyear=endyear(x), 1412 | span=span(x), 1413 | geography=geography(x)[i,], 1414 | acs.colnames=acs.colnames(x)[j], 1415 | modified=modified(x), 1416 | acs.units=acs.units(x)[j], 1417 | currency.year=currency.year(x), 1418 | estimate=estimate(x)[i,j, drop=F], 1419 | standard.error=standard.error(x)[i,j, drop=F]) 1420 | }) 1421 | 1422 | setReplaceMethod(f="[", signature="acs", 1423 | definition=function(x,i,j,value){ 1424 | if (missing(i)) i=1:dim(x)[1] 1425 | if (missing(j)) j=1:dim(x)[2] 1426 | # is value acs object? ## still need to check for metadata being the same 1427 | if (is.acs(value) && all(dim(value)==c(length(i),length(j)))){ 1428 | if (endyear(x) != endyear(value)) { 1429 | warning("original and replacement do not have same endyear;\nkeeping original value", call.=F)} 1430 | if (span(x) != span(value)) { 1431 | warning("original and replacement do not have same span;\nkeeping original value", call.=F)} 1432 | if (currency.year(x) != currency.year(value)) { 1433 | warning("original and replacement do not have same currency.year;\nkeeping original value", call.=F)} 1434 | x@estimate[i,j]=value@estimate 1435 | x@standard.error[i,j]=value@standard.error 1436 | # check for mismatch geo when not all cols changed 1437 | if (!all(geography(x[i,j])==geography(value))){ # if not identical geogs 1438 | if (dim(x)[2]<=length(j)){ # if changing all cols or more 1439 | x@geography[i,]=geography(value) # change all geo 1440 | warning("geographies do not match but all columns changed;\nusing new geographies", call.=F) 1441 | }else{ 1442 | warning("geographies do not match but some columns retained;\nkeeping original geography values", call.=F) 1443 | } 1444 | } 1445 | if (!all(acs.colnames(x[i,j])==acs.colnames(value))){ # if not identical colnames 1446 | if (dim(x)[1]<=length(i)){ # if not changing all rows or more 1447 | x@acs.colnames[j]=acs.colnames(value) 1448 | warning("acs.colnames do not match but all rows changes;\nusing new acs.colnames", call.=F) 1449 | }else{ 1450 | warning("acs.colnames do not match but some rows retained;\nkeeping original acs.colnames", call.=F) 1451 | } 1452 | } 1453 | # is value two item list? 1454 | } else if (is.list(value) && length(value)==2) { 1455 | if (is.null(value$estimate)) x@estimate[i,j]=value[[1]] 1456 | else x@estimate[i,j]=value$estimate 1457 | if (is.null(value$standard.error)){ 1458 | if (is.null(value$error)) x@standard.error[i,j]=value[[2]] 1459 | else x@standard.error[i,j]=value$error 1460 | } else x@standard.error[i,j]=value$standard.error 1461 | ## standard.error --> 0 1462 | # is value a single number? 1463 | ## } else if (is.numeric(value) && (length(value)==1)) { 1464 | ## x@estimate[i,j]=value 1465 | ## x@standard.error[i,j]=0 1466 | ## # is value a vector of numbers? 1467 | ## } else if (is.numeric(value) && (length(value)==length(x[i,j]))){ 1468 | ## x@estimate[i,j]=value 1469 | ## x@standard.error[i,j]=0 1470 | ## next stanza does the work of both of the previous: 1471 | } else if (is.numeric(value)) { 1472 | x@estimate[i,j]=value 1473 | x@standard.error[i,j]=0 1474 | } else {stop("incompatible objects or dimensions;\nunable to parse for replacement", call.=F)} 1475 | x@modified=T 1476 | x=.acs.dimnames(x) # in case geography or acs.colnames changed 1477 | validObject(x) 1478 | return(x) 1479 | }) 1480 | 1481 | cbind.acs=function(e1, e2, ...) { 1482 | if (e1@endyear != e2@endyear | e1@span != e2@span) { 1483 | warning("** acs objects x and y must have same endyear and span;\nreturning NA **") 1484 | return(NA)} 1485 | if (identical(geography(e1), geography(e2))) GEOGRAPHY=geography(e1) 1486 | else {warning( "geographies do not appear to match; using first geography") 1487 | GEOGRAPHY=geography(e1)} 1488 | NEW.ESTIMATE=cbind(estimate(e1), estimate(e2)) 1489 | NEW.ERROR=cbind(standard.error(e1), standard.error(e2)) 1490 | acs.obj=new(Class="acs", endyear=endyear(e1), span=span(e1), modified=T, geography=GEOGRAPHY, acs.units=factor(c(acs.units(e1),acs.units(e2)), levels=.acs.unit.levels), currency.year=currency.year(e1), acs.colnames=c(acs.colnames(e1), acs.colnames(e2)), estimate=NEW.ESTIMATE, standard.error=NEW.ERROR) 1491 | acs.obj=.acs.dimnames(acs.obj) 1492 | acs.obj 1493 | } 1494 | 1495 | rbind.acs=function(e1, e2, ...) { 1496 | if (e1@endyear != e2@endyear | e1@span != e2@span) { 1497 | warning("** acs objects x and y must have same endyear and span;\nreturning NA **") 1498 | return(NA)} 1499 | if (identical(acs.colnames(e1), acs.colnames(e2))) ACS.COLNAMES=acs.colnames(e1) 1500 | else {warning( "columns do not appear to match; using first colnames") 1501 | ACS.COLNAMES=acs.colnames(e1)} 1502 | GEOGRAPHY=rbind.fill(geography(e1), geography(e2)) 1503 | NEW.ESTIMATE=rbind(estimate(e1), estimate(e2)) 1504 | NEW.ERROR=rbind(standard.error(e1), standard.error(e2)) 1505 | acs.obj=new(Class="acs", endyear=endyear(e1), span=span(e1), modified=T, geography=GEOGRAPHY, acs.units=acs.units(e1), currency.year=currency.year(e1), acs.colnames=acs.colnames(e1), estimate=NEW.ESTIMATE, standard.error=NEW.ERROR) 1506 | acs.obj=.acs.dimnames(acs.obj) 1507 | acs.obj 1508 | } 1509 | 1510 | setMethod("+", signature(e1 = "acs", e2 = "acs"), function(e1, e2) { 1511 | header=.acs.combine.headers(e1,e2,"+") 1512 | NEW.ESTIMATE=estimate(e1)+estimate(e2) 1513 | NEW.ERROR=sqrt(standard.error(e1)^2+standard.error(e2)^2) 1514 | acs.obj=new(Class="acs", 1515 | endyear=header$endyear, 1516 | span=header$span, 1517 | modified=T, 1518 | geography=header$geography, 1519 | acs.units=header$acs.units, 1520 | currency.year=header$currency.year, 1521 | acs.colnames=header$acs.colnames, 1522 | estimate=NEW.ESTIMATE, 1523 | standard.error=NEW.ERROR) 1524 | acs.obj=.acs.dimnames(acs.obj) 1525 | acs.obj 1526 | } 1527 | ) 1528 | 1529 | setMethod("-", signature(e1 = "acs", e2 = "acs"), function(e1, e2) { 1530 | header=.acs.combine.headers(e1, e2, "-") 1531 | NEW.ESTIMATE=estimate(e1)-estimate(e2) 1532 | NEW.ERROR=sqrt(standard.error(e1)^2+standard.error(e2)^2) 1533 | acs.obj=new(Class="acs", 1534 | endyear=header$endyear, 1535 | span=header$span, 1536 | modified=T, 1537 | geography=header$geography, 1538 | acs.units=header$acs.units, 1539 | currency.year=header$currency.year, 1540 | acs.colnames=header$acs.colnames, 1541 | estimate=NEW.ESTIMATE, 1542 | standard.error=NEW.ERROR) 1543 | acs.obj=.acs.dimnames(acs.obj) 1544 | acs.obj 1545 | } 1546 | ) 1547 | 1548 | ## old; works, but not great. 1549 | # .acs.divider=function(num, den, proportion, verbose=F) { 1550 | # if (proportion==T) header=.acs.combine.headers(num, den, "/") 1551 | # else header=.acs.combine.headers(num, den, ":") 1552 | # p=estimate(num)/estimate(den) 1553 | # if (all(estimate(den)!=0) && proportion==T & all((p^2 * standard.error(den)^2)>0)){ 1554 | # header$acs.units=factor("proportion", levels=.acs.unit.levels) 1555 | # if (verbose) {warning("** using formula for PROPORTIONS, which assumes that numerator is a SUBSET of denominator **")} 1556 | # NEW.ERROR=sqrt(standard.error(num)^2 - (p^2 * standard.error(den)^2))/estimate(den)} 1557 | # else { 1558 | # # a recommended correction when term under sqrt is negative 1559 | # if (proportion==T){ 1560 | # if(verbose){warning("** due to the nature of some of the errors, using the more conservative formula for RATIOS, which assumes that numerator is not a subset of denominator **")}} 1561 | # header$acs.units=factor("ratio", levels=.acs.unit.levels) 1562 | # NEW.ERROR=sqrt(standard.error(num)^2 + (p^2 * standard.error(den)^2))/estimate(den) 1563 | # } 1564 | # acs.obj=new(Class="acs", 1565 | # endyear=header$endyear, 1566 | # span=header$span, 1567 | # modified=T, 1568 | # geography=header$geography, 1569 | # acs.units=header$acs.units, 1570 | # currency.year=header$currency.year, 1571 | # acs.colnames=header$acs.colnames, 1572 | # estimate=p, 1573 | # standard.error=NEW.ERROR) 1574 | # acs.obj=.acs.dimnames(acs.obj) 1575 | # acs.obj} 1576 | 1577 | # new, to deal with zeroes, and more precise ratio-style correction 1578 | 1579 | .acs.divider=function(num, den, proportion, verbose=F, output="result") { 1580 | if (proportion==T) header=.acs.combine.headers(num, den, "/") 1581 | else header=.acs.combine.headers(num, den, ":") 1582 | p=estimate(num)/estimate(den) 1583 | # start with proportion-style 1584 | if (proportion==T){ 1585 | header$acs.units=rep(factor("proportion", levels=.acs.unit.levels), length(header$acs.units)) 1586 | if (verbose) {warning("** using formula for PROPORTIONS, which assumes that numerator is a SUBSET of denominator **")} 1587 | NEW.ERROR=suppressWarnings(sqrt(standard.error(num)^2 - (p^2 * standard.error(den)^2))/estimate(den)) 1588 | # change all that are should be ratio-stye 1589 | # index for ratio corrections 1590 | proportion.numerators=suppressWarnings(sqrt(standard.error(num)^2 - (p^2 * standard.error(den)^2))) 1591 | ratio.correct.index=is.na(proportion.numerators) 1592 | # if any fail the test 1593 | if(any(ratio.correct.index)){ 1594 | # use ratio-style correction 1595 | ratio.errors=sqrt(standard.error(num)^2 + (p^2 * standard.error(den)^2))/estimate(den) 1596 | NEW.ERROR[ratio.correct.index]=ratio.errors[ratio.correct.index] 1597 | if(verbose) { 1598 | warning(paste("**Note: due to the nature of the errors in some cells,\n they were divided using the more conservative formula for RATIOS\n which assumes that numerator is not a subset of denominator**:\n in total, ", sum(ratio.correct.index), " ratio-style divisions substituted;\n see ?divide.acs and/or use output=\"result\" for more.", sep=""))} 1599 | if(output=="both" | output=="div.method"){ 1600 | ratio.report=p # just to get a matrix with the same dims 1601 | colnames(ratio.report)=header$acs.colnames 1602 | rownames(ratio.report)=header$geography[[1]] 1603 | ratio.report[ratio.correct.index]="ratio" 1604 | ratio.report[!ratio.correct.index]="proportion" 1605 | }}} 1606 | else { 1607 | # ratio style 1608 | header$acs.units=rep(factor("ratio", levels=.acs.unit.levels), length(header$acs.units)) 1609 | NEW.ERROR=sqrt(standard.error(num)^2 + (p^2 * standard.error(den)^2))/estimate(den) 1610 | ratio.report=p # just to get a matrix with the same dims 1611 | colnames(ratio.report)=header$acs.colnames 1612 | rownames(ratio.report)=header$geography[[1]] 1613 | ratio.report[,]="ratio" 1614 | } 1615 | acs.obj=new(Class="acs", 1616 | endyear=header$endyear, 1617 | span=header$span, 1618 | modified=T, 1619 | geography=header$geography, 1620 | acs.units=header$acs.units, 1621 | currency.year=header$currency.year, 1622 | acs.colnames=header$acs.colnames, 1623 | estimate=p, 1624 | standard.error=NEW.ERROR) 1625 | acs.obj=.acs.dimnames(acs.obj) 1626 | if(output=="both") {list("result"=acs.obj, "div.method"=ratio.report)} 1627 | else if(output=="div.method"){ratio.report} 1628 | else acs.obj 1629 | } 1630 | 1631 | 1632 | 1633 | setMethod("/", signature(e1 = "acs", e2 = "acs"), function(e1, e2) { 1634 | # by default, use more conservative "ratio-style" dividing 1635 | warning("** using the more conservative formula for ratio-type 1636 | dividing, which does not assume that numerator is a subset of 1637 | denominator; for more precise results when seeking a proportion 1638 | and not a ratio, use divide.acs(..., method=\"proportion\") **") 1639 | .acs.divider(num=e1, den=e2, proportion=F, verbose=F) 1640 | }) 1641 | 1642 | divide.acs=function(numerator, denominator, method="ratio", verbose=T, output="result"){ 1643 | if(identical(method, "ratio")) { 1644 | .acs.divider(num=numerator, den=denominator, proportion=F, verbose=verbose, output=output) 1645 | } else if(identical(method, "proportion")) { 1646 | .acs.divider(num=numerator, den=denominator, proportion=T, verbose=verbose, output=output) 1647 | } else {warning("Error: must set method to \"ratio\" or \"proportion\"") 1648 | NA} 1649 | } 1650 | 1651 | setMethod("*", signature(e1 = "acs", e2 = "acs"), function(e1, e2) { 1652 | header=.acs.combine.headers(e1, e2, "*") 1653 | NEW.ESTIMATE=estimate(e1)*estimate(e2) 1654 | NEW.ERROR=sqrt((estimate(e1)^2*standard.error(e2)^2)+(estimate(e2)^2*standard.error(e1)^2)) 1655 | acs.obj=new(Class="acs", 1656 | endyear=header$endyear, 1657 | span=header$span, 1658 | modified=T, 1659 | geography=header$geography, 1660 | acs.units=header$acs.units, 1661 | currency.year=header$currency.year, 1662 | acs.colnames=header$acs.colnames, 1663 | estimate=NEW.ESTIMATE, 1664 | standard.error=NEW.ERROR) 1665 | acs.obj=.acs.dimnames(acs.obj) 1666 | acs.obj} 1667 | ) 1668 | 1669 | setMethod("+", signature(e1 = "acs", e2 = "numeric"), function(e1, e2) { 1670 | e2=.acs.make.constant.object(value=e2, template=e1) 1671 | e1+e2 1672 | } 1673 | ) 1674 | 1675 | # and reverse classes... 1676 | 1677 | setMethod("+", signature(e1 = "numeric", e2 = "acs"), function(e1, e2) { 1678 | e1=.acs.make.constant.object(value=e1, template=e2) 1679 | e1+e2 1680 | } 1681 | ) 1682 | 1683 | setMethod("-", signature(e1 = "acs", e2 = "numeric"), function(e1, e2) { 1684 | e2=.acs.make.constant.object(value=e2, template=e1) 1685 | e1-e2 1686 | } 1687 | ) 1688 | 1689 | # ditto... 1690 | 1691 | setMethod("-", signature(e1 = "numeric", e2 = "acs"), function(e1, e2) { 1692 | e1=.acs.make.constant.object(value=e1, template=e2) 1693 | e1-e2 1694 | } 1695 | ) 1696 | 1697 | setMethod("/", signature(e1 = "acs", e2 = "numeric"), function(e1, e2) { 1698 | e2=.acs.make.constant.object(value=e2, template=e1) 1699 | e1/e2 1700 | } 1701 | ) 1702 | 1703 | # ditto... 1704 | 1705 | setMethod("/", signature(e1 = "numeric", e2 = "acs"), function(e1, e2) { 1706 | e1=.acs.make.constant.object(value=e1, template=e2) 1707 | e1/e2 1708 | } 1709 | ) 1710 | 1711 | setMethod("*", signature(e1 = "acs", e2 = "numeric"), function(e1, e2) { 1712 | e2=.acs.make.constant.object(value=e2, template=e1) 1713 | e1*e2 1714 | } 1715 | ) 1716 | 1717 | # ditto... 1718 | 1719 | setMethod("*", signature(e1 = "numeric", e2 = "acs"), function(e1, e2) { 1720 | e1=.acs.make.constant.object(value=e1, template=e2) 1721 | e1*e2 1722 | } 1723 | ) 1724 | 1725 | setMethod("show", signature(object = "acs"), function(object) { 1726 | if(is.na(span(object)) | is.na(endyear(object))) years="NO MEANINGFUL YEAR" 1727 | else 1728 | if(span(object)==0 | span(object)==1) years=endyear(object) 1729 | else years=paste(endyear(object)-span(object)+1,"--",endyear(object)) 1730 | if(span(object)==0) {dataset="Decennial Census (SF1/SF3)" } else {dataset="ACS"} 1731 | cat(dataset, "DATA: \n", years, ";\n") 1732 | cat(" Estimates w/90% confidence intervals;\n for different intervals, see confint()\n") 1733 | est=estimate(object) 1734 | err=standard.error(object) 1735 | output=matrix(paste(est, "+/-", 1.645*err), nrow=nrow(est)) 1736 | dimnames(output)=dimnames(est) 1737 | print(output, quote=FALSE) 1738 | }) 1739 | 1740 | setMethod("summary", signature(object = "acs"), function(object) { 1741 | if(span(object)==1) years=endyear(object) 1742 | else years=paste(endyear(object)-span(object)+1,"--",endyear(object)) 1743 | cat("ACS DATA: \n", years,"\n") 1744 | cat("----------\nESTIMATES:\n") 1745 | print(summary(estimate(object))) 1746 | cat("----------\n90% MARGINS OF ERROR:\n") 1747 | print(summary(1.645*standard.error(object))) 1748 | }) 1749 | 1750 | dim.acs=function(x){ 1751 | dim(estimate(x))} 1752 | 1753 | length.acs=function(x){ 1754 | length(estimate(x))} 1755 | 1756 | confint.acs=function(object, parm="all", level=.95, alternative="two.sided",...) { 1757 | if (parm[1]=="all") parm=1:dim(object)[2] 1758 | z.upper=switch(alternative, two.sided=qnorm((1+level)/2), greater=Inf, less=qnorm(level)) 1759 | z.lower=switch(alternative, two.sided=qnorm((1+level)/2), greater=qnorm(level), less=Inf) 1760 | labels=switch(alternative, two.sided=c((1-level)/2 , 1 - (1-level)/2), less=c(0,level), greater=c(1-level,1)) 1761 | labels=paste(100*labels, "%", sep=" ") 1762 | RESULT=list() 1763 | for (i in parm) { 1764 | conf.int.lower=estimate(object[,i])-standard.error(object[,i])*z.lower 1765 | conf.int.upper=estimate(object[,i])+standard.error(object[,i])*z.upper 1766 | RESULT[[acs.colnames(object)[i]]]=data.frame(conf.int.lower, 1767 | conf.int.upper, 1768 | row.names=geography(object)[[1]]) 1769 | names(RESULT[[acs.colnames(object)[i]]])=labels 1770 | } 1771 | RESULT 1772 | } 1773 | 1774 | setMethod("sum", signature(x = "acs"), function(x, 1775 | agg.term=c("aggregate", "aggregate"), one.zero=FALSE, ..., na.rm=FALSE) { 1776 | if(length(agg.term)<2){agg.term[2]=agg.term[1]} 1777 | est=estimate(x) 1778 | err=standard.error(x) 1779 | if (one.zero==T && any(est==0)) { 1780 | max.zero.error=max(err[est==0]) 1781 | err[est==0]=c(max.zero.error,rep(0,sum(est==0)-1)) 1782 | } 1783 | if (dim(est)[1]==1){ geography=geography(x)} # single row 1784 | else { 1785 | geography=geography(x[1,1]) 1786 | for (i in 1:length(geography)){ 1787 | geography[,i]=agg.term[1]} 1788 | } 1789 | if (dim(est)[2]==1){acs.units=acs.units(x) # single column 1790 | acs.colnames=acs.colnames(x) 1791 | } 1792 | else {acs.units=factor(levels=.acs.unit.levels) 1793 | acs.colnames=agg.term[2]} 1794 | ESTIMATE=as.matrix(sum(est)) 1795 | ERROR=as.matrix(sqrt(sum(err^2))) 1796 | acs.obj=new(Class="acs", 1797 | endyear=endyear(x), 1798 | span=span(x), 1799 | modified=T, 1800 | geography=geography, 1801 | acs.units=acs.units, 1802 | currency.year=currency.year(x), 1803 | acs.colnames=acs.colnames, 1804 | estimate=ESTIMATE, 1805 | standard.error=ERROR) 1806 | acs.obj=.acs.dimnames(acs.obj) 1807 | acs.obj 1808 | }) 1809 | 1810 | .apply.acs=function(X, MARGIN, FUN, ...) 1811 | { 1812 | FUN=match.fun(FUN) 1813 | if (identical(MARGIN, 1)){ # apply row-wise 1814 | acs.obj=FUN(X[,1], ...) 1815 | if(dim(X)[2]>1){ 1816 | for (i in 2:dim(X)[2]){ 1817 | acs.obj=cbind(acs.obj, FUN(X[,i], ...)) 1818 | }} 1819 | } 1820 | if (identical(MARGIN, 2)){ # apply col-wise 1821 | acs.obj=FUN(X[1,], ...) 1822 | if (dim(X)[1]>1){ 1823 | for (i in 2:dim(X)[1]){ 1824 | acs.obj=rbind(acs.obj, FUN(X[i,], ...)) 1825 | }} 1826 | } 1827 | # I think the next part works, except it fails because the stuff above 1828 | # doesn't like single rows or single columns... 1829 | # if (identical (MARGIN, c(1,2))){ 1830 | # acs.obj=apply(apply(X, MARGIN=1, FUN=FUN), MARGIN=2, 1831 | # FUN=FUN)} 1832 | 1833 | # or maybe this...? 1834 | if (all(MARGIN==c(1,2))){ 1835 | acs.obj=FUN(apply(X, MARGIN=2, FUN=FUN, ...), ...)} 1836 | acs.obj} 1837 | 1838 | 1839 | if (!isGeneric("apply")) { 1840 | setGeneric("apply", def=function(X, MARGIN, FUN, ...){standardGeneric("apply")})}else{} 1841 | setMethod("apply", signature="acs", def=function(X, MARGIN, FUN, ...){.apply.acs(X, MARGIN, FUN, ...)}) 1842 | 1843 | setMethod("plot", 1844 | signature(x = "acs"), 1845 | function (x, conf.level=.95, err.col="red", err.lwd=1, 1846 | err.pch="-", err.cex=2, err.lty=2, x.res=300, labels="auto", 1847 | by="geography", true.min=T, ...) 1848 | { 1849 | # internal plot function to plot individual x-y plots with conf 1850 | # intervals, assume that either i or j or length 1 1851 | plot.xy.acs=function(x, object, conf.int.upper, conf.int.lower, estimates, labels, xlab, ylab, ...){ 1852 | if(missing(xlab)) xlab="" 1853 | if(missing(ylab)) ylab="" 1854 | plot(rep(x,2), c(conf.int.upper, conf.int.lower), type="n", xaxt="n", xlab=xlab, ylab=ylab,...) 1855 | axis(side=1, labels=labels, at=x, ...) 1856 | lines(x=matrix(c(x,x,rep(NA, length(x))), ncol=length(x), byrow=T), matrix(c(conf.int.lower, conf.int.upper, rep(NA, length(x))), ncol=length(x), byrow=T), col=err.col, lwd=err.lwd, lty=err.lty) 1857 | points(x, conf.int.upper, pch=err.pch, cex=err.cex, col=err.col) 1858 | points(x, conf.int.lower, pch=err.pch, cex=err.cex, col=err.col) 1859 | points(x, estimates,...) 1860 | } 1861 | acs.density.plot=function(x, type="l", xlim, 1862 | xlab=acs.colnames(x), ylab="Density Distribution", 1863 | conf.level, col="black", err.col, err.lwd, err.lty, 1864 | x.res, ...){ 1865 | est=estimate(x) 1866 | err=standard.error(x) 1867 | if (missing(xlim)) xlim=c(est-(4*err), est+(4*err)) 1868 | x.vals=seq(from=xlim[1], to=xlim[2], by=(xlim[2]-xlim[1])/x.res) 1869 | plot(x.vals, dnorm(x.vals, mean=est, sd=err), type=type, 1870 | xlab=xlab, ylab=ylab, col=col,...) 1871 | if (conf.level) {abline(v=qnorm(mean=est, sd=err, p=c(((1-conf.level)/2), (1-((1-conf.level)/2)))), col=err.col, lwd=err.lwd, lty=err.lty)} 1872 | } 1873 | i=dim(x)[1] 1874 | j=dim(x)[2] 1875 | if (length(x)==1) { 1876 | acs.density.plot(x, conf.level=conf.level, err.col=err.col, 1877 | err.lwd=err.lwd, err.lty=err.lty, x.res=x.res, ...) 1878 | } else if (i == 1 | j == 1){ 1879 | con=confint(x, level=conf.level) 1880 | conf.int.upper=NA 1881 | conf.int.lower=NA 1882 | estimates=NA 1883 | if (i == 1) { # one row 1884 | if (identical(labels, "auto")) labels=acs.colnames(x) 1885 | for (k in 1:j){ 1886 | conf.int.upper[k]=as.numeric(con[[k]][2]) 1887 | if (true.min==T) { 1888 | conf.int.lower[k]=as.numeric(con[[k]][1]) 1889 | } else {if (true.min==F) {true.min=0} 1890 | conf.int.lower[k]=max(true.min, as.numeric(con[[k]][1]))} 1891 | estimates[k]=estimate(x)[1,k] 1892 | }} 1893 | else { 1894 | if (identical(labels, "auto")) labels=geography(x)[[1]] 1895 | for (k in 1:i){ # one column 1896 | conf.int.upper[k]=as.numeric(con[[1]][k,2]) 1897 | if (true.min==T) { 1898 | conf.int.lower[k]=con[[1]][k,1] 1899 | } else {if (true.min==F) {true.min=0} 1900 | conf.int.lower[k]=max(true.min, con[[1]][k,1])} 1901 | estimates[k]=estimate(x)[k,1] 1902 | }} 1903 | plot.xy.acs(x=1:max(i,j), object=x, conf.int.upper=conf.int.upper, conf.int.lower=conf.int.lower, estimates=estimates, labels=labels,...) 1904 | } else { 1905 | if (by=="geography"){ 1906 | par(mfrow=c(i, 1)) 1907 | for (k in 1:i){ 1908 | plot(x[k,], sub=geography(x)[k,1], conf.level=conf.level, err.col=err.col, err.lwd=err.lwd, err.pch=err.pch, err.cex=err.cex, err.lty=err.lty, labels=labels,...) 1909 | } 1910 | } else if (by=="acs.colnames") { 1911 | par(mfrow=c(1,j)) 1912 | for (k in 1:j){ 1913 | plot(x[,k], sub=acs.colnames(x)[k], conf.level=conf.level, 1914 | err.col=err.col, err.lwd=err.lwd, err.pch=err.pch, 1915 | err.cex=err.cex, err.lty=err.lty, labels=labels,...) 1916 | } 1917 | } 1918 | } 1919 | } 1920 | ) 1921 | 1922 | if (!isGeneric("acs.colnames<-")) { 1923 | setGeneric("acs.colnames<-", def=function(x, value){standardGeneric("acs.colnames<-")})}else{} 1924 | 1925 | # setGeneric("acs.colnames<-", function(x, value) standardGeneric("acs.colnames<-")) 1926 | 1927 | setReplaceMethod(f="acs.colnames", signature="acs", 1928 | definition=function(x,value){ 1929 | x@acs.colnames=value 1930 | x=.acs.dimnames(x) 1931 | x@modified=T 1932 | validObject(x) 1933 | return(x) 1934 | }) 1935 | 1936 | if (!isGeneric("geography<-")) { 1937 | setGeneric("geography<-", def=function(object, value){standardGeneric("geography<-")})}else{} 1938 | 1939 | setReplaceMethod(f="geography", signature="acs", 1940 | definition=function(object,value){ 1941 | object@geography=value 1942 | object=.acs.dimnames(object) 1943 | object@modified=T 1944 | validObject(object) 1945 | return(object) 1946 | }) 1947 | 1948 | 1949 | if (!isGeneric("endyear<-")) { 1950 | setGeneric("endyear<-", function(object, value) standardGeneric("endyear<-"))}else{} 1951 | 1952 | setReplaceMethod(f="endyear", signature="acs", 1953 | definition=function(object,value){ 1954 | warning(paste( 1955 | "Changing value of endyear from ", 1956 | endyear(object), 1957 | " to ", 1958 | value, 1959 | ".\nThis is an unusual thing to do, unless the original value was incorrect.\nAlso changing value of currency.year to", 1960 | value, 1961 | ", without converting currency values.\nPlease see ?endyear and ?currency.year for more information", 1962 | sep="") 1963 | , call.=F) 1964 | object@endyear=as.integer(value) 1965 | object@currency.year=as.integer(value) 1966 | object@modified=T 1967 | validObject(object) 1968 | return(object) 1969 | }) 1970 | 1971 | if (!isGeneric("span<-")) { 1972 | setGeneric("span<-", function(x, value) standardGeneric("span<-"))}else{} 1973 | 1974 | setReplaceMethod(f="span", signature="acs", 1975 | definition=function(x,value){ 1976 | warning(paste("Changing value of span from ", 1977 | span(x), " to ", value, ".\nThis is an unusual 1978 | thing to do, unless the original value was 1979 | incorrect.\nSee ?acs for more information", 1980 | sep=""), call.=F) 1981 | x@span=as.integer(value) 1982 | x@modified=T 1983 | validObject(x) 1984 | return(x) 1985 | }) 1986 | 1987 | if (!isGeneric("acs.units<-")) { 1988 | setGeneric("acs.units<-", function(x, value) standardGeneric("acs.units<-"))}else{} 1989 | 1990 | setReplaceMethod(f="acs.units", signature="acs", 1991 | definition=function(x,value){ 1992 | x@acs.units=factor(value, levels=.acs.unit.levels) 1993 | x@modified=T 1994 | validObject(x) 1995 | return(x) 1996 | }) 1997 | 1998 | if (!isGeneric("currency.year<-")) { 1999 | setGeneric("currency.year<-", def=function(object, value){standardGeneric("currency.year<-")})}else{} 2000 | 2001 | setReplaceMethod(f="currency.year", signature="acs", 2002 | definition=function(object, value){ 2003 | currency.convert(object, rate="auto", newyear=value) 2004 | }) 2005 | 2006 | currency.convert=function(object, rate="auto", newyear=NA_integer_, verbose=F){ 2007 | if (rate=="auto"){ 2008 | .env=environment() 2009 | data("cpi", envir=.env) 2010 | new.rate="cpi[as.character(newyear)]" 2011 | new.rate=eval(parse(text=new.rate)) 2012 | curr.rate="cpi[as.character(currency.year(object))]" 2013 | curr.rate=eval(parse(text=curr.rate)) 2014 | rate=new.rate/curr.rate} 2015 | dollar.cols=which(acs.units(object)=="dollars") 2016 | if (verbose) { 2017 | if (!missing(newyear)){ 2018 | output=c(paste("CPI (base 1982-84) for ", currency.year(object), 2019 | " = ", curr.rate, sep=""), 2020 | "\n", 2021 | paste("CPI (base 1982-84) for ", newyear, " = ", new.rate, sep=""), 2022 | "\n", 2023 | paste("$1.00 in ", currency.year(object), " dollars = $", round(rate,2), " in ", newyear, " dollars.", sep=""), 2024 | "\n")} else {output=c(paste("$1.00 in ", 2025 | currency.year(object), 2026 | " dollars = $", 2027 | round(rate,2), 2028 | " in converted dollars.", 2029 | sep=""), 2030 | "\n")} 2031 | output=c(output, "Converting the following columns:", "\n", 2032 | paste(acs.colnames(object)[dollar.cols], "\n", sep="")) 2033 | warning(output, call.=F) 2034 | } 2035 | for (i in dollar.cols){ 2036 | object@estimate[,i]=object@estimate[,i]*rate 2037 | object@standard.error[,i]=object@standard.error[,i]*rate 2038 | } 2039 | object@currency.year=as.integer(newyear) 2040 | object@modified=T 2041 | validObject(object) 2042 | return(object) 2043 | } 2044 | 2045 | # helper function for replacing geography or acs.colnames 2046 | 2047 | prompt.acs=function(object, filename=NA, name=NA, 2048 | what="acs.colnames", geocols="all", ...){ 2049 | print("To end session, enter a blank line.") 2050 | if (what=="geography"){ 2051 | if (geocols=="all") geocols=1:dim(geography(object))[2] 2052 | value=geography(object) 2053 | for (j in geocols){ 2054 | for (i in 1:dim(geography(object))[1]){ 2055 | line.input=readline(prompt=paste("Change ", value[i,j]," to: \n", sep="")) 2056 | if (line.input=="") {break} else {value[i,j]=line.input} 2057 | } 2058 | } 2059 | } 2060 | else if (what=="acs.colnames"){ 2061 | value=acs.colnames(object) 2062 | for (i in 1:length(acs.colnames(object))){ 2063 | line.input=readline(prompt=paste("Change ", value[i]," to: \n", sep="")) 2064 | if (line.input=="") {break} else {value[i]=line.input} 2065 | } 2066 | } else if (what=="acs.units"){ 2067 | value=acs.units(object) 2068 | input=rep("", length(value)) 2069 | print("Type [c]ount, [d]ollars, [p]roportion, [r]atio, or [o]ther.") 2070 | for (i in 1:length(value)){ 2071 | line.input=readline(prompt=paste(acs.colnames(object)[i], " is currently in these units: ", value[i],". Change to what units?: (c,d,p,r,o)\n", sep="")) 2072 | if (line.input=="") {break} else {input[i]=line.input} 2073 | } 2074 | for (i in .acs.unit.levels){ 2075 | value[input==substr(start=1, stop=1,i)]=i} 2076 | } else{ 2077 | value=NA 2078 | warning(paste("prompt can only prompt for \"geography\", \"acs.units\", or \"acs.colnames\", not \"" 2079 | , what, "\"", sep=""))} 2080 | value 2081 | } 2082 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # acs 2 | 3 | Provides a general toolkit for downloading, managing, analyzing, and 4 | presenting data from the U.S. Census, including SF1 (Decennial 5 | short-form), SF3 (Decennial long-form), and the American Community 6 | Survey (ACS). Confidence intervals provided with ACS data are 7 | converted to standard errors to be bundled with estimates in complex 8 | acs objects. Package provides new methods to conduct standard 9 | operations on acs objects and present/plot data in statistically 10 | appropriate ways. 11 | 12 | ## Maintainer 13 | 14 | Ezra Haber Glenn 15 | 16 | ## Current version 17 | 18 | The current version of the package is 2.1.4, released in February, 19 | 2019. This *extremely* minor update corrects a problem related to the 20 | api urls used by the Census. 21 | 22 | No other aspects of the package were changed with this release. 23 | 24 | ## Previous versions 25 | 26 | Version 2.1.3 was released in March, 2018 to correct a problem related 27 | to acs.lookup for acs tables for 2016. This fix is more of a 28 | "workaround" than a true fix: starting with the 2016 release, the 29 | Census Bureau changed the format for the XML variable lookup tables 30 | and calls to acs.lookup (and acs.fetch) were failing; the quick 31 | solution was to simply use the 2015 lookup tables for these requests, 32 | which should be safe in most situations, since table numbers and 33 | variable codes generally do not change from year to year. (In some 34 | situations this assumption is not true: see 35 | https://www.census.gov/programs-surveys/acs/technical-documentation/table-and-geography-changes/2016/5-year.html 36 | for details.) 37 | 38 | Prior to this, previous versions (2.1.3, released in March 2018; 39 | 2.1.2, released in September 2017; 2.1.0 and 2.1.1, both released in 40 | July 2017) were minor updates to replace the package's dependency on 41 | RCurl (specifically, RCurl::urlGet and RCurl::url_exists) with similar 42 | httr functions and address some https/TLS incompatability issues 43 | between RCurl and users with Windows environments, all necessary to 44 | accommodate changes in the Census API format, including a shift to 45 | https transfer. Other changes included removing plyr from a 46 | "dependency" and simply importing the required "rbind.fill" function, 47 | and updating cbind/rbind options to be consistent with S3 methods. 48 | 49 | In March, 2016, acs version 2.0 was released, considered a substantial 50 | update over the previous version 1.2 due to (1) a major expansion in 51 | the number of datasets available and (2) a modification to the 52 | acs.fetch and acs.lookup options, which now require a user to explicitly 53 | specify "endyear=" for *all* calls. 54 | 55 | As of this version, the package provides full support for *all ACS, 56 | SF1, and SF3 data* currently available via the Census API, including 57 | ACS data from 2005-2015 and Decennial data from 1990, 2000, and 2010. 58 | 59 | You can track development of the `acs` package at 60 | http://eglenn.scripts.mit.edu/citystate/. 61 | 62 | 63 | ## Installation/Upgrading 64 | ### Installation 65 | 66 | To install the updated version, simply fire up an R session and type: 67 | 68 | ```R 69 | install.packages("acs", clean=T) 70 | ``` 71 | 72 | The package maintainer recommends two additional (optional) steps to 73 | improve performance: 74 | 75 | #### Installing or migrating an api key 76 | 77 | To use the package to download data via the American Community Survey 78 | application program interface (API), users need to request an API key 79 | from the Census. See 80 | http://www.census.gov/developers/tos/key_request.html. 81 | 82 | The package includes a function, api.key.install, to allow users to 83 | save their key in the package data directory, where it can be found 84 | and used automatically for future sessions: 85 | 86 | ```R 87 | > # do this once, you never need to do it again 88 | > api.key.install(key="592bc14cnotarealkey686552b17fda3c89dd389") 89 | ``` 90 | 91 | If a user has previously installed a key, it may be lost during the 92 | update process. If the "clean" option has been set as part of the 93 | update, the package configure scripts will attempt to migrate the key 94 | to a new location. Failing this, the install script will suggest that 95 | users run api.key.migrate() after installation, which might resolve 96 | the issue. 97 | ```R 98 | > api.key.migrate() 99 | ``` 100 | 101 | At worst, if both migration methods fail, you can simply re-run 102 | api.key.install() with your original key and be good to go. 103 | 104 | #### Installing census lookup tables 105 | 106 | To obtain variable codes and other metadata needed to access the 107 | Census API, both "acs.fetch" and "acs.lookup" must consult various XML 108 | lookup files, which are provided by the Census with each data release. 109 | As of version 2.0 these files are accessed online at run-time for each 110 | query (a change made to keep the package-size small to conform with 111 | CRAN policies). As an alternative to package-time installation of 112 | lookup tables, users may run "acs.tables.install()" after installation 113 | to download and archive all current tables (approximately 10MB, as of 114 | version 2.0 release). 115 | 116 | ```R 117 | > acs.tables.install() 118 | ``` 119 | 120 | Use of this function is completely optional and the package should 121 | work fine without it (assuming the computer is online and is able to 122 | access the lookup tables), but running it once will result in faster 123 | searches and quicker downloads for all subsequent sessions. (The 124 | results are saved and archived, so once a user has run the function, 125 | it is unnecessary to run again, unless the acs package is re-installed 126 | or updated.) 127 | 128 | 129 | ### Upgrading 130 | 131 | If you've previously installed the package, you can upgrade with: 132 | 133 | ```R 134 | update.packages("acs", clean=T) 135 | ``` 136 | 137 | Remember to re-run acs.tables.install() after upgrading (see above). 138 | 139 | ## Use 140 | 141 | The package includes a number of functions with advanced options, to 142 | allow users to work with data from the Census in any number of 143 | different ways. That said, the general workflow is fairly simple: 144 | 145 | + install and load the package, and (optionally) install an API key; 146 | 147 | + create a geo.set using the geo.make() function; 148 | 149 | + optionally, use the acs.lookup() function to explore the variables 150 | you may want to download; 151 | 152 | + use the acs.fetch() function to download data for your new 153 | geography; and then 154 | 155 | + use the existing functions in the package to work with your data. 156 | 157 | To learn more, consult the following: 158 | 159 | + the printed manual pages for the package; 160 | 161 | + ["Working with acs.R" (June 2013), Ezra Haber Glenn](http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2552524); 162 | 163 | + [The CityState webpage] (http://eglenn.scripts.mit.edu/citystate/ "CityState") 164 | 165 | 166 | ## Changes since previous version 167 | 168 | + endyear is now required: under the old package, acs.fetch and 169 | acs.lookup would default to endyear=2011 when no endyear was 170 | provided. This seemed smart at the time -- 2011 was the most 171 | recent data available -- but it is becoming increasingly absurd. 172 | One solution would have been to change the default to be whatever 173 | data is most recent, but that would have the unintended result of 174 | making the same script run differently from one year to the next: 175 | bad mojo. So the new preferred "version 1.3 solution" is to 176 | *require* users to explicitly indicate the endyear that they want 177 | to fetch each time. 178 | 179 | + New ACS Data: the package now provides on-board support for all 180 | endyears and spans currently available through the API, including: 181 | 182 | + American Community Survey 5-Year Data (2005-2009 through 2010-2015) 183 | 184 | + American Community Survey 3 Year Data (2013, 2012) 185 | 186 | + American Community Survey 1 Year Data (2015, 2014, 2013, 2012, 2011) 187 | 188 | See for more 189 | info, including guidance about which geographies are provided for 190 | each dataset. 191 | 192 | + Decennial Census Data: the package now includes the ability to 193 | download Decennial Data from the SF1 and SF3, using the same 194 | acs.fetch() function used for ACS data. Data includes: 195 | 196 | + SF1/Short-Form (1990, 2000, 2010) 197 | 198 | + SF3/Long-Form (1990, 2000) 199 | 200 | + Other improvements/updates/changes: 201 | 202 | + CPI tables: the CPI tables used for currency.year() and 203 | currency.convert() have been updated to include data up 204 | through 2015. 205 | 206 | + acs.fetching with saved acs.lookup results: the results of 207 | acs.lookup can still be saved and passed to acs.fetch via the 208 | "variable=" option, with a slight change: under v. 1.2, the 209 | passed acs.lookup results would overrule any explicit endyear or 210 | span; with v. 1.3, the opposite is true (the endyear and span in 211 | the acs.lookup results are ignored by acs.fetch). This may seem 212 | insignificant, but it will eventually be important, when users 213 | want to fetch data from years that are more recent than the 214 | version of the package, and need to use old lookup results to do 215 | so. 216 | 217 | + divide.acs fixes: the package includes a more robust divide.acs() 218 | function, which handles zero denominators better and takes full 219 | advantage of the potential for reduced standard errors when 220 | dividing proportions. 221 | 222 | ## Additional notes, details, issues 223 | 224 | + treatment of SF1/SF3 data: When fetched via acs.fetch(), this data 225 | is downloaded and converted to acs-class objects. (Note: standard 226 | errors for Decennial data will always be zero, which is technically 227 | not correct for SF3 survey data, but no margins of error are 228 | reported by the API.) See 229 | 230 | for more info. 231 | 232 | + 1990 table names and numbers: Census support for the 1990 data has 233 | been a bit inconsistent -- the variable lookup tables were not in 234 | the same format as others, and far less descriptive information has 235 | been provided about table and variable names. This can make it 236 | tricky to find and fetch data, but if you know what you want, you 237 | can probably find it; looking in the files in package's extdata 238 | directory might help give you a sense of what the variable codes 239 | and table numbers look like. 240 | -------------------------------------------------------------------------------- /cleanup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | printf "cleanup:\n" 4 | printf " checking whether archived api.key exists\n" 5 | 6 | if [ -e "${R_LIBRARY_DIR}/api.key-holder.rda" ] 7 | then 8 | printf " api.key exists: migrating...\n" 9 | mkdir "${R_LIBRARY_DIR}/acs/extdata" 10 | mv "${R_LIBRARY_DIR}/api.key-holder.rda" "${R_LIBRARY_DIR}/acs/extdata/key.rda" 11 | fi 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | printf "checking whether api.key exists\n" 4 | 5 | if [ -e "${R_LIBRARY_DIR}/00LOCK-acs/acs/extdata/key.rda" ] 6 | then 7 | printf "api.key exists:\n archiving as ${R_LIBRARY_DIR}/api.key-holder.rda\n" 8 | cp "${R_LIBRARY_DIR}/00LOCK-acs/acs/extdata/key.rda" "${R_LIBRARY_DIR}/api.key-holder.rda" 9 | printf " if install/cleanup process does not confirm api.key migration\n use:\n\n > api.key.migrate()\n\n to ensure proper migration of key\n" 10 | fi 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /data/cpi.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/cpi.rda -------------------------------------------------------------------------------- /data/datalist: -------------------------------------------------------------------------------- 1 | cpi 2 | fips.american.indian.area 3 | fips.county 4 | fips.county.subdivision 5 | fips.place 6 | fips.school 7 | fips.state 8 | kansas07 9 | kansas09 10 | lawrence10 11 | -------------------------------------------------------------------------------- /data/fips.american.indian.area.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/fips.american.indian.area.rda -------------------------------------------------------------------------------- /data/fips.county.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/fips.county.rda -------------------------------------------------------------------------------- /data/fips.county.subdivision.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/fips.county.subdivision.rda -------------------------------------------------------------------------------- /data/fips.place.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/fips.place.rda -------------------------------------------------------------------------------- /data/fips.school.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/fips.school.rda -------------------------------------------------------------------------------- /data/fips.state.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/fips.state.rda -------------------------------------------------------------------------------- /data/kansas07.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/kansas07.rda -------------------------------------------------------------------------------- /data/kansas09.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/kansas09.rda -------------------------------------------------------------------------------- /data/lawrence10.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cran/acs/eca27424a419d37e662376626d6bd08b3099df30/data/lawrence10.rda -------------------------------------------------------------------------------- /man/acs-class.Rd: -------------------------------------------------------------------------------- 1 | \name{acs-class} 2 | \Rdversion{1.1} 3 | \docType{class} 4 | \alias{acs-class} 5 | \alias{acs.colnames,acs-method} 6 | \alias{acs.units,acs-method} 7 | \alias{-,acs,acs-method} 8 | \alias{-,acs,numeric-method} 9 | \alias{-,numeric,acs-method} 10 | \alias{/,acs,acs-method} 11 | \alias{/,acs,numeric-method} 12 | \alias{/,numeric,acs-method} 13 | \alias{[<-,acs-method} 14 | \alias{[,acs-method} 15 | \alias{*,acs,acs-method} 16 | \alias{*,acs,numeric-method} 17 | \alias{*,numeric,acs-method} 18 | \alias{+,acs,acs-method} 19 | \alias{+,acs,numeric-method} 20 | \alias{+,numeric,acs-method} 21 | \alias{estimate,acs-method} 22 | \alias{modified,acs-method} 23 | \alias{show,acs-method} 24 | \alias{span,acs-method} 25 | \alias{standard.error,acs-method} 26 | \alias{summary,acs-method} 27 | \alias{estimate} 28 | \alias{modified} 29 | \alias{span} 30 | \alias{standard.error} 31 | \alias{acs.colnames} 32 | \alias{acs.units} 33 | \alias{dim.acs} 34 | \alias{length.acs} 35 | \alias{acs.colnames<-} 36 | \alias{acs.units<-} 37 | \alias{is.acs} 38 | \alias{span<-} 39 | \alias{apply} 40 | \alias{acs.colnames<-,acs-method} 41 | \alias{acs.units<-,acs-method} 42 | \alias{is.acs} 43 | \alias{span<-,acs-method} 44 | \alias{apply,acs-method} 45 | 46 | \title{Class \code{"acs"}} 47 | \description{ 48 | 49 | The acs class provides a convenient wrapper for demographic data from 50 | the U.S. Census, especially the American Community Survey. Estimates 51 | and standard errors are kept together, along with geographic information 52 | and metadata necessary to manipulate and analyze data in this form. 53 | 54 | } 55 | \section{Objects from the Class}{ 56 | 57 | acs objects can be created by calls of the form \code{new("acs", ...)}, 58 | or through helper functions provided by the package (currently 59 | \code{read.acs} and \code{acs.fetch}), or from the output of 60 | subsetting or other calls on existing acs objects. Once created, acs 61 | objects can be manipulated through new methods to deal appropriately 62 | with common analytical tasks such as combining subgroups or 63 | geographies, mathematical operations on estimates, and computing (and 64 | plotting) confidence intervals. 65 | 66 | } 67 | \section{Slots}{ 68 | \describe{ 69 | 70 | \item{\code{endyear}:}{Object of class \code{"integer"} indicating 71 | the last year included in the dataset (e.g., 2012 for data from the 72 | 2008--2012 ACS)} 73 | 74 | \item{\code{span}:}{Object of class \code{"integer"} representing the 75 | number of years the dataset spans (e.g., 3 for data from the 76 | 2011--2013 ACS); for decennial census datasets (SF1 and SF3), span = 77 | 0.} 78 | 79 | \item{\code{geography}:}{Object of class \code{"data.frame"} containing 80 | columns extracted from the data's geographic header: typically 81 | includes geographic place names, census summary level values, and 82 | unique numeric identifiers, but can contain any geographic names or 83 | labels desired. When acs objects are created or modified, the first 84 | geography column will be used to label estimates and standard 85 | errors.} 86 | 87 | \item{\code{acs.colnames}:}{Object of class \code{"character"} giving 88 | the variable names for each column } 89 | 90 | \item{\code{modified}:}{Object of class \code{"logical"} to indicate 91 | whether the object has been modified since construction } 92 | 93 | \item{\code{acs.units}:}{Object of class \code{"factor"} designating the 94 | type of units in each column (e.g., count or percentage or dollars); 95 | only used minimally, to check appropriateness of some operations; 96 | mostly reserved for future functionality} 97 | 98 | \item{\code{currency.year}:}{Object of class \code{"integer"} indicating 99 | the year that all currency values have been adjusted to (by default 100 | the same as endyear, but able to be modified by the user for 101 | comparisons with other years; see \code{\link{currency.convert}}.)} 102 | 103 | \item{\code{estimate}:}{Object of class \code{"matrix"} holding 104 | the reported ACS estimates} 105 | 106 | \item{\code{standard.error}:}{Object of class \code{"matrix"} holding 107 | the calculated values of the standard errors for each estimate, 108 | derived from the reported 90\% confidence intervals } 109 | 110 | 111 | } 112 | } 113 | \section{Methods}{ 114 | \describe{ 115 | \item{acs.colnames}{\code{signature(object = "acs")}: Standard 116 | accessor function; returns character vector } 117 | \item{acs.units}{\code{signature(object = "acs")}: Standard 118 | accessor function; returns factor vector } 119 | \item{currency.year}{\code{signature(object = "acs")}: Standard accessor function; returns integer } 120 | \item{endyear}{\code{signature(object = "acs")}: Standard accessor function; returns integer } 121 | \item{estimate}{\code{signature(object = "acs")}: Standard accessor 122 | function; returns matrix } 123 | \item{geography}{\code{signature(object = "acs")}: Standard accessor 124 | function; returns data.frame } 125 | \item{modified}{\code{signature(object = "acs")}: Standard accessor 126 | function; return logical } 127 | \item{span}{\code{signature(object = "acs")}: Standard accessor function; returns integer } 128 | \item{standard.error}{\code{signature(object = "acs")}: Standard 129 | accessor function; returns matrix } 130 | 131 | \item{sum}{\code{signature(object = "acs")}: Aggregates (adds) all 132 | estimates in the object, and adds the corresponding standard 133 | errors in a statistically appropriate way; returns new acs object} 134 | 135 | \item{summary}{\code{signature(object = "acs")}: Prints standard summary data on both estimates 136 | and standard errors} 137 | \item{confint}{\code{signature(object = "acs")}: Prints estimates 138 | with confidence intervals} 139 | % \item{-}{\code{signature(e1 = "acs", e2 = "acs")}: Subtract one 140 | % estimate from another; deal appropriately with standard error 141 | % (\code{sqrt(standard.error(e1)^2+standard.error(e2)^2} } 142 | % \item{-}{\code{signature(e1 = "acs", e2 = "numeric")}: Subtract a 143 | % standard number from an estimate; deal appropriately with standard error 144 | % (\code{sqrt(standard.error(e1)} } 145 | % \item{-}{\code{signature(e1 = "numeric", e2 = "acs")}: Subtract an estimate 146 | % from a standard number; deal appropriately with standard error 147 | % (\code{sqrt(standard.error(e2)} } 148 | % \item{/}{\code{signature(e1 = "acs", e2 = "acs")}: Divide one 149 | % estimate by another; deal appropriately with standard error. (Assumes that numerator 150 | % is NOT a subset of denominator.) } 151 | % \item{/}{\code{signature(e1 = "acs", e2 = "numeric")}: ... } 152 | % \item{/}{\code{signature(e1 = "numeric", e2 = "acs")}: ... } 153 | \item{[}{\code{signature(x = "acs")}: subsetting works for acs objects 154 | using standard \code{[i,j]} square bracket notation, similar to 155 | two-dimensional matrices; returns a new acs object with estimates, 156 | standard errors, and associated metadata for "i" rows (geographies) and 157 | "j" columns (variable columns); essentially, subsetting for this class is 158 | structured to mirror standard operations on matrix objects} 159 | 160 | \item{[<-}{\code{signature(x = "acs")}: new values may be 161 | replaced/assigned to an existing acs object using standard 162 | \code{[i,j]} bracket notation. The assignment can accept a number 163 | of different forms: a valid acs object (including a subsetted one), 164 | a list of two matrices (ideally named "estimate" and "error" or 165 | "standard.error"), or a numeric object which may be coerced into a 166 | matrix (to be used as estimates, with zero-values assigned to 167 | corresponding standard errors). } 168 | % \item{*}{\code{signature(e1 = "acs", e2 = "acs")}: ... } 169 | % \item{*}{\code{signature(e1 = "acs", e2 = "numeric")}: ... } 170 | % \item{*}{\code{signature(e1 = "numeric", e2 = "acs")}: ... } 171 | % \item{+}{\code{signature(e1 = "acs", e2 = "acs")}: ... } 172 | % \item{+}{\code{signature(e1 = "acs", e2 = "numeric")}: ... } 173 | % \item{+}{\code{signature(e1 = "numeric", e2 = "acs")}: ... } 174 | } 175 | 176 | In addition to these methods, new methods for basic arithmetic 177 | functions (+, -, *, /) have been provided to deal appropriately 178 | with combining estimates and standard errors. } 179 | 180 | \author{ 181 | Ezra Haber Glenn \email{eglenn@mit.edu} 182 | } 183 | 184 | \examples{ 185 | showClass("acs") 186 | # load some data from the ACS 187 | data(kansas09) 188 | str(kansas09) 189 | 190 | # access slots 191 | endyear(kansas09) 192 | span(kansas09) 193 | estimate(kansas09)[1:5,1:5] 194 | standard.error(kansas09[1:5,1:5]) 195 | 196 | 197 | # subset 198 | kansas09[1:4,6:9] 199 | 200 | # more complicated subsets 201 | kansas09[c("Linn County, Kansas", "Wilson County, Kansas") , 202 | grep(pattern="21.years", x=acs.colnames(kansas09))] 203 | 204 | # addition on estimates and errors 205 | kansas09[1:4,25]+kansas09[1:4,49] 206 | 207 | # can even multiply and divide 208 | # males per female, by county 209 | kansas09[1:4,2]/kansas09[1:4,26] 210 | 211 | # (males<5 plus females<5) * 12 212 | (kansas09[7,3]+kansas09[7,27]) * 12 213 | 214 | # some replacement: males<5 as a percentage of all males 215 | kansas09[,3]=kansas09[,3]/kansas09[,2] 216 | } 217 | 218 | \keyword{classes} 219 | -------------------------------------------------------------------------------- /man/acs-package.Rd: -------------------------------------------------------------------------------- 1 | \name{acs-package} 2 | \alias{acs-package} 3 | \alias{acs} 4 | \docType{package} 5 | \title{ 6 | Download, Manipulate, and Present American Community Survey and 7 | Decennial Data from the US Census 8 | } 9 | \description{ 10 | 11 | Provides a general toolkit for downloading, managing, analyzing, and 12 | presenting data from the U.S. Census, including SF1 (Decennial 13 | "short-form"), SF3 (Decennial "long-form"), and the American Community 14 | Survey (ACS). Confidence intervals provided with ACS data are 15 | converted to standard errors to be bundled with estimates in complex 16 | acs objects. Package provides new methods to conduct standard 17 | operations on acs objects and present/plot data in statistically 18 | appropriate ways.} 19 | 20 | \details{ \tabular{ll}{ Package: \tab acs\cr Type: \tab Package\cr 21 | Version: \tab 2.1.4\cr Date: \tab 2018-02-14\cr License: \tab GPL-3\cr 22 | Depends: \tab stringr, methods, XML\cr } 23 | 24 | The package defines a new "acs" class (containing estimates, standard 25 | errors, geography, and metadata for tables from the U.S. Census 26 | American Community Survey), with methods to deal appropriately with 27 | common tasks, such as combining subgroups or geographies, mathematical 28 | operations on estimates, tests of significance, and computing (and 29 | plotting) confidence intervals. 30 | 31 | } 32 | \author{ 33 | Ezra Haber Glenn \email{eglenn@mit.edu} 34 | } 35 | \references{ 36 | \enumerate{ 37 | 38 | \item{"A Compass for Understanding and Using American Community Survey 39 | Data: What State and Local Governments Need to Know." Washington, DC: 40 | U.S. Census Bureau. 41 | 2009. \url{http://www.census.gov/library/publications/2009/acs/state-and-local.html}.} 42 | 43 | \item{"acs.R: An R Package for Neighborhood-Level Data from the 44 | U.S. Census." Ezra Haber Glenn, Department of Urban Studies and 45 | Planning, Massachusetts Institute of Technology. Presented at the 46 | Computers in Urban Planning and Urban Management Conference, July 6, 47 | 2011. 48 | \url{http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2171390}.} 49 | 50 | \item{"Working with acs.R (June 2013)", Ezra Haber Glenn. 51 | \url{http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2552524}} 52 | 53 | \item{CityState webpage: \url{http://eglenn.scripts.mit.edu/citystate/}} 54 | 55 | \item{User Group Mailing List: \url{http://mailman.mit.edu/mailman/listinfo/acs-r}} 56 | } 57 | } 58 | \keyword{ package } 59 | \keyword{ manip } 60 | -------------------------------------------------------------------------------- /man/acs.fetch.Rd: -------------------------------------------------------------------------------- 1 | \name{acs.fetch} 2 | \alias{acs.fetch} 3 | \alias{api.url.maker} 4 | 5 | 6 | 7 | \title{ Downloads demographic data (ACS, SF1, SF3) via the Census API 8 | and converts to a proper acs object with estimates, standard errors, and 9 | associated metadata.} 10 | 11 | \description{ When passed a valid geo.set object and either lookup terms 12 | (table.number, table.name, keyword) or a valid acs.lookup object, 13 | queries the Census API and downloads data to create a new acs-class 14 | object. Geographical information is preserved, metadata in bundled 15 | together with the acs object, and margins of errors are converted to 16 | standard errors to accompany estimates (see \code{help(acs)}).} 17 | 18 | \usage{ 19 | acs.fetch(endyear, span = 5, geography, table.name, 20 | table.number, variable, keyword, dataset = "acs", 21 | key, col.names = "auto", ...) 22 | } 23 | %- maybe also 'usage' for other objects documented here. 24 | \arguments{ 25 | \item{endyear}{an integer indicating the latest year of the data in the 26 | survey (e.g., for data from the 2007-2011 5-year ACS data, endyear would 27 | be 2011)} 28 | 29 | \item{span}{an integer indicating the span (in years) of the desired ACS 30 | data (should be 1, 3, or 5 for ACS datasets, and 0 for decennial 31 | census SF1 and SF3 datasets); defaults to 5, but ignored and reset 32 | to 0 if dataset="sf1" or "sf3".} 33 | 34 | \item{geography}{a valid geo.set object specifying the census 35 | geography or geographies to be fetched; can be created "on the fly" 36 | with a call to \code{geo.make()} } 37 | 38 | \item{table.name}{a string giving the search term(s) to find in the 39 | name of the ACS census table (for example, "Sex" or "Age"); accepts 40 | multiple words, which must all be found in the returned table names; 41 | always case-sensitive. (Note: when set, this variable is passed to 42 | an internal call to acs.lookup---see 43 | \code{\link{acs.lookup}}).} 44 | 45 | \item{table.number}{a string (not a number) indicating the table from 46 | the Census to fetch; examples: "B01003" or "B23013"; always 47 | case-sensitive. Used to fetch all variables for a given table 48 | number; if "table.number" is provided, other lookup variables 49 | ("table.name" or "keyword") will be ignored.} 50 | 51 | \item{variable}{an object of acs.lookup class, or a string (not a 52 | number) or vector of strings indicating the exact variable 53 | number(s) the Census to fetch. See details for more. 54 | Non-acs.lookup examples include "B01003_001" or "B23013_003" or 55 | c("B01003_001", "B23013_003"). Used to fetch specific variables, 56 | as opposed to all variables for a given table number; if 57 | "variable" is provided, all other lookup variables ("table.name", 58 | "table.number", and "keyword") will be ignored. } 59 | 60 | \item{keyword}{a string or vector of strings giving the search 61 | term(s) to find in the name of the census variable (for example, 62 | "Male" or "Haiti"); accepts multiple words, which must all be 63 | found in the returned variable names; always case-sensitive. 64 | (Note: when set, this variable is passed to an internal call to 65 | acs.lookup---see \code{\link{acs.lookup}}).} 66 | 67 | \item{dataset}{either "acs" (the default), "sf1", or "sf3", indicating 68 | whether to fetch data from in the American Community Survey or the 69 | SF1/SF3 datasets. See details for more information about available 70 | data.} 71 | 72 | \item{key}{a string providing the Census API key to use for when 73 | fetching data. Typically saved once via \code{api.key.install} 74 | and passed automatically with each call; see 75 | \code{\link{api.key.install}}} 76 | 77 | \item{col.names}{either "auto","pretty", or a vector of strings of 78 | the same length as the number of variables to be fetched. When 79 | "auto" (the default), census variable codes will be used as column 80 | names for the fetched data; when "pretty", descriptive variables 81 | names will be used; otherwise col.names will be used.} 82 | 83 | \item{\dots}{ Not used interactively (reserved for recursive calls). 84 | }} 85 | 86 | \details{ 87 | 88 | Assuming you have created some geography with geo.make and you have 89 | already installed an API key, the call is quite simple: for example, 90 | \code{acs.fetch(endyear=2014, geography=my.geo, table.number="B01003")}. 91 | (For more on API keys, see \code{\link{api.key.install}}; if you haven't 92 | installed one, you can always add a "key=YOUR.KEY.HERE" argument to 93 | \code{acs.fetch} each time.) 94 | 95 | By default, acs.fetch will download 5-year ACS, but as of version 2.0 96 | users must specify a specific "endyear". Users may also select 1- or 97 | 3-year ACS data using the "span=" option, as well as Decennial data 98 | using the "dataset" option. (When dataset="sf1" or "sf3", span will be 99 | reset to 0 regardless of any explict or default options.) At present, 100 | the API provides five-, three- and one-year data for a variety of 101 | different endyears, and Decennial data for 2010, 2000, and 1990; see the 102 | chart below and/or visit 103 | \url{http://www.census.gov/data/developers/data-sets.html} to learn more 104 | about what is available through the API. (Warning: support for 1990 is 105 | a bit unreliable as of the date of this version, due to non-standard 106 | variable lookup tables.) 107 | 108 | \itemize{ \item{American Community Survey 5-Year Data (dataset="acs", 109 | span=5): 2005-2009 through 2010-2014} 110 | 111 | \item{American Community Survey 3 Year Data (dataset="acs", span=3): 112 | 2013, 2012} 113 | 114 | \item{American Community Survey 1 Year Data (dataset="acs", span=1): 115 | 2014, 2013, 2012, 2011} 116 | 117 | \item{SF1/Short-Form (dataset="sf1"): 1990, 2000, 2010} 118 | 119 | \item{SF3/Long-Form (dataset="sf3"): 1990, 2000} 120 | 121 | } 122 | 123 | Downloading based on a table number is probably the most fool-proof way 124 | to get the data you want, but acs.fetch will also accept a number of 125 | other arguments instead of "table.number". Users can provide strings to 126 | search for in table names (e.g., table.name="Age by Sex" or 127 | table.name="First Ancestry Reported") or keywords to find in the names 128 | of variables (e.g., keyword="Male" or keyword="Haiti")---but be warned: 129 | given how many tables there are, you may get more matches than you 130 | expected and suffer from the "download overload" of fast-scrolling 131 | screens full of data. (But don't lose hope: see the 132 | \code{\link{acs.lookup}} tool, which can help with this problem.) 133 | 134 | On the other hand, if you know you want a specific variable or two (not 135 | a whole table, just a few columns of it, such as variable="B05001_006" 136 | or variable=c("B16001_058", "B16001_059")), you can ask for that with 137 | \code{acs.fetch(variable="these.variable.codes", ...)}. 138 | 139 | Note: when "combine=T" for the fetched geo.set, data will be aggregated 140 | in the resulting acs abject. Some users may therefore wish to specify 141 | "one.zero=T" as an additional argument to \code{acs.fetch}; see 142 | \code{\link{sum-methods}}. } 143 | 144 | \value{Returns a new acs-class object with estimates, standard errors 145 | (derived from the census 90\% margins of error), and metadata of the 146 | fetched data from the Census API. } 147 | 148 | \references{ 149 | \enumerate{ 150 | \item{\url{http://www.census.gov/developers/}} 151 | \item{\url{http://www.census.gov/data/developers/data-sets.html}} 152 | }} 153 | \author{ 154 | Ezra Haber Glenn \email{eglenn@mit.edu} 155 | } 156 | 157 | 158 | \seealso{ 159 | \code{\link{acs.lookup}}. 160 | } 161 | 162 | -------------------------------------------------------------------------------- /man/acs.lookup-class.Rd: -------------------------------------------------------------------------------- 1 | \name{acs.lookup-class} 2 | \Rdversion{1.1} 3 | \docType{class} 4 | \alias{acs.lookup-class} 5 | \alias{is.acs.lookup} 6 | \alias{results} 7 | \alias{+,acs.lookup,acs.lookup-method} 8 | \alias{c,acs.lookup-method} 9 | \alias{endyear,acs.lookup-method} 10 | \alias{show,acs.lookup-method} 11 | \alias{[,acs.lookup-method} 12 | \alias{results,acs.lookup-method} 13 | \alias{span,acs.lookup-method} 14 | 15 | \title{Class \code{"acs.lookup"}} 16 | 17 | \description{ A new class to hold the results of calls to 18 | \code{acs.lookup}, typically for possible modification and then passing 19 | to calls to \code{acs.fetch} (using the "variable=" argument). } 20 | 21 | \section{Objects from the Class}{ Objects can be created by calls of the 22 | form \code{new("acs.lookup", ...)}, but more typically will be created 23 | as output from calls to \code{acs.lookup}. } 24 | 25 | \section{Slots}{ 26 | \describe{ 27 | \item{\code{endyear}:}{Object of class \code{"numeric"} indicating 28 | the year of the census dataset; e.g., for data from the 2005-2009 ACS, 29 | endyear=2009} 30 | \item{\code{span}:}{Object of class \code{"numeric"} indicating 31 | the span in years of the census dataset; e.g., for data from the 2005-2009 ACS, 32 | span=5. For decennial census datasets (SF1 and SF3), span = 33 | 0.} 34 | \item{\code{args}:}{Object of class \code{"list"} containing the 35 | search terms used in the call to \code{acs.lookup}, including some or 36 | all of: keyword, table.name, endyear, dataset, table.number, and case.sensitive.} 37 | \item{\code{results}:}{Object of class \code{"data.frame"} 38 | containing character strings in four columns: variable.code, 39 | table.number, table.name, and variable.name.} 40 | } 41 | } 42 | \section{Methods}{ 43 | \describe{ 44 | \item{+}{\code{signature(e1 = "acs.lookup", e2 = "acs.lookup")}: 45 | used for combining two acs.lookup objects into one } 46 | \item{c}{\code{signature(x = "acs.lookup")}: used for combining two 47 | acs.lookup objects into one } 48 | \item{endyear}{\code{signature(object = "acs.lookup")}: returns 49 | endyear from acs.lookup object } 50 | \item{[}{\code{signature(object = "acs.lookup")}: used for 51 | subsetting an acs.lookup object } 52 | \item{results}{\code{signature(object = "acs.lookup")}: returns 53 | results (as dataframe) from acs.lookup object } 54 | \item{span}{\code{signature(object = "acs.lookup")}: returns 55 | span from acs.lookup object } 56 | } 57 | } 58 | 59 | \author{ 60 | Ezra Haber Glenn \email{eglenn@mit.edu} 61 | } 62 | 63 | \seealso{ 64 | \code{\link{acs.lookup}} 65 | } 66 | \examples{ 67 | showClass("acs.lookup") 68 | } 69 | \keyword{classes} 70 | -------------------------------------------------------------------------------- /man/acs.lookup.Rd: -------------------------------------------------------------------------------- 1 | \name{acs.lookup} 2 | \alias{acs.lookup} 3 | 4 | \title{ Search for relevant demographic variables and tables from the US 5 | Census. } 6 | 7 | \description{ The \code{acs.fetch} function is used to download data 8 | from the US Census American Community Survey. The \code{acs.lookup} 9 | function provides a convenience function to use in advance to locate 10 | tables and variables that may be of interest. 11 | 12 | \code{acs.lookup} takes arguments similar to \code{acs.fetch} --- in 13 | particular, "table.number", "table.name", and "keyword", as well as 14 | "endyear","span", and "dataset" --- and searches for matches in the 15 | meta-data of the Census tables. When multiple search terms are passed 16 | to a given argument (e.g., \code{keyword=c("Female", "GED")}), the 17 | tool returns matches where ALL of the terms are found; similarly, when 18 | more than one lookup argument is used (e.g., 19 | \code{table.number="B01001", keyword="Female"}), the tool searches for 20 | matches that include all of the terms (i.e., terms are combined with a 21 | logical "AND", not a logical "OR"). 22 | 23 | Results from acs.lookup --- which are acs.lookup class objects --- can 24 | then be inspected, subsetted (with [square brackets]), and combined 25 | (with \code{c} or \code{+}) to create custom acs.lookup objects to 26 | store and later pass to \code{acs.fetch}. 27 | 28 | } 29 | 30 | \usage{ 31 | acs.lookup(endyear, span = 5, dataset = "acs", keyword, 32 | table.name, table.number, case.sensitive = T) 33 | } 34 | %- maybe also 'usage' for other objects documented here. 35 | \arguments{ 36 | 37 | \item{endyear}{an integer indicating the latest year of the data in 38 | the survey (e.g., for data from the 2007-2011 5-year ACS data, 39 | endyear would be 2011; limited by acceptable values currently 40 | provided by the Census API); for 2016 and later, the 2015 lookup 41 | tables are used (see details).} 42 | 43 | \item{span}{an integer indicating the span (in years) of the desired 44 | ACS data (should be 1, 3, or 5); defaults to 5. Ignored and reset 45 | to 0 if dataset="sf1" or "sf3".} 46 | 47 | \item{dataset}{either "acs" (the default), "sf1", or "sf3", indicating 48 | whether to look for tables and variables in the American Community 49 | Survey, the SF1 dataset (decennial/"short-form"), or the SF3 dataset 50 | (decennial/"long-form").} 51 | 52 | \item{keyword}{ a string or vector of strings giving the search 53 | term(s) to find in the name of the ACS census variable (for 54 | example, "Male" or "Haiti"); accepts multiple words, which must 55 | all be found in the returned variable names. } 56 | 57 | \item{table.name}{a string giving the search term(s) to find in the 58 | name of the ACS census table (for example, "Sex" or "Age" or "Age 59 | by Sex"); accepts multiple words, which must all be found in the 60 | returned table names. } 61 | 62 | \item{table.number}{a string (not a number) indicating the desired 63 | table from the Census to fetch; examples: "B01003" or "B23013"; 64 | always case-sensitive. Used to identify all variables for a given 65 | table number. } 66 | 67 | \item{case.sensitive}{a logical flag indicating whether searching is 68 | case-sensitive (the default) or not. Note that the Census is not 69 | entirely consistent in capitalization in table and variable names, 70 | so setting \code{case.sensitive=F} may be useful in finding all 71 | possible matches.} 72 | } 73 | 74 | \details{ 75 | 76 | In many cases, \code{acs.lookup} is called internally by 77 | \code{acs.fetch}, to determine the variable codes to use for a given 78 | table.name or table.number. Since each lookup involves a search of 79 | static XML tables (provided by the census for each endyear/span 80 | combination, and included by the acs package in /extdata), searches 81 | involving more recent years (e.g., for version 2.0, endyears > 2014) may 82 | fail. In such situations, users may wish to call \code{acs.fetch} with 83 | the "variable=" option, perhaps reusing variables from a saved 84 | \code{acs.lookup} search for a previous year. 85 | 86 | For example, once the 2011-2015 5-year ACS data is available via the 87 | API, users can attempt the following to access Table B01003, even before 88 | the new version of the package is installed with the correct variable 89 | lookup tables: \code{acs.fetch(endyear=2015, span=5, 90 | variable=acs.lookup(endyear=2014, span=5, table.number="B01003"))}. 91 | 92 | Note: version 2.1.3 of the package implements a "workaround" to address a 93 | problem accessing data from 2016, when the Census Bureau seems to have 94 | changed the format for their XML variable lookup tables, causing calls 95 | to acs.lookup (and acs.fetch) to fail for "endyear=2016". The 96 | (hopefully) temporary solution was to simply use the 2015 lookup tables 97 | for these requests, which should be safe in most situations, since table 98 | numbers and variable codes generally do not change from year to year. 99 | In certain situations, this may not be true: see 100 | \url{https://www.census.gov/programs-surveys/acs/technical-documentation/table-and-geography-changes/2016/5-year.html}.} 101 | 102 | \value{ Returns an acs.lookup class object with the results of the 103 | query. acs.lookup objects can be subsetted and combined, and passed 104 | to the "variable" argument of \code{acs.fetch}. } 105 | 106 | \author{ 107 | Ezra Haber Glenn \email{eglenn@mit.edu} 108 | } 109 | 110 | \seealso{ 111 | \code{\link{acs.lookup-class}} 112 | } 113 | 114 | \examples{ 115 | \dontrun{acs.lookup(endyear=2014, span=5, table.number="B01001") 116 | acs.lookup(endyear=2012, span=1, table.number="B01001", keyword="Female") 117 | acs.lookup(endyear=2012, span=1, keyword=c("Female", "GED")) 118 | acs.lookup(endyear=2000, dataset="sf3", table.number="P56") 119 | acs.lookup(endyear=1990, dataset="sf3", table.number="H058") 120 | age.by.sex=acs.lookup(endyear=2014, span=5, table.name="Age by Sex") 121 | age.by.sex 122 | workers.age.by.sex=age.by.sex[4:6] 123 | workers.age.by.sex 124 | } 125 | } 126 | 127 | -------------------------------------------------------------------------------- /man/acs.tables.install.Rd: -------------------------------------------------------------------------------- 1 | \name{acs.tables.install} 2 | \alias{acs.tables.install} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | 5 | \title{ 6 | Downloads and stores XML tables used to lookup variable codes, table 7 | names, and other metadata associated with acs package. 8 | } 9 | 10 | \description{ To obtain variable codes and other metadata needed to 11 | access the Census API, both \code{acs.fetch} and \code{acs.lookup} 12 | must consult various XML lookup files, which are provided by the 13 | Census with each data release. To keep the acs package-size small, as 14 | of version 2.0 these files are accessed online at run-time for each 15 | query. As an alternative, users may use \code{acs.tables.install} to 16 | download and archive all current tables (approximately 10MB, as of 17 | version 2.0 release). 18 | 19 | Use of this function is completely optional and the package should 20 | work fine without it (assuming the computer is online and is able to 21 | access the lookup tables), but running it once may result in faster 22 | searches and quicker downloads for all subsequent sessions. (The 23 | results are saved and archived, so once a user has run the function, 24 | it is unnecessary to run again, unless the acs package is re-installed 25 | or updated.) } 26 | 27 | \usage{ 28 | acs.tables.install() } 29 | 30 | \value{ 31 | Downloads the files and saves them to the package's "extdata" 32 | directory; return an error if no files found. 33 | } 34 | \references{ 35 | \url{http://www.census.gov/data/developers/data-sets.html} 36 | } 37 | \author{ 38 | Ezra Haber Glenn \email{eglenn@mit.edu} 39 | } 40 | 41 | \seealso{ 42 | \code{\link{acs.fetch}} 43 | \code{\link{acs.lookup}}} 44 | -------------------------------------------------------------------------------- /man/api.key.install.Rd: -------------------------------------------------------------------------------- 1 | \name{api.key.install} 2 | \alias{api.key.install} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | 5 | \title{ 6 | Installs an API key from the US Census to use with calls 7 | to \code{acs.fetch}. 8 | } 9 | \description{ 10 | The \code{acs.fetch} function requires an "API key" to use when 11 | downloading data from the US Census API. Rather than pass this rather 12 | long string to the function each time, users can save the key as part of 13 | the package installation, using the \code{api.key.install} function. 14 | Once installed, an api key is saved on the system and available for use 15 | in future sessions. (To replace a key, simply call the function again 16 | with the new key.) 17 | } 18 | \usage{ 19 | api.key.install(key, file = "key.rda") 20 | } 21 | %- maybe also 'usage' for other objects documented here. 22 | \arguments{ 23 | \item{key}{ 24 | The API key provided to the user upon registering with the US Census 25 | Developer's page. A string. 26 | } 27 | \item{file}{ 28 | An alternate name to use when storing key; reserved for future use. 29 | } 30 | } 31 | 32 | \value{ 33 | Saves the key and exits silently, unless an error is encountered. 34 | } 35 | \details{ 36 | 37 | The requirement for a key seems to be laxly enforced by the Census API, 38 | but is nonetheless coded into the acs package. Users without a key may 39 | find success by simply installing a blank key (i.e., key="") via 40 | \code{api.key.install(key="")}; similarly, calls to \code{acs.fetch} and 41 | \code{geo.make(..., check=T)} may succeed with a \code{key=""} argument. 42 | Note that while this may work today, it may fail in the future if the 43 | API decides to start enforcing the requirement. 44 | 45 | } 46 | \references{ 47 | To request an API key, see \url{http://www.census.gov/developers/} 48 | } 49 | \author{ 50 | Ezra Haber Glenn \email{eglenn@mit.edu} 51 | } 52 | 53 | \seealso{ 54 | \code{\link{acs.fetch}} 55 | } 56 | -------------------------------------------------------------------------------- /man/api.key.migrate.Rd: -------------------------------------------------------------------------------- 1 | \name{api.key.migrate} 2 | \alias{api.key.migrate} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | 5 | \title{ 6 | After updating the acs package, installs an archived API key from a 7 | previous installation. 8 | } 9 | \description{ 10 | The \code{acs.fetch} function requires an "API key" to use when 11 | downloading data from the US Census API. Rather than pass this rather 12 | long string to the function each time, users can save the key as part of 13 | the package installation, using the \code{api.key.install} function. 14 | Once installed, an api key is saved on the system and available for use 15 | in future sessions. (To replace a key, simply call the function again 16 | with the new key.) 17 | 18 | During the update process, this key may be lost or left in the wrong 19 | location. A call to \code{api.key.migrate()} can help restore an 20 | archived key, if found. 21 | } 22 | \usage{ 23 | api.key.migrate() 24 | } 25 | %- maybe also 'usage' for other objects documented here. 26 | 27 | \value{ 28 | Migrates the key (if found) and exits silently; return an error if no 29 | archived key is found. 30 | } 31 | \references{ 32 | To request an API key, see \url{http://www.census.gov/developers/} 33 | } 34 | \author{ 35 | Ezra Haber Glenn \email{eglenn@mit.edu} 36 | } 37 | 38 | \seealso{ 39 | \code{\link{acs.fetch}} 40 | \code{\link{api.key.install}}} 41 | -------------------------------------------------------------------------------- /man/cbind.acs.Rd: -------------------------------------------------------------------------------- 1 | \name{cbind.acs} 2 | \alias{cbind.acs} 3 | \alias{cbind} 4 | 5 | \title{Combine acs Objects by Columns 6 | } 7 | 8 | \description{ Take a pair of acs objects and combine by columns. 9 | } 10 | 11 | \usage{ 12 | \method{cbind}{acs}(e1, e2, ...) 13 | } 14 | 15 | \arguments{ 16 | \item{e1, e2}{two acs-class objects} 17 | \item{...}{provided for consistency with cbind S3 method} 18 | } 19 | 20 | \details{ When passed two acs-class objects, cbind will first check to 21 | confirm whether the objects contain compatible data: same endyear and 22 | span; same geography. If not, it will issue a warning, but will still 23 | proceed. 24 | 25 | After this check, the function will return a new acs object that has 26 | resulted from combining the two arguments column-wise. The effect is 27 | essentially the same as cbind on the underlying estimate and 28 | standard.error matrices, with all the additional acs metadata tended 29 | to.} 30 | 31 | \value{ Returns a single new acs object with all of the data contained 32 | in the two arguments. } 33 | 34 | \author{ 35 | Ezra Haber Glenn \email{eglenn@mit.edu} 36 | } 37 | 38 | -------------------------------------------------------------------------------- /man/confint.acs.Rd: -------------------------------------------------------------------------------- 1 | \name{confint.acs} 2 | \alias{confint.acs} 3 | \alias{confint} 4 | \title{ 5 | Return upper and lower bounds of given confidence intervals for acs objects. 6 | } 7 | 8 | \description{ When passed an acs object, \code{confint} will return 9 | a list of two-column dataframes (one dataframe for each variable 10 | specified in \code{parm}) including lower and upper bounds for given 11 | confidence intervals. Intervals can be one- or two-sided. } 12 | 13 | \usage{ 14 | \method{confint}{acs}(object, parm = "all", level = 0.95, alternative = "two.sided", \ldots) 15 | } 16 | 17 | 18 | \arguments{ 19 | \item{object}{ 20 | a acs object (or subset). 21 | } 22 | \item{parm}{which variables/columns to return confidence intervals for; 23 | defaults to "all", which computes confidence intervals for all 24 | estimates in the acs object.} 25 | \item{level}{ 26 | the confidence level required -- e.g., .95 = 95\% confidence. 27 | } 28 | \item{alternative}{ 29 | whether the interval should be one-sided (i.e., one-tailed -- "greater" or 30 | "less" -- extending to Inf (or -Inf) on one side) or "two-sided". 31 | } 32 | \item{...}{additional argument(s) for methods.} 33 | } 34 | \value{ Returns a list of dataframes (one for each variable specified in 35 | \code{parm}) of the lower and upper bounds of the confidence interval 36 | for each row of the data. } 37 | 38 | \author{ 39 | Ezra Haber Glenn \email{eglenn@mit.edu}. 40 | } 41 | 42 | 43 | \examples{ 44 | 45 | # load ACS data 46 | data(kansas09) 47 | 48 | # confidence intervals for select columns 49 | confint(kansas09[20:25,], parm=c(4,5,10)) 50 | 51 | # another way to accomplish this 52 | confint(kansas09[20:25,c(4,5,10)]) 53 | 54 | # store data and extract at will 55 | my.conf <- confint(kansas09) 56 | str(my.conf) 57 | my.conf[32] 58 | my.conf$Universe...TOTAL.POPULATION.IN.THE.UNITED.STATES..U.S..citizen.by.naturalization 59 | 60 | # try a different value for level 61 | confint(kansas09[1:10,6], level=.75) 62 | 63 | # ... or a one-sided confidence interval 64 | confint(kansas09[1:10,6], level=.75, alternative="greater") 65 | confint(kansas09[1:10,29], level=.75, alternative="less") 66 | 67 | } 68 | % Add one or more standard keywords, see file 'KEYWORDS' in the 69 | % R documentation directory. 70 | -------------------------------------------------------------------------------- /man/cpi.Rd: -------------------------------------------------------------------------------- 1 | \name{cpi} 2 | \alias{cpi} 3 | \docType{data} 4 | \title{Consumer Price Index data (1913-2015). 5 | } 6 | 7 | \description{ Contains data on the Consumer Price Index for All Urban 8 | Consumers (CPI-U) for the years 1913-2015 from the U.S. Bureau of Labor 9 | Statistics. Used by the acs package for currency conversion functions. 10 | Scaled for base (100) to be 1982-84.} 11 | 12 | \usage{ 13 | data(cpi) 14 | } 15 | 16 | \format{A named vector containing 103 observations, one for each year 17 | from 1913 through 2015.} 18 | 19 | \source{ 20 | \url{http://www.bls.gov/cpi/} 21 | } 22 | \seealso{ 23 | \code{\link{currency.year}} 24 | 25 | \code{\link{currency.convert}} 26 | } 27 | \keyword{datasets} 28 | -------------------------------------------------------------------------------- /man/currency.convert.Rd: -------------------------------------------------------------------------------- 1 | \name{currency.convert} 2 | \alias{currency.convert} 3 | \alias{currency.convert,acs-method} 4 | \title{Convert dollar values of acs object to a new base year. 5 | } 6 | \description{ 7 | \code{currency.convert} provides a helper function to create a new 8 | copy of an acs-class object with a modified currency.year and 9 | converted dollar values without altering the original object. 10 | } 11 | \usage{ 12 | 13 | currency.convert(object, rate="auto", newyear=NA_integer_, verbose=F) 14 | 15 | } 16 | 17 | \arguments{ 18 | \item{object}{ an acs object} 19 | \item{rate}{an optional rate to apply; "auto" (the default) will look 20 | up values from the cpi dataset.} 21 | \item{newyear}{an integer specifying the new value of currency.year to 22 | convert into} 23 | \item{verbose}{whether to print additional information about the conversion} 24 | } 25 | 26 | \details{ 27 | 28 | \code{currency.convert} provides a helper function to create a new 29 | copy of an acs-class object with a modified currency.year and 30 | converted dollar values without altering the original object. When 31 | \code{rate="auto"} (the default), \code{currency.convert} will look up 32 | values from the \code{cpi} database to use in conversion. When a 33 | numeric rate is provided through this option, actual \code{cpi} values 34 | are ignored. When \code{verbose=T}, currency.convert will provide 35 | additional information about the rates of conversion and the 36 | acs.colnames converted. 37 | 38 | As of version 2.0 the package includes CPI data from 1913 through 39 | 2015, allowing conversion of dollar values for any years in this 40 | range.} 41 | 42 | 43 | \value{ Returns a new acs object with updated dollar values and 44 | \code{currency.year} metadata. 45 | 46 | Unlike \code{currency.year<-}, \code{currency.convert} does not alter 47 | the original object.} 48 | 49 | \seealso{ 50 | 51 | \code{\link{currency.year}} 52 | 53 | \code{\link{cpi}} 54 | 55 | } 56 | \examples{ 57 | lawrence10 # median income data, endyear = 2010 58 | currency.convert(lawrence10, newyear=2014) # convert $$ to 2014 dollars 59 | currency.convert(lawrence10, newyear=1929) # convert $$ to 1929 dollars 60 | } 61 | \author{ 62 | Ezra Haber Glenn \email{eglenn@mit.edu} 63 | } 64 | 65 | -------------------------------------------------------------------------------- /man/currency.year.Rd: -------------------------------------------------------------------------------- 1 | \name{currency.year} 2 | \alias{currency.year} 3 | \alias{currency.year<-} 4 | \alias{currency.year,acs-method} 5 | \alias{currency.year<-,acs-method} 6 | \title{Return (or change) currency.year value from the metadata of an acs object. 7 | } 8 | 9 | \description{ Standard accessor/replacement method for metadata 10 | contained within S4 acs-class objects. } 11 | 12 | \usage{ 13 | currency.year(object) 14 | 15 | currency.year(object)<-value 16 | 17 | } 18 | 19 | \arguments{ 20 | \item{object}{ an acs object} 21 | \item{value}{an integer value to be used in replacement } 22 | } 23 | 24 | \details{ \code{currency.year} will return the (integer) value of the 25 | dollar-year of object. 26 | 27 | Assigning a new value to currency.year (through 28 | \code{currency.year(object)<-value} or 29 | \code{currency.year(object)=value}) will change the value of 30 | \code{currency.year} in the object's metadata and also modify all 31 | dollar values of the object (as determined by 32 | \code{acs.units(object)=="dollars"}) to be in the dollars of the 33 | desired new year. 34 | 35 | A related function, \code{currency.convert} provides a helper function 36 | to create a new copy of an acs-class object with a modified 37 | currency.year and converted dollar values without altering the 38 | original object. When \code{rate="auto"} (the default), 39 | \code{currency.convert} will look up values from the \code{cpi} 40 | database to use in conversion. When a numeric rate is provided 41 | through this option, actual \code{cpi} values are ignored. When 42 | \code{verbose=T}, currency.convert will provide additional information 43 | about the rates of conversion and the acs.colnames converted. 44 | 45 | As of version 2.0 the package includes CPI data from 1913 through 46 | 2015, allowing conversion of dollar values for any years in this 47 | range.} 48 | 49 | 50 | \value{ 51 | Returns (or replaces) an integer value from the "currency.year" slot of an object. 52 | } 53 | \seealso{ 54 | 55 | \code{\link{cpi}} 56 | 57 | \code{\link{currency.convert}} 58 | 59 | \code{\link{acs-class}} 60 | } 61 | 62 | \author{ 63 | Ezra Haber Glenn \email{eglenn@mit.edu} 64 | } 65 | 66 | -------------------------------------------------------------------------------- /man/divide.acs.Rd: -------------------------------------------------------------------------------- 1 | \name{divide.acs} 2 | \alias{divide.acs} 3 | \title{Divide one acs object or variable by another. 4 | } 5 | 6 | \description{The \code{acs} package provides a new S4 method for 7 | standard division operations using "/" notation. However, due to the 8 | nature of estimates and errors, there are actually two types of 9 | division, with slightly different meanings: depending on which 10 | variables are being divided, the process may be either a 11 | "proportion"-type division (in which the numerator is a subset of the 12 | denominator) or a "ratio"-type division (in which this is not the 13 | case). When dividing with standard "a/b" notation, the package will 14 | always use the more conservative ratio-type procedure. 15 | 16 | When appropriate, "proportion"-type division may be desirable, as it 17 | results in lower standarard errors. To allow users to specify which 18 | type of division to use for acs objects, the package includes a new 19 | \code{"divide.acs"} function. (See details.)} 20 | 21 | \usage{ 22 | divide.acs(numerator, denominator, method="ratio", verbose=T, output="result") 23 | } 24 | 25 | \arguments{ 26 | \item{numerator}{ an acs object to divide } 27 | \item{denominator}{ an acs object to divide by } 28 | \item{method}{ either "ratio" (the default) or "proportion", to 29 | indicate what kind of division is desired } 30 | \item{verbose}{ whether to provide additional warnings or just shut up } 31 | \item{output}{either "result" (the default), "div.method", or "both"} 32 | } 33 | 34 | \value{ 35 | Returns a new acs object with the results of the division (the 36 | default), or (when result="div.method") a martix with diagnostic 37 | information, or (when result="both"), a list with both of these 38 | objects (the first name $result and the second $div.method). 39 | } 40 | 41 | \details{In certain cases, "proportion-style" division will fail, due 42 | to the creation of a negative number under a square root when 43 | calculating new standard errors. To address this problem and prevent 44 | unnecessary NaN values in the standard.errors, the package implements 45 | the recommended Census practice of simply using "ratio-style" division in 46 | those cases. 47 | 48 | If method="proportion" (not the default) and verbose=T (the default), 49 | \code{division.acs} will provide a warning to indicate when 50 | "ratio-style" division has been used, including the number of standard 51 | error cells so affected. Users wishing to examine a detailed, 52 | cell-by-cell report may run \code{divide.acs} with the 53 | output="div.method" of output="both" to get additional diagnostic 54 | information. 55 | 56 | See 57 | "A Compass for Understanding and Using American Community Survey Data" 58 | below for details on when this substitution is recommended.} 59 | 60 | \seealso{ 61 | \code{\link{acs-class}} 62 | } 63 | 64 | \references{ 65 | \enumerate{ 66 | 67 | \item{"A Compass for Understanding and Using American Community Survey 68 | Data: What State and Local Governments Need to Know." Washington, DC: 69 | U.S. Census Bureau. 70 | 2009. \url{http://www.census.gov/library/publications/2009/acs/state-and-local.html}.} 71 | }} 72 | \author{ 73 | Ezra Haber Glenn \email{eglenn@mit.edu} 74 | } 75 | 76 | -------------------------------------------------------------------------------- /man/endyear.Rd: -------------------------------------------------------------------------------- 1 | \name{endyear} 2 | \alias{endyear<-} 3 | \alias{endyear} 4 | \alias{endyear,acs-method} 5 | \alias{endyear<-,acs-method} 6 | \title{Return or replace endyear value from the metadata of an acs object. 7 | } 8 | 9 | \description{ \code{endyear()} will return the (integer) value of the 10 | latest year of the object (for example, for the 2005-2009 ACS survey, 11 | \code{endyear} = 2009.) When used for assignment, \code{endyear<-} will 12 | change the value of the endyear slot in an acs object, warning the user 13 | that this is an unusual thing to do. } 14 | 15 | \usage{ 16 | endyear(object) 17 | 18 | endyear(object)<-value 19 | 20 | } 21 | 22 | \arguments{ 23 | \item{object}{ an acs object 24 | } 25 | \item{value}{an integer to use as the new endyear} 26 | } 27 | 28 | \details{ Normal operations on acs objects should not involve altering 29 | the value of endyear (although users may wish to change the value of 30 | currency.year for comparisons with other objects). Sometimes endyear 31 | may be set incorrectly when data is imported, in which case 32 | \code{endyear<-} may be necessary.} 33 | 34 | \value{ 35 | Returns (or replaces) an integer value from the \code{endyear} slot of an object. 36 | } 37 | 38 | \seealso{ 39 | 40 | \code{currency.year}, which is often what users will be intending to 41 | modify 42 | 43 | \code{\link{acs-class}} 44 | 45 | } 46 | \author{ 47 | Ezra Haber Glenn \email{eglenn@mit.edu} 48 | } 49 | 50 | -------------------------------------------------------------------------------- /man/fips.state.Rd: -------------------------------------------------------------------------------- 1 | \name{fips.state} 2 | \alias{fips.state} 3 | \alias{fips.county} 4 | \alias{fips.county.subdivision} 5 | \alias{fips.place} 6 | \alias{fips.school} 7 | \alias{fips.american.indian.area} 8 | \docType{data} 9 | \title{ 10 | FIPS codes and geographic names for use in searching and creating 11 | geographies in the acs package. 12 | } 13 | \description{ 14 | FIPS codes and geographic names for use in searching and creating 15 | geographies in the acs package. (Used internally.) 16 | } 17 | \usage{data(fips.state)} 18 | \format{Each table is a dataframe containing FIPS codes and names from 19 | the US Census.} 20 | 21 | \source{ 22 | 23 | State: http://www.census.gov/geo/reference/ansi_statetables.html 24 | 25 | County: http://www.census.gov/geo/www/codes/county/download.html 26 | 27 | County Subdivision: 28 | http://www.census.gov/geo/www/codes/cousub/download.html 29 | 30 | Place: http://www.census.gov/geo/www/codes/place/download.html 31 | 32 | School: http://www.census.gov/geo/www/codes/sd/ 33 | 34 | American Indian Area: http://www.census.gov/geo/www/codes/aia/ 35 | } 36 | 37 | 38 | \keyword{datasets} 39 | -------------------------------------------------------------------------------- /man/flatten.geo.set.Rd: -------------------------------------------------------------------------------- 1 | \name{flatten.geo.set} 2 | \alias{flatten.geo.set} 3 | \title{ 4 | Convenience function to "flatten" a nested geo.set object. 5 | } 6 | \description{ 7 | In the acs package, geo.set objects may contain nested levels of geo.set 8 | objects, which is often desired (to organize complex sets and subsets of 9 | geography). Sometimes, however, when combining these sets, users may 10 | prefer to remove the nesting levels. This convenience function will 11 | recursively prowl through a geo.set and return a single flat geo.set 12 | (one level deep) containing of the composite geographies. 13 | } 14 | \usage{ 15 | flatten.geo.set(x) 16 | } 17 | 18 | \arguments{ 19 | \item{x}{ the geo.set to be flattened 20 | 21 | } 22 | } 23 | 24 | \value{ 25 | Returns a new geo.set object. 26 | 27 | } 28 | 29 | \author{ 30 | Ezra Haber Glenn \email{eglenn@mit.edu} 31 | } 32 | 33 | 34 | \seealso{ 35 | \code{\link{geo.set-class}} 36 | } 37 | \examples{ 38 | 39 | # a multiple-county geo.set 40 | psrc=geo.make(state="WA", county=c(33,35,53,61)) 41 | 42 | # combine geo.sets 43 | north.mercer.island=geo.make(state=53, county=33, tract=c(24300,24400)) 44 | optional.tract=geo.make(state=53, county=33, tract=24500) 45 | # add in one more tract to create new, larger geo 46 | north.mercer.island.plus=north.mercer.island + optional.tract 47 | 48 | # created a nested geo.set 49 | my.nested.geo.set=c(north.mercer.island.plus, psrc) 50 | str(my.nested.geo.set) 51 | length(my.nested.geo.set) 52 | 53 | # .. and flatten in out 54 | # note difference in structure and length 55 | my.flat.geo.set=flatten.geo.set(my.nested.geo.set) 56 | str(my.flat.geo.set) 57 | length(my.flat.geo.set) 58 | } 59 | 60 | -------------------------------------------------------------------------------- /man/geo.lookup.Rd: -------------------------------------------------------------------------------- 1 | \name{geo.lookup} 2 | \alias{geo.lookup} 3 | 4 | \title{ 5 | Search Census geographies 6 | } 7 | \description{ 8 | 9 | When working with the acs package and the \code{acs.fetch} and 10 | \code{geo.make} functions, it can be difficult to find exactly the right 11 | geographic units: \code{geo.make} expects single matches to the groups 12 | of arguments it is given, which can be problematic when trying to find 13 | names for places or county subdivisions, which are unfamiliar to many 14 | users (and often seem very close or redundant: e.g., knowing whether to 15 | look for "Moses Lake city" vs. "Moses Lake CDP"). To help, the 16 | \code{geo.lookup} function will search on the same arguments as 17 | \code{geo.make}, but outputs all the matches for your inspection. 18 | 19 | } 20 | \usage{ 21 | geo.lookup(state, county, county.subdivision, place, 22 | american.indian.area, school.district, school.district.elementary, 23 | school.district.secondary, school.district.unified) 24 | } 25 | %- maybe also 'usage' for other objects documented here. 26 | \arguments{ 27 | \item{state}{either the two-digit numeric FIPS code for the state, the 28 | two-letter postal abbreviation, or a character string to match in 29 | the state name} 30 | 31 | \item{county}{either the numeric FIPS code for the county or a character 32 | string to match in the county name } 33 | 34 | \item{county.subdivision}{either the numeric FIPS code for the county 35 | subdivision or a character string to match in the county subdivision 36 | name} 37 | 38 | \item{place}{either the numeric FIPS code for the place or a character 39 | string to match in the place name} 40 | 41 | \item{american.indian.area}{either the numeric FIPS code for the 42 | American Indian Area/Alaska Native Area/Hawaiian Home Land, or a 43 | character string to match in the names of these Census areas} 44 | 45 | \item{school.district}{either the numeric FIPS code for the state 46 | school district (any type), or a character string to search for in 47 | the names of the school districts.} 48 | 49 | \item{school.district.elementary}{either the numeric FIPS code for 50 | the state school district (elementary), or a character string to 51 | search for in the names of these elementary school districts.} 52 | 53 | \item{school.district.secondary}{either the numeric FIPS code for the 54 | state school district (secondary), or a character string to search 55 | for in the names of these secondary school districts.} 56 | 57 | \item{school.district.unified}{either the numeric FIPS code for the 58 | state school district (unified), or a character string to search for 59 | in the names of these unified school districts.} 60 | 61 | } \details{ Unlike \code{geo.make}, \code{geo.lookup} searches for 62 | matches anywhere in geographic names (except when dealing with state 63 | names), and will output a dataframe showing candidates that match some 64 | or all of the arguments. (When multiple arguments are provided, the 65 | logic is a little complicated: basically, with the exception of American 66 | Indian Areas, to be included all geographies must match the given state 67 | name; when a county and a subdivision are both given, both must match; 68 | otherwise, geographies are included that match any --- but not 69 | necessarily all --- of the other arguments.) } \value{ Returns a 70 | dataframe of the matching geographies, with one column for each of the 71 | given search terms. } 72 | 73 | \author{ 74 | Ezra Haber Glenn \email{eglenn@mit.edu} 75 | } 76 | 77 | \seealso{ 78 | \code{\link{geo.make}} 79 | } 80 | \examples{ 81 | geo.lookup(state="WA", county="Ska", county.subdivision="oo") 82 | geo.lookup(state="WA", county="Kit", place="Ra") 83 | 84 | # find all counties in WA or OR with capital M or B in name 85 | geo.lookup(state=c("WA", "OR"), county=c("M","B")) 86 | 87 | # find all unified school districts in Kansas with "Ma" in name 88 | geo.lookup(state="KS", school.district.unified="Ma") 89 | 90 | # find all american indian areas with "Hop" in name 91 | geo.lookup(american.indian.area="Hop") 92 | } 93 | -------------------------------------------------------------------------------- /man/geo.make.Rd: -------------------------------------------------------------------------------- 1 | \name{geo.make} 2 | \alias{geo.make} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | \title{ 5 | Create a new geo.set object for use with the acs package. 6 | } 7 | 8 | \description{ The \code{geo.make} function is used to create new 9 | user-specified geographies for use with the \code{acs.fetch} function of 10 | the acs package. At the most basic level, a user specifies some 11 | combination of existing census levels (state, county, county 12 | subdivision, place, tract, block group, msa, csa, puma, and more -- see 13 | arguments), and the function returns a new geo.set object holding this 14 | information. 15 | 16 | When specifying state, county, county subdivision, place, american 17 | indian area, and/or any of the state school district arguments, 18 | \code{geo.make} will accept either FIPS codes or common geographic 19 | names, and will try to match on partial strings; there is also limited 20 | support for regular expressions, but by default the searches are case 21 | sensitive and matches are expected at the start of names. (For example, 22 | \code{geo.make(state="WA", county="Kits")} should find Kitsap County, 23 | and the more adventurous \code{yakima=geo.make(state="Washi", 24 | county=".*kima")} should work to create the a geo.set for Yakima 25 | county.) 26 | 27 | Other geographies (including tract, block.group, csa, msa, region, 28 | division, urban.area, necta, puma, zip.code. and/or 29 | congressional.district) can only be specified by FIPS codes (or "*" for 30 | all). 31 | 32 | Tracts should be specified as six digit numbers, although initial zeroes 33 | may be removed; note that trailing zeroes are often removed in common 34 | usage, so a tract that may be referred to as "tract 243" is technically 35 | FIPS code 24300; likewise "tract 3872.01" is FIPS code 387201 for the 36 | purposes of geo.make. 37 | } 38 | \usage{ 39 | geo.make(us, region, division, state, county, county.subdivision, 40 | place, tract, block.group, msa, csa, necta, urban.area, 41 | congressional.district, state.legislative.district.upper, 42 | state.legislative.district.lower, puma, zip.code, 43 | american.indian.area, school.district.elementary, 44 | school.district.secondary, school.district.unified, 45 | combine = F, combine.term = "aggregate", check = FALSE, key = "auto") 46 | } 47 | %- maybe also 'usage' for other objects documented here. 48 | \arguments{ 49 | 50 | \item{us}{either the number 1, the character "*", or TRUE, indicating 51 | whether the geo.set should contain data for the entire U.S.; if 52 | selected, no other geography options may be specified; setting us 53 | corresponds to using census summary level 010.} 54 | 55 | \item{region}{a numeric code (or wildcard "*" for all) corresponding 56 | to the desired FIPS region (e.g., region=1 for Census Northeast 57 | Region); if selected, no other geography options may be specified; 58 | setting region corresponds to using census summary level 020.} 59 | 60 | \item{division}{a numeric code (or wildcard "*" for all) corresponding 61 | to the desired FIPS division (e.g., division=4 for Census West North 62 | Central Division); if selected, no other geography options may be 63 | specified; setting division corresponds to using census summary 64 | level 030.} 65 | 66 | \item{american.indian.area}{either the numeric code (or wildcard "*" 67 | for all) corresponding to the desired FIPS American Indian 68 | Area/Alaska Native Area/Hawaiian Home Land, or a character string to 69 | match in the names of these Census areas; if selected, no other 70 | geography options may be specified; setting american.indian.area 71 | corresponds to using census summary level 250.} 72 | 73 | \item{state}{either the two-digit numeric FIPS code for the state, the 74 | two-letter postal abbreviation, or a character string to match in 75 | the state name (or wildcard "*" for all); setting state without 76 | other options corresponds to using census summary level 040, but it 77 | may be used in conjunction with other summary levels below.} 78 | 79 | \item{county}{either the numeric FIPS code (or wildcard "*" for all) 80 | for the county or a character string to match in the county name; 81 | setting state and county without other options corresponds to using 82 | census summary level 050, but they may be used in conjunction with 83 | other summary levels below.} 84 | 85 | \item{county.subdivision}{either the numeric FIPS code (or wildcard 86 | "*" for all) for the county subdivision or a character string to 87 | match in the county subdivision name; setting state, county, and 88 | county.subdivision without other options corresponds to using census 89 | summary level 060.} 90 | 91 | \item{place}{either the numeric FIPS code (or wildcard "*" for all) 92 | for the place or a character string to match in the place name; 93 | setting state and place without other options corresponds to using 94 | census summary level 160.} 95 | 96 | \item{tract}{a six digit numeric FIPS code (or wildcard "*" for all) 97 | for the census tract, including trailing zeroes; remove decimal 98 | points; leading zeroes may be omitted; see description; tract may be 99 | used with state and county to create geo.sets for census summary 100 | levels 140, and with state, county, and block.group for summary 101 | level 150.} 102 | 103 | \item{block.group}{the numeric FIPS code (or wildcard "*" for all) for 104 | the block.group; block.group may be used with state, county, and 105 | tract to create geo.sets for census summary levels 150.} 106 | 107 | \item{msa}{a numeric code (or wildcard "*" for all) corresponding to 108 | the desired FIPS metropolitan statistical area/micropolitan 109 | statistical area (e.g., msa=10100 for Aberdeen, SD micropolitan 110 | statistical area); setting msa without other options corresponds to 111 | using census summary level 310, but it may be used in conjunction 112 | with state for summary level 320.} 113 | 114 | \item{csa}{a numeric code (or wildcard "*" for all) corresponding to 115 | the desired FIPS combined statistical area (e.g., csa=104 for Census 116 | Albany-Schenectady-Amsterdam, NY CSA); setting csa without other 117 | options corresponds to using census summary level 330, but it may be 118 | used in conjunction with state for summary level 340.} 119 | 120 | \item{necta}{a numeric code (or wildcard "*" for all) corresponding to 121 | the desired FIPS New England City and Town Area (e.g., necta=77650 122 | for Rutland, VT Micropolitan NECTA); if selected, no other 123 | geography options may be specified; setting necta corresponds to 124 | using census summary level 350.} 125 | 126 | \item{urban.area}{a numeric code (or wildcard "*" for all) 127 | corresponding to the desired FIPS urban area (e.g., urban.area=3169 128 | for Aromas, CA Urban Cluster); if selected, no other 129 | geography options may be specified; setting urban.area corresponds 130 | to using census summary level 400.} 131 | 132 | \item{congressional.district}{a numeric code (or wildcard "*" for all) 133 | corresponding to the desired FIPS congressional district (e.g., 134 | state="ME" and congressional.district=1 for Maine's first 135 | congressional district); setting state and congressional.district 136 | without other options corresponds to using census summary level 500, 137 | but they may be used in conjunction with county for summary level 138 | 510.} 139 | 140 | \item{state.legislative.district.upper}{a numeric or character code 141 | (or wildcard "*" for all) corresponding to the desired FIPS state 142 | legislative district (upper chamber); these codes vary from state to 143 | state, and are sometimes numbers (1, 2, 3, etc. in Massachusetts) 144 | and sometimes letters ("A", "B", "C", etc. in Alaska); setting state 145 | and state.legislative.district.upper without other options 146 | corresponds to using census summary level 610.} 147 | 148 | \item{state.legislative.district.lower}{a numeric or character code 149 | (or wildcard "*" for all) corresponding to the desired FIPS state 150 | legislative district (lower chamber); these codes vary from state to 151 | state, and are sometimes numbers (1, 2, 3, etc. in Massachusetts) 152 | and sometimes letters ("A", "B", "C", etc. in Alaska); setting state 153 | and state.legislative.district.lower without other options 154 | corresponds to using census summary level 620.} 155 | 156 | \item{puma}{a numeric code (or wildcard "*" for all) corresponding to 157 | the desired FIPS public use microdata area (e.g., state=10 and 158 | puma=103 for PUMA 103 in Delaware); setting state and puma 159 | without other options corresponds to using census summary level 160 | 795.} 161 | 162 | \item{zip.code}{a numeric code (or wildcard "*" for all) corresponding 163 | to the desired zip code tabulation area (e.g., zip.code=91303 for 164 | zip code 91303); if selected, no other geography options may be 165 | specified; setting zip.code corresponds to using census summary 166 | level 860.} 167 | 168 | \item{school.district.elementary}{a numeric code (or wildcard "*" for 169 | all) corresponding to the desired FIPS state school district 170 | (elementary), or a character string to search for in the names of 171 | these districts; setting state and school.district.elementary 172 | without other options corresponds to using census summary level 173 | 950.} 174 | 175 | \item{school.district.secondary}{a numeric code (or wildcard "*" for 176 | all) corresponding to the desired FIPS state school district 177 | (secondary), or a character string to search for in the names of 178 | these districts; setting state and school.district.secondary 179 | without other options corresponds to using census summary level 180 | 960.} 181 | 182 | \item{school.district.unified}{a numeric code (or wildcard "*" for 183 | all) corresponding to the desired FIPS state school district 184 | (unified), or a character string to search for in the names of these 185 | districts; setting state and school.district.unified without other 186 | options corresponds to using census summary level 970.} 187 | 188 | \item{combine}{a logical flag to indicate whether the component 189 | geographies of the geo.set are to be combined when data is 190 | downloaded; see details.} 191 | 192 | \item{combine.term}{a character string to provide a label for 193 | aggregate geography, if data is combined} 194 | 195 | \item{check}{logical flag indicating whether to run a check for valid 196 | geographies with Census API; defaults to FALSE; when TRUE, a current 197 | API key must be provided or installed} 198 | 199 | \item{key}{when check=T and no API key has been previously installed 200 | through \code{api.key.install}, a string key may be provided here} 201 | 202 | } 203 | 204 | \details{In addition to creating individual combinations of census 205 | geographies, users can pass vector arguments (with recycling) to 206 | geo.make to create sets of geographies. Important: each set of 207 | arguments must match with exactly one known Census geography: if, for 208 | example, the names of two places (or counties, or whatever) would both 209 | match, the \code{geo.make} function will return an error. (To the 210 | development team, this seemed preferable to simply including both 211 | matches, since all sorts of place names might match a string, and it 212 | is doubtful a user really wants them all.) The one exception to this 213 | "single match" rule is that for the smallest level of geography 214 | specified, a user can enter "*" to indicate that all geographies at 215 | that level should be selected. 216 | 217 | When creating new geographies, note, too, that not all combinations 218 | are valid. In particular the package attempts to follow paths through 219 | the Census summary levels (such as summary level 140: 220 | "state-county-tract" or summary level 160: "state-place"). So when 221 | specifying, for example, state, county, and place, the county will be 222 | ignored. 223 | 224 | Note: when a geo.set with "combine=T" is passed to \code{acs.fetch}, 225 | downloaded data will be aggregated in the resulting acs abject. Some 226 | users may therefore wish to specify "one.zero=T" as an additional 227 | argument to \code{acs.fetch}; see \code{\link{sum-methods}}. 228 | 229 | The following table may be helpful in figuring out which options to set 230 | for which Census summary levels. For more information on which datasets 231 | and endyear/span combinations are available for each summary level, see 232 | \url{http://www.census.gov/data/developers/data-sets.html} (click each 233 | dataset and search for "Examples and Supported Geography"). 234 | 235 | \tabular{cl}{ 236 | SUMMARY LEVEL \tab ARGUMENTS REQUIRED \cr 237 | 010 \tab us \cr 238 | 020 \tab region \cr 239 | 030 \tab division \cr 240 | 040 \tab state \cr 241 | 050 \tab state, county \cr 242 | 060 \tab state, county, county.subdivision \cr 243 | 140 \tab state, county, tract \cr 244 | 150 \tab state, county, tract, block.group \cr 245 | 160 \tab state, place \cr 246 | 250 \tab american.indian.area \cr 247 | 310 \tab msa \cr 248 | 320 \tab state, msa \cr 249 | 330 \tab csa \cr 250 | 340 \tab state, csa \cr 251 | 350 \tab necta \cr 252 | 400 \tab urban.area \cr 253 | 500 \tab state, congressional.district \cr 254 | 510 \tab state, congressional.district, county \cr 255 | 610 \tab state, state.legislative.district.upper \cr 256 | 620 \tab state, state.legislative.district.lower \cr 257 | 795 \tab state, puma \cr 258 | 860 \tab zip.code \cr 259 | 950 \tab state, school.district.elementary \cr 260 | 960 \tab state, school.district.secondary \cr 261 | 970 \tab state, school.district.unified \cr 262 | } 263 | 264 | All other arguments/combinations will either be ignored or result in a 265 | failure. } \value{ Returns a geo.set class object. } 266 | 267 | \author{ 268 | Ezra Haber Glenn \email{eglenn@mit.edu} 269 | } 270 | \references{ 271 | \enumerate{ 272 | 273 | \item{"acs.R: An R Package for Neighborhood-Level Data from the 274 | U.S. Census." Ezra Haber Glenn, Department of Urban Studies and 275 | Planning, Massachusetts Institute of Technology. Presented at the 276 | Computers in Urban Planning and Urban Management Conference, July 277 | 6, 2011. 278 | \url{http://papers.ssrn.com/sol3/papers.cfm?abstract_id=2171390}.} 279 | 280 | \item{Census API Supported Geography: 281 | \url{http://www.census.gov/data/developers/data-sets.html}}}} 282 | 283 | \seealso{ 284 | \code{\link{geo.set-class}} 285 | } 286 | \examples{ 287 | 288 | # some single-state geo.sets 289 | washington=geo.make(state=53) 290 | alabama=geo.make(state="Alab") 291 | 292 | # a county match 293 | yakima=geo.make(state="WA", county="Yakima") 294 | yakima 295 | 296 | # a multiple-county geo.set 297 | psrc=geo.make(state="WA", county=c(33,35,53,61)) 298 | psrc 299 | 300 | # combine geo.sets 301 | north.mercer.island=geo.make(state=53, county=33, tract=c(24300,24400)) 302 | optional.tract=geo.make(state=53, county=33, tract=24500) 303 | # add in one more tract to create new, larger geo 304 | north.mercer.island.plus=north.mercer.island + optional.tract 305 | 306 | # using wildcards 307 | 308 | # all unified school districts in Kansas 309 | geo.make(state="KS", school.district.unified="*") 310 | 311 | # all state house districts in Alaska 312 | geo.make(state="AK", state.legislative.district.lower="*") 313 | 314 | # all tracts in Kings County, NY 315 | geo.make(state="NY", county="King", tract="*") 316 | 317 | } 318 | 319 | -------------------------------------------------------------------------------- /man/geo.set-class.Rd: -------------------------------------------------------------------------------- 1 | \name{geo.set-class} 2 | \Rdversion{1.1} 3 | \docType{class} 4 | \alias{geo-class} 5 | \alias{geo.set-class} 6 | \alias{api.for} 7 | \alias{api.in} 8 | \alias{sumlev} 9 | \alias{is.geo} 10 | \alias{geo.list} 11 | \alias{is.geo.set} 12 | \alias{[,geo.set-method} 13 | \alias{[[,geo.set-method} 14 | \alias{[<-,geo.set-method} 15 | \alias{[[<-,geo.set-method} 16 | \alias{+,geo,geo.set-method} 17 | \alias{+,geo.set,geo-method} 18 | \alias{+,geo,geo-method} 19 | \alias{+,geo.set,geo.set-method} 20 | \alias{c,geo.set-method} 21 | \alias{combine} 22 | \alias{combine.term} 23 | \alias{combine<-,geo.set-method} 24 | \alias{combine,geo.set-method} 25 | \alias{combine.term<-,geo.set-method} 26 | \alias{combine.term,geo.set-method} 27 | \alias{geo.list,geo.set-method} 28 | \alias{length,geo.set-method} 29 | \alias{show,geo-method} 30 | \alias{name,geo-method} 31 | \alias{sumlev,geo-method} 32 | \alias{api.for,geo-method} 33 | \alias{api.in,geo-method} 34 | \alias{combine<-} 35 | \alias{combine.term<-} 36 | \alias{name} 37 | 38 | \title{Class \code{"geo.set"}} 39 | 40 | \description{The geo.set class provides a convenient wrapper for 41 | user-defined geographies, used for downloading data from the U.S. Census 42 | American Community Survey. A geo.set may hold the designation of a 43 | single geography (say, a census tract, a county, or a state), or may 44 | bundle together multiple geographies of various levels, which may or may 45 | not be "combined" when downloaded. Note that geo.sets may even contain 46 | nested geo.sets. 47 | 48 | Note: even a single geographic unit --- one specific tract or county --- 49 | must be wrapped up as a geo.set. Technically, each individual element 50 | in the set is known as a "geo", but users will rarely (if ever) interact 51 | will individual elements such as this; wrapping all groups of 52 | geographies --- even groups consisting of just one element --- in 53 | geo.sets like this will help make them easier to deal with as the 54 | geographies get more complex. 55 | 56 | geo.set objects may be combined with the simple addition operator 57 | (\code{+}). By default, this will always return "flat" geo.sets with 58 | all the geographies in a single list. The combination operator 59 | (\code{c}), on the other hand, will generally return nested hierarchies, 60 | embedding sets within sets. When working with nested sets like this, 61 | the "combine" flag can be set at each level to aggregate subsets within 62 | the structure (although be careful --- if a higher level of set includes 63 | "combine=T" you'll never actually see the unaggregated subsets deeper 64 | down). 65 | 66 | Using these different techniques, users are able to create whatever sort 67 | of new geographies they need --- aggregating some geographies, keeping 68 | others distinct (but still bundled as a set for convenience), mixing and 69 | matching different levels of Census geography, and so on. 70 | } 71 | 72 | \section{Objects from the Class}{ 73 | Objects can be created by calls of the form \code{new("geo.set", ...)}, 74 | or more frequently through the \code{geo.make()} helper function. 75 | } 76 | \section{Slots}{ 77 | \describe{ 78 | \item{\code{geo.list}:}{Object of class \code{"list"} containing individual census geographies (as geo class 79 | object) and/or geo.sets.} 80 | \item{\code{combine}:}{Object of class \code{"logical"} indicating 81 | whether or not data from the constituent geographies should be 82 | combined when downloaded. Set with \code{combine<-} or specified 83 | when using \code{geo.make}. } 84 | \item{\code{combine.term}:}{Object of class \code{"character"} 85 | indicating a new label to use when data is combined; ignored when 86 | combine set to F. Set with \code{combine.term<-} or specified 87 | when using \code{geo.make}. } 88 | } 89 | } 90 | \section{Methods}{ 91 | \describe{ 92 | \item{[}{\code{signature(x = "geo.set")}: subset geo.set, similar to 93 | single-bracket list subsetting in R} 94 | \item{[[}{\code{signature(x = "geo.set")}: subset geo.set, similar to 95 | double-bracket list subsetting in R } 96 | \item{+}{\code{signature(e1 = "geo", e2 = "geo")}: combine two geo 97 | objects; returns a geo.set (generally reserved for internal use) } 98 | \item{+}{\code{signature(e1 = "geo", e2 = "geo.set")}: combine a geo object 99 | onto an existing geo.set; returns a geo.set (generally reserved for internal use)} 100 | \item{+}{\code{signature(e1 = "geo.set", e2 = "geo")}: combine an 101 | existing geo.set object with a geo object; returns a geo.set (generally reserved for internal use) } 102 | \item{+}{\code{signature(e1 = "geo.set", e2 = "geo.set")}: combine 103 | two geo.set objects; always flattens each set -- no nesting } 104 | \item{c}{\code{signature(x = "geo.set")}: combine two or more 105 | geo.set objects, preserving the structure of each -- allows nesting } 106 | \item{combine<-}{\code{signature(object = "geo.set")}: used to 107 | set or change value of combine} 108 | \item{combine}{\code{signature(object = "geo.set")}: returns logical 109 | value of combine } 110 | \item{combine.term<-}{\code{signature(object = "geo.set")}: used to 111 | set or change combine.term } 112 | \item{combine.term}{\code{signature(object = "geo.set")}: returns combine.term } 113 | \item{geo.list}{\code{signature(object = "geo.set")}: returns the 114 | geo.list of the geo.set (used internally)} 115 | \item{length}{\code{signature(x = "geo.set")}: returns an integer 116 | indicating how many geographies it contains; non-recursive. } 117 | 118 | \item{name}{\code{signature(object = "geo")}: returns the text name 119 | of an individual geo object.} 120 | 121 | \item{sumlev}{\code{signature(object = "geo")}: returns the summary 122 | level of an individual geo object.} } } 123 | 124 | \author{ 125 | Ezra Haber Glenn \email{eglenn@mit.edu} 126 | } 127 | 128 | \references{ 129 | http://eglenn.scripts.mit.edu/citystate/category/code/ 130 | } 131 | 132 | \seealso{ 133 | \code{\link{geo.make}} 134 | } 135 | \examples{ 136 | showClass("geo.set") 137 | } 138 | \keyword{classes} 139 | -------------------------------------------------------------------------------- /man/geography.Rd: -------------------------------------------------------------------------------- 1 | \name{geography} 2 | \alias{geography<-} 3 | \alias{geography} 4 | \alias{geography,acs-method} 5 | \alias{geography<-,acs-method} 6 | \title{Return or replace geography metadata of an acs object. 7 | } 8 | 9 | \description{ \code{geography()} will return the geography of an acs 10 | object, as a dataframe. Depending on the format of the data at import 11 | (and possibly the values of \code{geocols=}, if the object was created 12 | with \code{read.acs}), this may have multiple columns, but the number 13 | of geographic rows should be the same as the number of rows of the acs 14 | estimates and standard errors. 15 | 16 | When used for assignment, \code{geography<-} will change the values 17 | contained in the metadata, replacing the existing dataframe with a new 18 | one. To replace a single value or a limited subset, call with 19 | subsetting (e.g., \code{geography(object)[i,j]<-value} or 20 | \code{geography(object)[[i]]<-value}; note that the brackets should 21 | occur \emph{outside} the call -- you are subsetting the dataframe, not 22 | the object). 23 | 24 | To help with replacement operations, the package provides a new 25 | \code{prompt} method, which can be used to interactively set new 26 | values for geography (as well as other metadata); see 27 | \code{prompt.acs}. } 28 | 29 | \usage{ 30 | geography(object) 31 | 32 | geography(object)<-value 33 | 34 | } 35 | 36 | \arguments{ 37 | \item{object}{ an acs object 38 | } 39 | \item{value}{a dataframe containing geographic metadata; must contain 40 | the same number of rows as the object } 41 | } 42 | 43 | \value{ 44 | Returns (or replaces) a dataframe containing the \code{geography} slot of an object. 45 | } 46 | 47 | \seealso{ 48 | 49 | \code{\link{prompt.acs}}, a helper function to interactively generate 50 | a new geography dataframe to be used for replacement. 51 | 52 | \code{\link{acs-class}} 53 | 54 | } 55 | \author{ 56 | Ezra Haber Glenn \email{eglenn@mit.edu} 57 | } 58 | 59 | \examples{ 60 | data(lawrence10) 61 | geography(lawrence10) 62 | str(geography(lawrence10)) 63 | } 64 | -------------------------------------------------------------------------------- /man/kansas07.Rd: -------------------------------------------------------------------------------- 1 | \name{kansas07} 2 | \alias{kansas07} 3 | \docType{data} 4 | \title{ 5 | County-level data from the 2007 American Community Survey for Kansas for 6 | use in examples of acs package. 7 | } 8 | \description{ 9 | County-level data from the 2007 American Community Survey for Kansas. 10 | Contains demographic data on sex, age, and citizenship. Used for 11 | examples in acs package. \code{kansas07} and the corresponding 12 | five-year survey data in \code{kansas09} provide acs objects to test 13 | and demonstrate various functions in the package. 14 | } 15 | \usage{data(kansas07)} 16 | \format{An acs-class object with 7 rows/geographies and 55 demographic 17 | variables, representing county-level ACS data for the state of Kansas. Also includes 18 | geographic and other metadata. 19 | 20 | Note that in comparison to \code{kansas09}, \code{kansas07} has far 21 | fewer rows, which illustrates the fact that the Census only provides 22 | ACS one-year data for the largest counties (over 65,000 population). 23 | } 24 | 25 | 26 | \source{ 27 | U.S. Census American Community Survey, 2007; \url{http://www.census.gov/} 28 | } 29 | 30 | \examples{ 31 | data(kansas07) 32 | str(kansas07) 33 | class(kansas07) 34 | 35 | geography(kansas07) 36 | 37 | # subsetting 38 | kansas07[1:3,2:4] 39 | 40 | # row-wise addition 41 | kansas07[1,6]+kansas07[2,6] 42 | 43 | # column-wise addition 44 | kansas07[1:4,3]+kansas07[1:4,27] 45 | 46 | } 47 | \keyword{datasets} 48 | -------------------------------------------------------------------------------- /man/kansas09.Rd: -------------------------------------------------------------------------------- 1 | \name{kansas09} 2 | \alias{kansas09} 3 | \docType{data} 4 | \title{ 5 | County-level data from the 2005-2009 American Community Survey for Kansas for 6 | use in examples of acs package. 7 | } 8 | \description{ 9 | County-level data from the 2005-2009 American Community Survey for Kansas. 10 | Contains demographic data on sex, age, and citizenship. Used for 11 | examples in acs package. \code{kansas09}, and the corresponding 12 | one-year survey data in \code{kansas07}, provide acs objects to test 13 | and demonstrate various functions in the package. 14 | } 15 | \usage{data(kansas09)} 16 | \format{An acs-class object with 105 rows/geographies and 55 demographic 17 | variables, representing county-level ACS data for the state of Kansas. Also includes 18 | geographic and other metadata.} 19 | 20 | 21 | \source{ 22 | U.S. Census American Community Survey, 2009; \url{http://www.census.gov/} 23 | } 24 | 25 | \examples{ 26 | data(kansas09) 27 | str(kansas09) 28 | class(kansas09) 29 | 30 | geography(kansas09) 31 | 32 | # subsetting 33 | kansas09[1:3,2:4] 34 | 35 | # row-wise addition 36 | kansas09[1,6]+kansas09[2,6] 37 | 38 | # column-wise addition 39 | kansas09[1:4,3]+kansas09[1:4,27] 40 | 41 | } 42 | \keyword{datasets} 43 | -------------------------------------------------------------------------------- /man/lawrence10.Rd: -------------------------------------------------------------------------------- 1 | \name{lawrence10} 2 | \alias{lawrence10} 3 | \docType{data} 4 | \title{ 5 | Tract-level data from the 2006-2010 American Community Survey for 6 | Lawrence, MA for use in examples of acs package. 7 | } 8 | \description{ 9 | Tract-level data from the 2006-2010 American Community Survey for 10 | Lawrence, MA. Contains median household income. Used for 11 | examples in acs package. 12 | } 13 | \usage{data(lawrence10)} 14 | 15 | \format{An acs-class object with 18 rows/geographies and 1 variable, 16 | representing tract-level ACS data for the city of Lawrence, MA from 17 | 2006-2010. Also includes geographic and other metadata.} 18 | 19 | 20 | \source{ 21 | U.S. Census American Community Survey, 2010; \url{http://www.census.gov/} 22 | } 23 | 24 | \examples{ 25 | data(lawrence10) 26 | str(lawrence10) 27 | class(lawrence10) 28 | 29 | # subsetting 30 | lawrence10[1:3,1] 31 | 32 | # row-wise subtraction 33 | lawrence10[1,1]+lawrence10[2,1] 34 | 35 | } 36 | \keyword{datasets} 37 | -------------------------------------------------------------------------------- /man/plot-methods.Rd: -------------------------------------------------------------------------------- 1 | \name{plot-methods} 2 | \docType{methods} 3 | \alias{plot} 4 | \alias{plot-methods} 5 | \alias{plot,acs-method} 6 | \alias{plot,acs,acs-method} 7 | \title{acs Methods for Function \code{plot}} 8 | \description{ 9 | Plot acs objects, with both estimates and confidence intervals.} 10 | \usage{ 11 | 12 | \S4method{plot}{acs}(x, conf.level=.95, err.col="red", err.lwd=1, 13 | err.pch="-", err.cex=2, err.lty=2, x.res=300, labels="auto", 14 | by="geography", true.min=T, ...) 15 | 16 | } 17 | 18 | \arguments{ 19 | \item{x}{the acs object to be plotted} 20 | 21 | \item{conf.level}{the desired confidence interval to use for error 22 | bars; numeric between 0<1} 23 | 24 | \item{err.col}{the color to use for the error bars; analogous to 25 | graphic parameter \code{col}} 26 | 27 | \item{err.lwd}{the line weight to use for the error bars; analogous to 28 | graphic parameter \code{lwd}} 29 | 30 | \item{err.pch}{the point character to use for the error bars; analogous to 31 | graphic parameter \code{pch}} 32 | 33 | \item{err.cex}{the scaling factor to use for the error bars; analogous to 34 | graphic parameter \code{cex}} 35 | 36 | \item{err.lty}{the line type to use for the error bars; analogous to 37 | graphic parameter \code{lty}} 38 | 39 | \item{x.res}{when plot called with a single acs value (see below), x.res 40 | determines the resolution of the resulting density plot; integer 41 | (defaults to 300, i.e., the curve is drawn with 300 points)} 42 | 43 | \item{labels}{the labels to use for the x axis; defaults to either 44 | geography names or acs.colnames based on dimensions of object plotted; vector of proper length required} 45 | 46 | \item{by}{in cases where multiple rows and columns are plotted, 47 | whether to provide a different plot for each value of \code{geography} (the 48 | default) or \code{acs.colnames}; accepts either "geography" or "acs.colnames"} 49 | 50 | \item{true.min}{whether to limit the lower bound of a confidence 51 | interval to some value or now; \code{TRUE} (the default) allows for 52 | negative lower bounds; also accepts \code{FALSE} to limit lower bounds 53 | to 0, or any number, to use that as a minimum lower bound; see 54 | details.} 55 | 56 | \item{...}{provided to allow for passing of additional arguments to 57 | plot functions} 58 | 59 | } 60 | \section{Methods}{ 61 | 62 | \describe{ 63 | 64 | \item{\code{signature(object = "acs")}}{ 65 | 66 | When passed an acs object (possibly involving subsetting), \code{plot} 67 | will call a plot showing both estimates and confidence intervals for 68 | the data contained in the object. 69 | 70 | If the object contains only one row or only one column, \code{plot} 71 | will use this dimension as the y-axis and will plot each observation 72 | along the x-axis, as three points (an estimate bracketed by upper and 73 | lower confidence bounds). If the object contains multiple rows and 74 | columns, \code{plot} will return a 1-by-y "plot of plots": by default 75 | there will be one plot per row showing all the data for each 76 | geography, although this can be changed by specifying 77 | \code{by="acs.colnames"}, to plot each variable as its own plot, with 78 | all of the geographies along the x-axis. 79 | 80 | In the special case where the dimensions of the object are 81 | exactly c(1,1) (i.e., a single geography and column), 82 | \code{plot} will return a density plot of the estimate. In this 83 | case, \code{conf.level}, \code{err.col}, \code{err.lty}, and 84 | \code{err.lwd} will be used to determine the properties of the 85 | margins of error lines. (For none, use \code{conf.level=F}. 86 | For these density plots, users may also wish to set \code{xlim} 87 | and \code{x.res}, which specify the horizontal extent and 88 | resolution of the plot.) 89 | 90 | \code{plot} accepts many of the standard graphical arguments to 91 | \code{plot}, such as \code{main}, \code{sub}, \code{xlab}, \code{pch}, 92 | and \code{col}, as well new ones listed above. 93 | 94 | In some cases, the lower bound of a confidence interval may 95 | extend below 0; in some cases this is desired, especially when a 96 | variable is actually stating the \emph{difference} between two 97 | estimates. In other cases, this may seem confusing (for 98 | example, when reporting the estimated count in a particular 99 | category). Setting \code{true.min} to \code{FALSE} (or 0) will 100 | limit the lower boundary of any confidence intervals computed 101 | and plotted. 102 | 103 | } 104 | 105 | } 106 | 107 | } 108 | 109 | \examples{ 110 | 111 | # load ACS data 112 | data(kansas07) 113 | 114 | # plot a single value 115 | plot(kansas07[4,4]) 116 | 117 | # plot by geography 118 | plot(kansas07[,10]) 119 | 120 | # plot by columns 121 | plot(kansas07[4,3:10]) 122 | 123 | # a density plot for a single variable 124 | plot(kansas07[7,10]) 125 | 126 | # same, using some graphical parameters 127 | plot(kansas07[7,10], col="blue", err.col="purple", err.lty=3) 128 | 129 | plot(kansas07[7,49], col="lightblue", type="h", x.res=3000, 130 | err.col="purple", err.lty=3, err.lwd=4, conf.level=.99, 131 | main=(paste("Distribution of Females>85 Years in ", 132 | geography(kansas07)[7,1], sep="")), 133 | sub="(99-percent margin of error shown in purple)") 134 | 135 | # something more complicated... 136 | 137 | plot(kansas07[c(1,3,4),3:25], err.col="purple", 138 | pch=16, err.pch="x", err.cex=1, ylim=c(0,5000), 139 | col=rainbow(23), conf.level=.99, 140 | labels=paste("grp. ",1:23)) 141 | 142 | } 143 | \keyword{methods} 144 | 145 | -------------------------------------------------------------------------------- /man/prompt.acs.Rd: -------------------------------------------------------------------------------- 1 | \name{prompt.acs} 2 | \alias{prompt.acs} 3 | \alias{prompt} 4 | \title{Prompt for new values for metadata in an acs object. 5 | } 6 | \description{ 7 | Helper function to interactively set new values 8 | for row- and/or column-names in an acs object. 9 | } 10 | \usage{ 11 | 12 | \method{prompt}{acs}(object, filename=NA, name=NA, what="acs.colnames", 13 | geocols="all", ...) 14 | 15 | } 16 | 17 | \arguments{ 18 | 19 | \item{object}{an acs object} 20 | 21 | \item{filename}{not used; provided for S3 generic/method consistency} 22 | 23 | \item{name}{not used; provided for S3 generic/method consistency} 24 | 25 | \item{what}{which acs-class metadata slot to prompt for; either 26 | "acs.colnames" (the default), "acs.units", or "geography"} 27 | 28 | \item{geocols}{a vector, or "all", specifying which columns from the 29 | geography metadata to prompt for (optional; defaults to "all"; ignored 30 | when \code{what="acs.colnames"})} 31 | 32 | \item{...}{not used; provided for S3 generic/method consistency} 33 | 34 | } 35 | 36 | \details{ The acs package provides this S3 \code{prompt} method for 37 | acs-class objects, primarily as a "helper" function to use in calls to 38 | \code{geography(object)<-}, \code{acs.units(object)<-}, or 39 | \code{acs.colnames(object)<-}. \code{prompt} provides an interactive 40 | interface, \code{prompt}ing the user for new metadata values based on 41 | the existing ones. 42 | 43 | When \code{what="geography"} and \code{geocols} is not "all", 44 | \code{prompt} will only prompt for replacements of the values of 45 | geocols, but will still return values for all geography columns, 46 | suitable for passing to \code{geography(object)<-}. 47 | 48 | Anytime during the interactive \code{prompt()} session, a user may enter a 49 | blank line to terminate, returning only the changed values 50 | up to that point (along with the unchanged values for remaining entries.)} 51 | 52 | 53 | \value{ Returns a value of the same class and dimensions as the current 54 | geography, acs.units, or acs.colnames of object, but with new names, 55 | suitable for passing to one of the replacement methods 56 | (\code{acs.colnames<-}, (\code{acs.units<-}, or \code{geography<-}).} 57 | 58 | \examples{ 59 | 60 | data(kansas07) 61 | 62 | acs.colnames(kansas07)=prompt(kansas07, what="acs.colnames") 63 | 64 | geography(kansas07)=prompt.acs(kansas07, what="geography") 65 | 66 | 67 | } 68 | \seealso{ 69 | 70 | \code{geography<-} 71 | 72 | \code{acs.colnames<-} 73 | 74 | \code{acs.units<-} 75 | 76 | } 77 | \author{ 78 | Ezra Haber Glenn \email{eglenn@mit.edu} 79 | } 80 | 81 | -------------------------------------------------------------------------------- /man/rbind.acs.Rd: -------------------------------------------------------------------------------- 1 | \name{rbind.acs} 2 | \alias{rbind.acs} 3 | \alias{rbind} 4 | 5 | \title{Combine acs Objects by Rows 6 | } 7 | 8 | \description{ Take a pair of acs objects and combine by rows. 9 | } 10 | 11 | \usage{ 12 | \method{rbind}{acs}(e1, e2, ...) 13 | } 14 | 15 | \arguments{ 16 | \item{e1, e2}{two acs-class objects} 17 | \item{...}{provided for consistency with cbind S3 method} 18 | } 19 | 20 | \details{ When passed two acs-class objects, rbind will first check to 21 | confirm whether the objects contain compatible data: same endyear and 22 | span; same column names. If not, it will issue a warning, but will 23 | still proceed. 24 | 25 | After this check, the function will return a new acs object that has 26 | resulted from combining the two arguments row-wise. The effect is 27 | essentially the same as rbind on the underlying estimate and 28 | standard.error matrices, with all the additional acs metadata tended 29 | to.} 30 | 31 | \value{ Returns a single new acs object with all of the data contained 32 | in the two arguments. } 33 | 34 | \author{ 35 | Ezra Haber Glenn \email{eglenn@mit.edu} 36 | } 37 | 38 | -------------------------------------------------------------------------------- /man/read.acs.Rd: -------------------------------------------------------------------------------- 1 | \name{read.acs} 2 | \alias{read.acs} 3 | 4 | \title{ 5 | Reads a comma-delimited file from the American Community 6 | Survey and creates an acs object with estimates, standard errors, and 7 | associated metadata. 8 | } 9 | \description{ 10 | When passed a comma-delimited file from the U.S. Census American Community 11 | Survey (typically downloaded via the FactFinder website and unzipped), 12 | read.acs returns an acs object with estimates, standard errors, and 13 | associated metadata. 14 | 15 | Most users will prefer to start with \code{\link{acs.fetch}} to import 16 | data; \code{read.acs} is maintained as a "legacy" function, primarily 17 | for use in situations where data is not available via the Census API. 18 | } 19 | \usage{ 20 | read.acs(filename, endyear = "auto", span = "auto", col.names= "auto", 21 | acs.units = "auto", geocols = "auto", skip = "auto") 22 | } 23 | %- maybe also 'usage' for other objects documented here. 24 | \arguments{ 25 | \item{filename}{ 26 | the name of the \code{.csv}, \code{.zip}, or \code{.txt} file to be input 27 | } 28 | 29 | \item{endyear}{ an integer (or "auto") indicating the latest year of the 30 | data in the survey (e.g., for data from the 2005-2009 5-year ACS data, 31 | endyear would be 2009) } 32 | 33 | \item{span}{ an integer (should be 1, 3, or 5), or "auto" to have 34 | read.acs guess the span from the filename (e.g., for data from the 35 | 2005-2009 5-year ACS data, span would be 5) } 36 | 37 | \item{col.names}{a vector of column names to be used as 38 | \code{acs.colnames} for the object; defaults to "auto", which will 39 | result in auto-generated names from the headers lines of the input file} 40 | 41 | \item{acs.units}{ a vector of factors indicating what sort of data is 42 | contained within each column of data ("count","dollars","proportion", 43 | "ratio", "other")} 44 | 45 | \item{geocols}{ a vector of integers indicating which columns contain 46 | the geographic header information; defaults to "auto", which is the same 47 | as 3:1, which seems to be the standard for FactFinder-2 downloads} 48 | 49 | \item{skip}{an integer indicating how many rows to skip before 50 | processing the csv file; defaults to "auto", which will try to guess 51 | the proper value} 52 | } 53 | 54 | \details{ 55 | 56 | After executing a query on the U.S. Census American FactFinder site 57 | (\url{http://factfinder2.census.gov}), users can download their 58 | results as a zip file containing data in comma-delimited file format 59 | (for example, "ACS_10_5YR_B19013_with_ann.csv"). \code{read.acs} 60 | simplifies the creation of new acs objects from these files. The 61 | function uses some rudimentary algorithms to guess intelligently about 62 | values for metadata (such as \code{endyear} and \code{geography}), 63 | based on current file-format used by the Census "AmericanFactFinder 2" 64 | download site. 65 | 66 | The specified \code{filename} can be an actual \code{.csv} file, or 67 | can be the name of a \code{.zip} file downloaded from the FactFinder 68 | site. If the latter, \code{read.acs} will extract the necessary data 69 | and leave the compressed zipfile in place. 70 | 71 | As a default, \code{read.acs} assumes the first three columns will 72 | contain geographic header information, which seems to be the standard 73 | for the new Census American Factfinder download site. Users can also 74 | set different values for the \code{geocols=} to specify other columns 75 | for this geographic information. The function will use the first of 76 | these columns for geographic rownames to label estimates. (By 77 | default, then, this would be the third column of the actual file, 78 | since \code{geocols=3:1}. For files downloaded via the Census 79 | "legacy" version of FactFinder prior to 2012, users will probably want 80 | to specify \code{geocols=4:1}. 81 | 82 | As for column names, by default \code{read.acs} will scan the file to 83 | determine how many of the initial rows contain "header" information, 84 | and will generate new \code{acs.colnames} by concatenating information 85 | found in these rows. Note that this can result in \emph{very long} 86 | variable names, and users may want to modify the contents of 87 | \code{acs.colnames} after creation. 88 | 89 | Alternatively, users can inspect downloaded csv files prior to import 90 | and specify the \code{skip=} option explicitly, as with 91 | \code{read.csv} and other \code{read.XXX} functions (i.e., the value 92 | of skip is equal to the number of rows prior to the last header row). 93 | Regardless of whether \code{skip=} is set or "auto", however, the 94 | column names will be created using all of the rows at the top of the 95 | file, \emph{even the "skipped" ones}. 96 | 97 | Finally, these new \code{acs.colnames} are used to guess intelligently 98 | about values for \code{acs.units}, but currently all this includes is 99 | a check for the word "dollars" in the names; if this is not found, the 100 | columns are assumed to be "counts". 101 | 102 | When no other values are provided, \code{read.acs} will attempt to 103 | determine \code{endyear} and \code{span} from the filename. 104 | 105 | } 106 | \value{ 107 | Returns a new acs-class object with estimates, standard errors 108 | (derived from the census 90\% margins of error), and metadata associated 109 | with the survey, 110 | } 111 | 112 | \author{ 113 | Ezra Haber Glenn \email{eglenn@mit.edu} 114 | } 115 | 116 | -------------------------------------------------------------------------------- /man/sum-methods.Rd: -------------------------------------------------------------------------------- 1 | \name{sum-methods} 2 | \docType{methods} 3 | \alias{sum} 4 | \alias{sum-methods} 5 | \alias{sum,acs-method} 6 | \alias{sum,acs,acs-method} 7 | \title{acs Methods for Function \code{sum}} 8 | \description{ 9 | Returns the sum of all the estimates present in its arguments, 10 | along with proper treatment of standard errors. 11 | } 12 | 13 | \usage{ 14 | 15 | \S4method{sum}{acs}(x, agg.term=c("aggregate", "aggregate"), 16 | one.zero=FALSE, ..., na.rm=FALSE) 17 | 18 | } 19 | 20 | \arguments{ 21 | \item{x}{the acs object to be summed} 22 | 23 | \item{agg.term}{a character vector (length 1 or 2) of labels to use 24 | for the geography or acs.colnames of the new object} 25 | 26 | \item{one.zero}{a logical flag indicating whether to include 27 | standard errors for only one zero-value estimates or all (the 28 | default); see details.} 29 | 30 | \item{...}{reserved for other arguments to pass} 31 | 32 | \item{na.rm}{whether to remove \code{NA}s from the values before 33 | \code{sum}ming; defaults to \code{FALSE}.} 34 | 35 | } 36 | 37 | \section{Methods}{ 38 | \describe{ 39 | 40 | \item{\code{signature(object = "acs")}}{ 41 | When passed an acs object (possibly involving subsetting), \code{sum} 42 | will return a new acs object created by aggregating (adding) all 43 | estimates in the object, and adding the corresponding standard errors in 44 | a statistically appropriate way. (Aggregate standard errors are 45 | computed by taking the square root of the sum of the squared standard 46 | errors of the terms to be aggregated.) 47 | 48 | If the original object contains a single row, the geographic metadata and 49 | row name is preserved; if not, the geographic metadata is replaced with 50 | the term "aggregate" (or the contents of the first item of the (vector) 51 | option \code{agg.term}). 52 | 53 | If the original object contains a single column, the column names and 54 | acs.units data are preserved; if not, the column names are replaced with 55 | the term "aggregate" or the contents of the second item of the (vector) 56 | option \code{agg.term}; note: if \code{agg.term} is only one item in 57 | length, it will be repeated here if needed. 58 | 59 | All other acs-class metadata is preserved, except for the \code{modified} 60 | flag, which is set to TRUE. 61 | } 62 | }} 63 | 64 | \details{Note: when aggregating ACS data, users may want to sum many 65 | fields with "0" values for estimates, especially when working with small 66 | geographies or detailed tables that split the population into many 67 | categories. In these cases, some analysts have suggested that the 68 | traditional summation procedure for standard errors (taking the 69 | square-root of the sum of the squares of the errors) may over-inflate 70 | the associated margins of error; instead, they recommend an alternative 71 | method, which ignores all but the single largest of the standard errors 72 | for any "zero-estimate" fields. Although this is somewhat 73 | unconventional, it is provided as an additional user-specified option 74 | here, through the "one.zero" argument.} 75 | 76 | \examples{ 77 | 78 | # load ACS data 79 | data(kansas09) 80 | 81 | # aggregate the third column, all rows 82 | sum(kansas09[,3]) 83 | 84 | # aggregate the fifth row, all column 85 | sum(kansas09[5,]) 86 | 87 | # aggregate all rows, columns 3 through 25, rename rows "Kansas" and columns "Total Males" 88 | sum(kansas09[, 3:25], agg.term=c("Kansas","Total Males")) 89 | } 90 | \keyword{methods} 91 | 92 | --------------------------------------------------------------------------------