Once you have downloaded an IPUMS extract, the next step is to load its data into R for analysis.
For more information about IPUMS data and how to generate and download a data extract, see the introduction to IPUMS data.
IPUMS extract structure
IPUMS extracts will be organized slightly differently for different IPUMS projects. In general, all projects will provide multiple files in a data extract. The files most relevant to ipumsr are:
- The metadata file containing information about the variables included in the extract data
- One or more data files, depending on the project and specifications in the extract
Both of these files are necessary to properly load data into R. Obviously, the data files contain the actual data values to be loaded. But because these are often in fixed-width format, the metadata files are required to correctly parse the data on load.
Even for .csv files, the metadata file allows for the addition of contextual variable information to the loaded data. This makes it much easier to interpret the values in the data variables and effectively use them in your data processing pipeline. See the value labels vignette for more information on working with these labels.
Reading microdata extracts
Microdata extracts typically provide their metadata in a DDI (.xml) file separate from the compressed data (.dat.gz) files.
Provide the path to the DDI file to read_ipums_micro()
to directly load its associated data file into R.
library(ipumsr)
library(dplyr)
# Example data
cps_ddi_file <- ipums_example("cps_00157.xml")
cps_data <- read_ipums_micro(cps_ddi_file)
head(cps_data)
#> # A tibble: 6 × 8
#> YEAR SERIAL MONTH ASECWTH STATEFIP PERNUM ASECWT INCTOT
#> <dbl> <dbl> <int+lbl> <dbl> <int+lbl> <dbl> <dbl> <dbl+lbl>
#> 1 1962 80 3 [March] 1476. 55 [Wisconsin] 1 1476. 4883
#> 2 1962 80 3 [March] 1476. 55 [Wisconsin] 2 1471. 5800
#> 3 1962 80 3 [March] 1476. 55 [Wisconsin] 3 1579. 999999998 [Missin…
#> 4 1962 82 3 [March] 1598. 27 [Minnesota] 1 1598. 14015
#> 5 1962 83 3 [March] 1707. 27 [Minnesota] 1 1707. 16552
#> 6 1962 84 3 [March] 1790. 27 [Minnesota] 1 1790. 6375
Note that you provide the path to the DDI file, not the data file. This is because ipumsr needs to find both the DDI and data files to read in your data, and the DDI file includes the name of the data file, whereas the data file contains only the raw data.
The loaded data have been parsed correctly and include variable
metadata in each column. For a summary of the column contents, use
ipums_var_info()
:
ipums_var_info(cps_data)
#> # A tibble: 8 × 4
#> var_name var_label var_desc val_labels
#> <chr> <chr> <chr> <list>
#> 1 YEAR Survey year "YEAR r… <tibble>
#> 2 SERIAL Household serial number "SERIAL… <tibble>
#> 3 MONTH Month "MONTH … <tibble>
#> 4 ASECWTH Annual Social and Economic Supplement Household … "ASECWT… <tibble>
#> 5 STATEFIP State (FIPS code) "STATEF… <tibble>
#> 6 PERNUM Person number in sample unit "PERNUM… <tibble>
#> 7 ASECWT Annual Social and Economic Supplement Weight "ASECWT… <tibble>
#> 8 INCTOT Total personal income "INCTOT… <tibble>
This information is also attached to specific columns. You can obtain
it with attributes()
or by using ipumsr helpers:
attributes(cps_data$MONTH)
#> $labels
#> January February March April May June July August
#> 1 2 3 4 5 6 7 8
#> September October November December
#> 9 10 11 12
#>
#> $class
#> [1] "haven_labelled" "vctrs_vctr" "integer"
#>
#> $label
#> [1] "Month"
#>
#> $var_desc
#> [1] "MONTH indicates the calendar month of the CPS interview."
ipums_val_labels(cps_data$MONTH)
#> # A tibble: 12 × 2
#> val lbl
#> <int> <chr>
#> 1 1 January
#> 2 2 February
#> 3 3 March
#> 4 4 April
#> 5 5 May
#> 6 6 June
#> 7 7 July
#> 8 8 August
#> 9 9 September
#> 10 10 October
#> 11 11 November
#> 12 12 December
While this is the most straightforward way to load microdata, it’s
often advantageous to independently load the DDI file into an
ipums_ddi
object containing the metadata:
cps_ddi <- read_ipums_ddi(cps_ddi_file)
cps_ddi
#> An IPUMS DDI for IPUMS CPS with 8 variables
#> Extract 'cps_00157.dat' created on 2023-07-10
#> User notes: User-provided description: Reproducing cps00006
This is because many common data processing functions have the side-effect of removing these attributes:
# This doesn't actually change the data...
cps_data2 <- cps_data %>%
mutate(MONTH = ifelse(TRUE, MONTH, MONTH))
# but removes attributes!
ipums_val_labels(cps_data2$MONTH)
#> # A tibble: 0 × 2
#> # ℹ 2 variables: val <dbl>, lbl <chr>
In this case, you can always use the separate DDI as a metadata reference:
ipums_val_labels(cps_ddi, var = MONTH)
#> # A tibble: 12 × 2
#> val lbl
#> <dbl> <chr>
#> 1 1 January
#> 2 2 February
#> 3 3 March
#> 4 4 April
#> 5 5 May
#> 6 6 June
#> 7 7 July
#> 8 8 August
#> 9 9 September
#> 10 10 October
#> 11 11 November
#> 12 12 December
Or even reattach the metadata, assuming the variable names still match those in the DDI:
cps_data2 <- set_ipums_var_attributes(cps_data2, cps_ddi)
ipums_val_labels(cps_data2$MONTH)
#> # A tibble: 12 × 2
#> val lbl
#> <int> <chr>
#> 1 1 January
#> 2 2 February
#> 3 3 March
#> 4 4 April
#> 5 5 May
#> 6 6 June
#> 7 7 July
#> 8 8 August
#> 9 9 September
#> 10 10 October
#> 11 11 November
#> 12 12 December
Hierarchical extracts
IPUMS microdata can come in either rectangular or hierarchical format.
Rectangular data are transformed such that every row of data
represents the same type of record. For instance, each row will
represent a person record, and all household-level information for that
person will be included in the same row. (This is the case for
cps_data
shown in the example above.)
Hierarchical data have records of different types interspersed in a single file. For instance, a household record will be included in its own row followed by the person records associated with that household.
Hierarchical data can be loaded in list format or long format.
read_ipums_micro()
will read in long format:
cps_hier_ddi <- read_ipums_ddi(ipums_example("cps_00159.xml"))
read_ipums_micro(cps_hier_ddi)
#> Use of data from IPUMS CPS is subject to conditions including that users should cite the data appropriately. Use command `ipums_conditions()` for more details.
#> # A tibble: 11,053 × 9
#> RECTYPE YEAR SERIAL MONTH ASECWTH STATEFIP PERNUM ASECWT INCTOT
#> <chr+lbl> <dbl> <dbl> <int+lb> <dbl> <int+lb> <dbl> <dbl> <dbl+lbl>
#> 1 H [Househ… 1962 80 3 [Mar… 1476. 55 [Wis… NA NA NA
#> 2 P [Person… 1962 80 NA NA NA 1 1476. 4.88e3
#> 3 P [Person… 1962 80 NA NA NA 2 1471. 5.8 e3
#> 4 P [Person… 1962 80 NA NA NA 3 1579. 1.00e9 [Mis…
#> 5 H [Househ… 1962 82 3 [Mar… 1598. 27 [Min… NA NA NA
#> 6 P [Person… 1962 82 NA NA NA 1 1598. 1.40e4
#> 7 H [Househ… 1962 83 3 [Mar… 1707. 27 [Min… NA NA NA
#> 8 P [Person… 1962 83 NA NA NA 1 1707. 1.66e4
#> 9 H [Househ… 1962 84 3 [Mar… 1790. 27 [Min… NA NA NA
#> 10 P [Person… 1962 84 NA NA NA 1 1790. 6.38e3
#> # ℹ 11,043 more rows
The long format consists of a single tibble
that includes rows with varying record types. In this example, some rows
have a record type of “Household” and others have a record type of
“Person”. Variables that do not apply to a particular record type will
be filled with NA
in rows of that record type.
To read data in list format, use
read_ipums_micro_list()
. This function returns a list where
each element contains all the records for a given record type:
read_ipums_micro_list(cps_hier_ddi)
#> Use of data from IPUMS CPS is subject to conditions including that users should cite the data appropriately. Use command `ipums_conditions()` for more details.
#> $HOUSEHOLD
#> # A tibble: 3,385 × 6
#> RECTYPE YEAR SERIAL MONTH ASECWTH STATEFIP
#> <chr+lbl> <dbl> <dbl> <int+lbl> <dbl> <int+lbl>
#> 1 H [Household Record] 1962 80 3 [March] 1476. 55 [Wisconsin]
#> 2 H [Household Record] 1962 82 3 [March] 1598. 27 [Minnesota]
#> 3 H [Household Record] 1962 83 3 [March] 1707. 27 [Minnesota]
#> 4 H [Household Record] 1962 84 3 [March] 1790. 27 [Minnesota]
#> 5 H [Household Record] 1962 107 3 [March] 4355. 19 [Iowa]
#> 6 H [Household Record] 1962 108 3 [March] 1479. 19 [Iowa]
#> 7 H [Household Record] 1962 122 3 [March] 3603. 27 [Minnesota]
#> 8 H [Household Record] 1962 124 3 [March] 4104. 55 [Wisconsin]
#> 9 H [Household Record] 1962 125 3 [March] 2182. 55 [Wisconsin]
#> 10 H [Household Record] 1962 126 3 [March] 1826. 55 [Wisconsin]
#> # ℹ 3,375 more rows
#>
#> $PERSON
#> # A tibble: 7,668 × 6
#> RECTYPE YEAR SERIAL PERNUM ASECWT INCTOT
#> <chr+lbl> <dbl> <dbl> <dbl> <dbl> <dbl+lbl>
#> 1 P [Person Record] 1962 80 1 1476. 4883
#> 2 P [Person Record] 1962 80 2 1471. 5800
#> 3 P [Person Record] 1962 80 3 1579. 999999998 [Missing. (1962-1964 …
#> 4 P [Person Record] 1962 82 1 1598. 14015
#> 5 P [Person Record] 1962 83 1 1707. 16552
#> 6 P [Person Record] 1962 84 1 1790. 6375
#> 7 P [Person Record] 1962 107 1 4355. 999999999 [N.I.U.]
#> 8 P [Person Record] 1962 107 2 1386. 0
#> 9 P [Person Record] 1962 107 3 1629. 600
#> 10 P [Person Record] 1962 107 4 1432. 999999999 [N.I.U.]
#> # ℹ 7,658 more rows
read_ipums_micro()
and
read_ipums_micro_list()
also support partial loading by
selecting only a subset of columns or a limited number of rows. See the
documentation for more details about other options.
Reading IPUMS NHGIS extracts
Unlike microdata projects, NHGIS extracts provide their data and
metadata files bundled into a single .zip archive.
read_nhgis()
anticipates this structure and can read data
files directly from this file without the need to manually extract the
files:
nhgis_ex1 <- ipums_example("nhgis0972_csv.zip")
nhgis_data <- read_nhgis(nhgis_ex1)
#> Use of data from NHGIS is subject to conditions including that users should cite the data appropriately. Use command `ipums_conditions()` for more details.
#> Rows: 71 Columns: 25
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> chr (9): GISJOIN, STUSAB, CMSA, PMSA, PMSAA, AREALAND, AREAWAT, ANPSADPI, F...
#> dbl (13): YEAR, MSA_CMSAA, INTPTLAT, INTPTLNG, PSADC, D6Z001, D6Z002, D6Z003...
#> lgl (3): DIVISIONA, REGIONA, STATEA
#>
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
nhgis_data
#> # A tibble: 71 × 25
#> GISJOIN YEAR STUSAB CMSA DIVISIONA MSA_CMSAA PMSA PMSAA REGIONA STATEA
#> <chr> <dbl> <chr> <chr> <lgl> <dbl> <chr> <chr> <lgl> <lgl>
#> 1 G0080 1990 OH 28 NA 1692 Akron, O… 0080 NA NA
#> 2 G0360 1990 CA 49 NA 4472 Anaheim-… 0360 NA NA
#> 3 G0440 1990 MI 35 NA 2162 Ann Arbo… 0440 NA NA
#> 4 G0620 1990 IL 14 NA 1602 Aurora--… 0620 NA NA
#> 5 G0845 1990 PA 78 NA 6282 Beaver C… 0845 NA NA
#> 6 G0875 1990 NJ 70 NA 5602 Bergen--… 0875 NA NA
#> 7 G1120 1990 MA 07 NA 1122 Boston, … 1120 NA NA
#> 8 G1125 1990 CO 34 NA 2082 Boulder-… 1125 NA NA
#> 9 G1145 1990 TX 42 NA 3362 Brazoria… 1145 NA NA
#> 10 G1160 1990 CT 70 NA 5602 Bridgepo… 1160 NA NA
#> # ℹ 61 more rows
#> # ℹ 15 more variables: AREALAND <chr>, AREAWAT <chr>, ANPSADPI <chr>,
#> # FUNCSTAT <chr>, INTPTLAT <dbl>, INTPTLNG <dbl>, PSADC <dbl>, D6Z001 <dbl>,
#> # D6Z002 <dbl>, D6Z003 <dbl>, D6Z004 <dbl>, D6Z005 <dbl>, D6Z006 <dbl>,
#> # D6Z007 <dbl>, D6Z008 <dbl>
Like microdata extracts, the data include variable-level metadata, where available:
attributes(nhgis_data$D6Z001)
#> $label
#> [1] "Total area: 1989 to March 1990"
#>
#> $var_desc
#> [1] "Table D6Z: Year Structure Built (Universe: Housing Units)"
However, variable metadata for NHGIS data are slightly different than
those provided by microdata products. First, they come from a .txt
codebook file rather than an .xml DDI file. Codebooks can still be
loaded into an ipums_ddi
object, but fields that do not
apply to aggregate data will be empty. In general, NHGIS codebooks
provide only variable labels and descriptions, along with citation
information.
nhgis_cb <- read_nhgis_codebook(nhgis_ex1)
# Most useful metadata for NHGIS is for variable labels:
ipums_var_info(nhgis_cb) %>%
select(var_name, var_label, var_desc)
#> # A tibble: 25 × 3
#> var_name var_label var_desc
#> <chr> <chr> <chr>
#> 1 GISJOIN GIS Join Match Code ""
#> 2 YEAR Data File Year ""
#> 3 STUSAB State/US Abbreviation ""
#> 4 CMSA Consolidated Metropolitan Statistical Area ""
#> 5 DIVISIONA Division Code ""
#> 6 MSA_CMSAA Metropolitan Statistical Area/Consolidated Metropolitan S… ""
#> 7 PMSA Primary Metropolitan Statistical Area Name ""
#> 8 PMSAA Primary Metropolitan Statistical Area Code ""
#> 9 REGIONA Region Code ""
#> 10 STATEA State Code ""
#> # ℹ 15 more rows
By design, NHGIS codebooks are human-readable, and it may be easier
to interpret their contents in raw format. To view the codebook itself
without converting to an ipums_ddi
object, set
raw = TRUE
.
nhgis_cb <- read_nhgis_codebook(nhgis_ex1, raw = TRUE)
cat(nhgis_cb[1:20], sep = "\n")
#> --------------------------------------------------------------------------------
#> Codebook for NHGIS data file 'nhgis0972_ds135_1990_pmsa'
#> --------------------------------------------------------------------------------
#>
#> Contents
#> - Data Summary
#> - Data Dictionary
#> - Citation and Use
#>
#> Additional documentation on NHGIS data sources is available at:
#> https://www.nhgis.org/documentation/tabular-data
#>
#> --------------------------------------------------------------------------------
#> Data Summary
#> --------------------------------------------------------------------------------
#>
#> Year: 1990
#> Geographic level: Consolidated Metropolitan Statistical Area--Primary Metropolitan Statistical Area
#> Dataset: 1990 Census: SSTF 9 - Housing Characteristics of New Units
#> NHGIS code: 1990_SSTF09
Handling multiple files
For more complicated NHGIS extracts that include data from multiple data sources, the provided .zip archive will contain multiple codebook and data files.
You can view the files contained in an extract to determine if this is the case:
nhgis_ex2 <- ipums_example("nhgis0731_csv.zip")
ipums_list_files(nhgis_ex2)
#> # A tibble: 2 × 2
#> type file
#> <chr> <chr>
#> 1 data nhgis0731_csv/nhgis0731_ds239_20185_nation.csv
#> 2 data nhgis0731_csv/nhgis0731_ts_nominal_state.csv
In these cases, you can use the file_select
argument to
indicate which file to load. file_select
supports most
features of the tidyselect
selection language. (See ?selection_language
for
documentation of the features supported in ipumsr.)
nhgis_data2 <- read_nhgis(nhgis_ex2, file_select = contains("nation"))
nhgis_data3 <- read_nhgis(nhgis_ex2, file_select = contains("ts_nominal_state"))
The matching codebook should automatically be loaded and attached to the data:
attributes(nhgis_data2$AJWBE001)
#> $label
#> [1] "Estimates: Total"
#>
#> $var_desc
#> [1] "Table AJWB: Sex by Age (Universe: Total population)"
attributes(nhgis_data3$A00AA1790)
#> $label
#> [1] "1790: Persons: Total"
#>
#> $var_desc
#> [1] "Table A00: Total Population"
(If for some reason the codebook is not loaded correctly, you can
load it separately with read_nhgis_codebook()
, which also
accepts a file_select
specification.)
file_select
also accepts the full path or the index of
the file to load:
# Match by file name
read_nhgis(nhgis_ex2, file_select = "nhgis0731_csv/nhgis0731_ds239_20185_nation.csv")
# Match first file in extract
read_nhgis(nhgis_ex2, file_select = 1)
NHGIS data formats
CSV data
NHGIS data are most easily handled in .csv format.
read_nhgis()
uses readr::read_csv()
to handle
the generation of column type specifications. If the guessed
specifications are incorrect, you can use the col_types
argument to adjust. This is most likely to occur for columns that
contain geographic codes that are stored as numeric values:
# Convert MSA codes to character format
read_nhgis(
nhgis_ex1,
col_types = c(MSA_CMSAA = "c"),
verbose = FALSE
)
#> # A tibble: 71 × 25
#> GISJOIN YEAR STUSAB CMSA DIVISIONA MSA_CMSAA PMSA PMSAA REGIONA STATEA
#> <chr> <dbl> <chr> <chr> <lgl> <chr> <chr> <chr> <lgl> <lgl>
#> 1 G0080 1990 OH 28 NA 1692 Akron, O… 0080 NA NA
#> 2 G0360 1990 CA 49 NA 4472 Anaheim-… 0360 NA NA
#> 3 G0440 1990 MI 35 NA 2162 Ann Arbo… 0440 NA NA
#> 4 G0620 1990 IL 14 NA 1602 Aurora--… 0620 NA NA
#> 5 G0845 1990 PA 78 NA 6282 Beaver C… 0845 NA NA
#> 6 G0875 1990 NJ 70 NA 5602 Bergen--… 0875 NA NA
#> 7 G1120 1990 MA 07 NA 1122 Boston, … 1120 NA NA
#> 8 G1125 1990 CO 34 NA 2082 Boulder-… 1125 NA NA
#> 9 G1145 1990 TX 42 NA 3362 Brazoria… 1145 NA NA
#> 10 G1160 1990 CT 70 NA 5602 Bridgepo… 1160 NA NA
#> # ℹ 61 more rows
#> # ℹ 15 more variables: AREALAND <chr>, AREAWAT <chr>, ANPSADPI <chr>,
#> # FUNCSTAT <chr>, INTPTLAT <dbl>, INTPTLNG <dbl>, PSADC <dbl>, D6Z001 <dbl>,
#> # D6Z002 <dbl>, D6Z003 <dbl>, D6Z004 <dbl>, D6Z005 <dbl>, D6Z006 <dbl>,
#> # D6Z007 <dbl>, D6Z008 <dbl>
Fixed-width data
read_nhgis()
also handles NHGIS files provided in
fixed-width format:
nhgis_fwf <- ipums_example("nhgis0730_fixed.zip")
nhgis_fwf_data <- read_nhgis(nhgis_fwf, file_select = matches("ts_nominal"))
#> Use of data from NHGIS is subject to conditions including that users should cite the data appropriately. Use command `ipums_conditions()` for more details.
#> Rows: 84 Columns: 28
#> ── Column specification ────────────────────────────────────────────────────────
#>
#> chr (4): GISJOIN, STATE, STATEFP, STATENH
#> dbl (24): A00AA1790, A00AA1800, A00AA1810, A00AA1820, A00AA1830, A00AA1840, ...
#>
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
nhgis_fwf_data
#> # A tibble: 84 × 28
#> GISJOIN STATE STATEFP STATENH A00AA1790 A00AA1800 A00AA1810 A00AA1820
#> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 G010 Alabama 01 010 NA NA NA 127901
#> 2 G020 Alaska 02 020 NA NA NA NA
#> 3 G025 Alaska Terri… NA 025 NA NA NA NA
#> 4 G040 Arizona 04 040 NA NA NA NA
#> 5 G045 Arizona Terr… NA 045 NA NA NA NA
#> 6 G050 Arkansas 05 050 NA NA NA NA
#> 7 G055 Arkansas Ter… NA 055 NA NA NA 14273
#> 8 G060 California 06 060 NA NA NA NA
#> 9 G080 Colorado 08 080 NA NA NA NA
#> 10 G085 Colorado Ter… NA 085 NA NA NA NA
#> # ℹ 74 more rows
#> # ℹ 20 more variables: A00AA1830 <dbl>, A00AA1840 <dbl>, A00AA1850 <dbl>,
#> # A00AA1860 <dbl>, A00AA1870 <dbl>, A00AA1880 <dbl>, A00AA1890 <dbl>,
#> # A00AA1900 <dbl>, A00AA1910 <dbl>, A00AA1920 <dbl>, A00AA1930 <dbl>,
#> # A00AA1940 <dbl>, A00AA1950 <dbl>, A00AA1960 <dbl>, A00AA1970 <dbl>,
#> # A00AA1980 <dbl>, A00AA1990 <dbl>, A00AA2000 <dbl>, A00AA2010 <dbl>,
#> # A00AA2020 <dbl>
The correct parsing of NHGIS fixed-width files is driven by the column parsing information contained in the .do file provided in the .zip archive. This contains information not only about column positions and data types, but also implicit decimals in the data.
If you no longer have access to the .do file, it is best to resubmit
and/or re-download the extract (you may also consider converting to .csv
format in the process). If you have moved the .do file, provide its file
path to the do_file
argument to use its column parsing
information.
Note that unlike read_ipums_micro()
, fixed-width files
for NHGIS are still handled by providing the path to the data
file, not the metadata file (i.e. you cannot provide an
ipums_ddi
object to the data_file
argument of
read_nhgis()
). This is for syntactical consistency with the
loading of NHGIS .csv files.
Reading spatial data
IPUMS distributes spatial data for several projects.
- For microdata projects, spatial data are distributed in shapefiles on dedicated geography pages separate from the standard extract system. Look for a Geography and GIS link in the Supplemental Data section of the project’s website to find spatial data files and information.
- For NHGIS, spatial data can be obtained within the extract system. Shapefiles will be distributed in their own .zip archive alongside the .zip archive containing the extract’s tabular data (if any tabular data are requested).
Use read_ipums_sf()
to load spatial data from any of
these sources as an sf
object from sf.
read_ipums_sf()
also supports the loading of spatial
files within .zip archives and the file_select
syntax for
file selection when multiple internal files are present.
nhgis_shp_file <- ipums_example("nhgis0972_shape_small.zip")
shp_data <- read_ipums_sf(nhgis_shp_file)
head(shp_data)
#> Simple feature collection with 6 features and 8 fields
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
#> Bounding box: xmin: -129888.4 ymin: -967051.1 xmax: 1948770 ymax: 751282.5
#> Projected CRS: USA_Contiguous_Albers_Equal_Area_Conic
#> # A tibble: 6 × 9
#> PMSA MSACMSA ALTCMSA GISJOIN GISJOIN2 SHAPE_AREA SHAPE_LEN GISJOIN3
#> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <chr>
#> 1 3280 3282 41 G3280 3280 2840869482. 320921. G32823280
#> 2 5760 5602 70 G5760 5760 237428573. 126226. G56025760
#> 3 1145 3362 42 G1145 1145 3730749183. 489789. G33621145
#> 4 1920 1922 31 G1920 1920 12068105590. 543164. G19221920
#> 5 0080 1692 28 G0080 0080 2401347006. 218892. G16920080
#> 6 1640 1642 21 G1640 1640 5608404797. 415671. G16421640
#> # ℹ 1 more variable: geometry <MULTIPOLYGON [m]>
These data can then be joined to associated tabular data. To preserve
IPUMS attributes from the tabular data used in the join, use an
ipums_shape_*_join()
function:
joined_data <- ipums_shape_left_join(
nhgis_data,
shp_data,
by = "GISJOIN"
)
attributes(joined_data$MSA_CMSAA)
#> $label
#> [1] "Metropolitan Statistical Area/Consolidated Metropolitan Statistical Area Code"
#>
#> $var_desc
#> [1] ""
For NHGIS data, the join code typically corresponds to the
GISJOIN
variable. However, for microdata projects, the
variable name used for a geographic level in the tabular data may differ
from that in the spatial data. Consult the documentation and metadata
for these files to identify the correct join columns and use the
by
argument to join on these columns.
Once joined, data include both statistical and spatial information along with the variable metadata.
Harmonized vs. non-harmonized data
Longitudinal analysis of geographic data is complicated by the fact that geographic boundaries shift over time. IPUMS therefore provides multiple types of spatial data:
- Harmonized (also called “integrated” or “consistent”) files have been made consistent over time by combining geographies that share area for different time periods.
- Non-harmonized, or year-specific, files represent geographies at a specific point in time.
Furthermore, some NHGIS time series tables have been standardized such that the statistics have been adjusted to apply to a year-specific geographical boundary.
When using spatial data, it is important to consult the project-specific documentation to ensure you are using the most appropriate boundaries for your research question and the data included in your analysis. As always, documentation for the IPUMS project you’re working with should explain the different options available.