Module: Census

Defined in:
lib/rboc.rb,
lib/rboc/geo.rb,
lib/rboc/data.rb,
lib/rboc/census.rb

Overview

A module defining methods for accessing the U.S. Census data API.

Census data is divided between a number of files, like the American Community Survey (ACS) 5 year estimates file, the ACS 3 year estimates file, and the 2010 Census summary file. See the data documentation on the Census website for a description of all available files.

In rboc, the list of available files (using abbreviated names) is contained in Census::DATA_SETS. Each entry in that array corresponds to a class constant in Census assigned to a Census::DataSet instance. A DataSet object contains one or more DataSetVintage objects which represent particular vintage for the given survey. Use the DataSet#vintage_years method to see the vintage years available.

Census::ACS5.vintage_years
# => [2010, 2011, 2012]

To access a particular data set vintage, use square brackets.

Census::ACS5[2010].class
# => Census::DataSetVintage

To download data, use the query method on a DataSet or DataSetVintage object. Calling #query on the containing DataSet is the same as calling #query on the most recent vintage year.

Census::ACS5.query(q=Census::Query.new) {|q| ...}
# returns data for most recent vintage year
Census::ACS5[2010].query(q=Census::Query.new) {|q| ...}
# returns data for 2010 vintage year

If a block is passed it is called on the Census::Query argument. Queries return Census::ResultSet. For each file there is also a “raw” query method with the same signature:

Census::ACS5.query_raw(q=Census::Query.new) {|q| ...}

The raw version returns the unmodified response string, which gives the requested data in JSON format. Note, however, that #query_raw will raise an error if you try to download more than 50 variables (this is a restriction of the Census API). #query will break your request into chunks and merge them into a single response object.

Examples:

# In the following examples I assume the user has installed a key locally, so a
key is not # specified in query parameters.

# Create a query to request the total population for each county in Iowa.
require 'rboc'
my_q = Census::Query.new
my_q.variables = ['B00001_001E'] # this needs to be an array
my_q.geo.summary_level = 'county'
my_q.geo.contained_in = { 'state' => 19 }

# Pass the query to an appropriate Census file, examine the returned column names, and 
# iterate over the results.
result = Census::ACS5.query my_q
result.colnames
# => ["B00001_001E", "state", "county"]
result.each {|row| p row}
# {"B00001_001E" => "1461", "state" => "19", "county" => "001"}
# {"B00001_001E" => "823", "state" => "19", "county" => "003"}
# ...

# You can also iterate over rows without column names
result.rows.each {|row| p row}
# ["1461", "19", "001"]
# ["823", "19", "003"]
# ...

# You can use a block to set query parameters.
result2 = Census::ACS5.query do |q|
  q.variables = ['B00001_001E']
  q.geo.summary_level = 'county'
  q.geo.contained_in = { 'state' => 19 }
end
result2 == result
# => true

# There is a second, chainable syntax for defining query parameters that
# is convenient for one-liners.
result3 = Census::ACS5.query {|q| q.get('B00001_001E').for('county').in('state' => 19)}
result3 = result
# => true

Defined Under Namespace

Classes: CensusApiError, DataSet, DataSetVintage, Geography, InvalidKeyError, InvalidQueryError, NoMatchingRecordsError, Query, ResultSet, ServerSideError

Constant Summary collapse

API_URL =

Base URL of the Census data API.

'http://api.census.gov/data'
LOCAL_DATA_DIR =

Where to store local data

File.join ENV['HOME'], '.census'
CACHE_DIR =

Where cached responses from the Census API. Only data descriptions are stored.

File.join LOCAL_DATA_DIR, 'cache'
INSTALLED_KEY_PATH =

Path to the installed API key.

File.join LOCAL_DATA_DIR, 'installed_key'
DATA_DISCOVERY_URL =

Data discoverable API URL

'http://api.census.gov/data.json'
DATA_SETS =
data_names.sort

Class Method Summary collapse

Class Method Details

.get_cached_url(url) ⇒ Object

Looks for the url basename in the cache directory. If it doesn’t exist, then downloads the file from the web.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/rboc/census.rb', line 118

def get_cached_url(url)
  local_file = File.join CACHE_DIR, File.basename(url)
  if File.exists? local_file
    File.read local_file
  else
    puts "Getting #{url}"
    c = Curl::Easy.new url
    c.perform
    file_content = c.body_str
    
    File.open local_file, 'w' do |f|
      f.write file_content
    end

    file_content
  end
end

.install_key!(key) ⇒ Object

Writes the given key to a local file. If a key is installed, then you don’t have to specify a key in your query.



99
100
101
102
103
# File 'lib/rboc/census.rb', line 99

def install_key!(key)
  File.open INSTALLED_KEY_PATH, 'w' do |f|
    f.write key
  end
end

.installed_keyObject

Returns the currently installed key or nil if no key is installed.



107
108
109
110
111
112
113
# File 'lib/rboc/census.rb', line 107

def installed_key
  if File.exists? INSTALLED_KEY_PATH
    File.read INSTALLED_KEY_PATH
  else
    nil
  end
end

.setup_local_directory!Object

Set up the local directory where cached data and the installed key will be stored.



85
86
87
88
89
90
91
92
93
94
# File 'lib/rboc/census.rb', line 85

def setup_local_directory!
  unless Dir.exists? LOCAL_DATA_DIR
    Dir.mkdir LOCAL_DATA_DIR
  end

  unless Dir.exists? CACHE_DIR
    Dir.mkdir CACHE_DIR
  end

end