Skip to content

Commit e00eaea

Browse files
authored
Support variable monetary value adjustment (#91)
1 parent f360a13 commit e00eaea

File tree

10 files changed

+225
-2
lines changed

10 files changed

+225
-2
lines changed

NEWS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
- Adds `read_ihgis_codebook()` to load codebook files containing
2525
file-level metadata for downloaded IHGIS extracts. This function is
2626
currently experimental.
27+
28+
- Enables monetary value adjustment for supported IPUMS USA and IPUMS
29+
CPS variables. Use the `adjust_monetary_values` argument to `var_spec()`
30+
to include an additional adjusted variable in your extract. See the
31+
[IPUMS CPS](https://cps.ipums.org/cps/adjusted_monetary_values.shtml)
32+
and [IPUMS USA](https://usa.ipums.org/usa/adjusted_monetary_values.shtml)
33+
documentation for more information on monetary adjustment.
2734

2835
## Function + argument retirements
2936

R/api_define_extract.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,8 @@ define_extract_nhgis <- function(description = "",
840840
#' @param data_quality_flags Logical indicating whether to include data quality
841841
#' flags for the given variable. By default, data quality flags are not
842842
#' included.
843+
#' @param adjust_monetary_values Logical indicating whether to include the
844+
#' variable's inflation-adjusted equivalent, if available.
843845
#' @param preselected Logical indicating whether the variable is preselected.
844846
#' This is not needed for external use.
845847
#'
@@ -900,6 +902,7 @@ var_spec <- function(name,
900902
case_selection_type = NULL,
901903
attached_characteristics = NULL,
902904
data_quality_flags = NULL,
905+
adjust_monetary_values = NULL,
903906
preselected = NULL) {
904907
if (!is_null(case_selections) && !is_empty(case_selections)) {
905908
case_selection_type <- case_selection_type %||% "general"
@@ -911,6 +914,7 @@ var_spec <- function(name,
911914
attached_characteristics = attached_characteristics,
912915
data_quality_flags = data_quality_flags,
913916
case_selection_type = case_selection_type,
917+
adjust_monetary_values = adjust_monetary_values,
914918
preselected = preselected,
915919
class = "var_spec"
916920
)
@@ -2804,6 +2808,7 @@ validate_ipums_spec.var_spec <- function(x,
28042808
"attached_characteristics",
28052809
"data_quality_flags",
28062810
"case_selection_type",
2811+
"adjust_monetary_values",
28072812
"preselected"
28082813
)]
28092814

@@ -2850,6 +2855,12 @@ validate_ipums_spec.var_spec <- function(x,
28502855
must_be_missing_msg = " when `case_selections` is not provided",
28512856
type = "character",
28522857
choices = c("general", "detailed")
2858+
),
2859+
list(
2860+
field = "adjust_monetary_values",
2861+
required = FALSE,
2862+
length = 1,
2863+
type = "logical"
28532864
)
28542865
)
28552866

@@ -3422,6 +3433,7 @@ extract_list_from_json.micro_json <- function(extract_json, validate = FALSE) {
34223433
case_selection_type = names(def$variables[[.x]]$caseSelections),
34233434
attached_characteristics = unlist(def$variables[[.x]]$attachedCharacteristics),
34243435
data_quality_flags = def$variables[[.x]]$dataQualityFlags,
3436+
adjust_monetary_values = def$variables[[.x]]$adjustMonetaryValues,
34253437
preselected = def$variables[[.x]]$preselected
34263438
)
34273439
)

R/api_process_extract.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ format_for_json.var_spec <- function(x) {
666666
dataQualityFlags = x$data_quality_flags,
667667
caseSelections = case_selections,
668668
attachedCharacteristics = as.list(x$attached_characteristics),
669+
adjustMonetaryValues = x$adjust_monetary_values,
669670
preselected = x$preselected
670671
)
671672
)

README.Rmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ knitr::opts_chunk$set(
2020
Status:Active](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
2121
[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/ipumsr)](https://CRAN.R-project.org/package=ipumsr)
2222
[![R build
23-
status](https://github.com/ipums/ipumsr/workflows/R-CMD-check/badge.svg)](https://github.com/ipums/ipumsr/actions)
23+
status](https://github.com/ipums/ipumsr/workflows/R-CMD-check/badge.svg)](https://github.com/ipums/ipumsr/actions/workflows/R-CMD-check.yaml)
2424
[![Codecov test
2525
coverage](https://codecov.io/gh/ipums/ipumsr/branch/main/graph/badge.svg)](https://app.codecov.io/gh/ipums/ipumsr?branch=main)
2626

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
Status:Active](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
1010
[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/ipumsr)](https://CRAN.R-project.org/package=ipumsr)
1111
[![R build
12-
status](https://github.com/ipums/ipumsr/workflows/R-CMD-check/badge.svg)](https://github.com/ipums/ipumsr/actions)
12+
status](https://github.com/ipums/ipumsr/workflows/R-CMD-check/badge.svg)](https://github.com/ipums/ipumsr/actions/workflows/R-CMD-check.yaml)
1313
[![Codecov test
1414
coverage](https://codecov.io/gh/ipums/ipumsr/branch/main/graph/badge.svg)](https://app.codecov.io/gh/ipums/ipumsr?branch=main)
1515

man/var_spec.Rd

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/fixtures/amv-errors.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
http_interactions:
2+
- request:
3+
method: post
4+
uri: https://api.ipums.org/extracts?collection=atus&version=2
5+
body:
6+
encoding: ''
7+
string: '{"description":"","dataStructure":{"rectangular":{"on":"P"}},"dataFormat":"fixed_width","sampleMembers":{"includeNonRespondents":false,"includeHouseholdMembers":false},"samples":{"at2004":{}},"variables":{"AGE":{"adjustMonetaryValues":true}},"caseSelectWho":"individuals","collection":"atus","version":2}'
8+
headers:
9+
Accept: application/json, text/xml, application/xml, */*
10+
Authorization: <<<IPUMS_API_KEY>>>
11+
Content-Type: application/json
12+
response:
13+
status:
14+
status_code: 400
15+
category: Client error
16+
reason: Bad Request
17+
message: 'Client error: (400) Bad Request'
18+
headers:
19+
cache-control: no-cache
20+
content-type: application/json; charset=utf-8
21+
date: Fri, 30 May 2025 12:35:20 GMT
22+
referrer-policy: strict-origin-when-cross-origin
23+
server: nginx/1.22.1
24+
vary: Origin
25+
x-content-type-options: nosniff
26+
x-frame-options: SAMEORIGIN
27+
x-permitted-cross-domain-policies: none
28+
x-ratelimit-limit: '-1'
29+
x-ratelimit-remaining: '0'
30+
x-ratelimit-reset: '0'
31+
x-request-id: 7ace3d95-de09-4080-9921-84e546bab908
32+
x-runtime: '0.486823'
33+
x-xss-protection: '0'
34+
content-length: '148'
35+
body:
36+
encoding: ''
37+
file: no
38+
string: '{"type":"SemanticValidationError","status":{"code":400,"name":"Bad
39+
Request"},"detail":["Monetary value adjustment is not supported for IPUMS
40+
ATUS"]}'
41+
recorded_at: 2025-05-30 12:35:21 GMT
42+
recorded_with: vcr/1.7.0, webmockr/2.0.0
43+
- request:
44+
method: post
45+
uri: https://api.ipums.org/extracts?collection=cps&version=2
46+
body:
47+
encoding: ''
48+
string: '{"description":"","dataStructure":{"rectangular":{"on":"P"}},"dataFormat":"fixed_width","sampleMembers":{"includeNonRespondents":false,"includeHouseholdMembers":false},"samples":{"cps2012_03s":{}},"variables":{"AGE":{"adjustMonetaryValues":true}},"caseSelectWho":"individuals","collection":"cps","version":2}'
49+
headers:
50+
Accept: application/json, text/xml, application/xml, */*
51+
Authorization: <<<IPUMS_API_KEY>>>
52+
Content-Type: application/json
53+
response:
54+
status:
55+
status_code: 400
56+
category: Client error
57+
reason: Bad Request
58+
message: 'Client error: (400) Bad Request'
59+
headers:
60+
cache-control: no-cache
61+
content-type: application/json; charset=utf-8
62+
date: Fri, 30 May 2025 12:35:20 GMT
63+
referrer-policy: strict-origin-when-cross-origin
64+
server: nginx/1.22.1
65+
vary: Origin
66+
x-content-type-options: nosniff
67+
x-frame-options: SAMEORIGIN
68+
x-permitted-cross-domain-policies: none
69+
x-ratelimit-limit: '-1'
70+
x-ratelimit-remaining: '0'
71+
x-ratelimit-reset: '0'
72+
x-request-id: c0ed18c1-416c-4370-8d7b-a47a085e1ff0
73+
x-runtime: '0.411693'
74+
x-xss-protection: '0'
75+
content-length: '142'
76+
body:
77+
encoding: ''
78+
file: no
79+
string: '{"type":"SemanticValidationError","status":{"code":400,"name":"Bad
80+
Request"},"detail":["Monetary value adjustment is not supported for AGE."]}'
81+
recorded_at: 2025-05-30 12:35:21 GMT
82+
recorded_with: vcr/1.7.0, webmockr/2.0.0

tests/fixtures/amv-extract.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
http_interactions:
2+
- request:
3+
method: post
4+
uri: https://api.ipums.org/extracts?collection=cps&version=2
5+
body:
6+
encoding: ''
7+
string: '{"description":"amv testing","dataStructure":{"rectangular":{"on":"P"}},"dataFormat":"fixed_width","sampleMembers":{"includeNonRespondents":false,"includeHouseholdMembers":false},"samples":{"cps2022_03s":{}},"variables":{"AGE":{},"HOURWAGE":{"adjustMonetaryValues":true}},"caseSelectWho":"individuals","collection":"cps","version":2}'
8+
headers:
9+
Accept: application/json, text/xml, application/xml, */*
10+
Authorization: <<<IPUMS_API_KEY>>>
11+
Content-Type: application/json
12+
response:
13+
status:
14+
status_code: 200
15+
category: Success
16+
reason: OK
17+
message: 'Success: (200) OK'
18+
headers:
19+
cache-control: max-age=0, private, must-revalidate
20+
content-type: application/json; charset=utf-8
21+
date: Fri, 30 May 2025 12:35:24 GMT
22+
etag: W/"b8fc19e11776e4dabb0afb3c7b826f79"
23+
referrer-policy: strict-origin-when-cross-origin
24+
server: nginx/1.22.1
25+
vary: Origin
26+
x-content-type-options: nosniff
27+
x-frame-options: SAMEORIGIN
28+
x-permitted-cross-domain-policies: none
29+
x-ratelimit-limit: '-1'
30+
x-ratelimit-remaining: '0'
31+
x-ratelimit-reset: '0'
32+
x-request-id: 58448277-611e-4058-af9a-439944340bad
33+
x-runtime: '1.447855'
34+
x-xss-protection: '0'
35+
content-length: '651'
36+
body:
37+
encoding: ''
38+
file: no
39+
string: '{"number":179,"status":"queued","email":"robe2037@umn.edu","downloadLinks":{},"extractDefinition":{"version":2,"dataStructure":{"rectangular":{"on":"P"}},"dataFormat":"fixed_width","caseSelectWho":"individuals","description":"amv
40+
testing","samples":{"cps2022_03s":{}},"variables":{"YEAR":{"preselected":true},"SERIAL":{"preselected":true},"MONTH":{"preselected":true},"CPSID":{"preselected":true},"ASECFLAG":{"preselected":true},"ASECWTH":{"preselected":true},"PERNUM":{"preselected":true},"CPSIDP":{"preselected":true},"CPSIDV":{"preselected":true},"ASECWT":{"preselected":true},"AGE":{},"HOURWAGE":{"adjustMonetaryValues":true}},"collection":"cps"}}'
41+
recorded_at: 2025-05-30 12:35:24 GMT
42+
recorded_with: vcr/1.7.0, webmockr/2.0.0

tests/testthat/test_api_process_extract.R

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,54 @@ test_that("Can submit an ATUS extract", {
213213
)
214214
})
215215

216+
test_that("Can submit extract with monetary value adjustment", {
217+
x <- define_extract_micro(
218+
"cps",
219+
"amv testing",
220+
samples = "cps2022_03s",
221+
variables = list("AGE", var_spec("HOURWAGE", adjust_monetary_values = TRUE))
222+
)
223+
224+
expect_true(x$variables$HOURWAGE$adjust_monetary_values)
225+
expect_null(x$variables$AGE$adjust_monetary_values)
226+
227+
vcr::use_cassette("amv-extract", {
228+
suppressMessages(
229+
submitted <- submit_extract(x)
230+
)
231+
})
232+
233+
expect_true(submitted$variables$HOURWAGE$adjust_monetary_values)
234+
expect_null(submitted$variables$AGE$adjust_monetary_values)
235+
})
236+
237+
test_that("Error on unsupported monetary value adjustment requests", {
238+
vcr::use_cassette("amv-errors", {
239+
expect_error(
240+
submit_extract(
241+
define_extract_micro(
242+
"atus",
243+
"",
244+
samples = "at2004",
245+
variables = var_spec("AGE", adjust_monetary_values = TRUE)
246+
)
247+
),
248+
"Monetary value adjustment is not supported for IPUMS ATUS"
249+
)
250+
expect_error(
251+
submit_extract(
252+
define_extract_micro(
253+
"cps",
254+
"",
255+
samples = "cps2012_03s",
256+
variables = var_spec("AGE", adjust_monetary_values = TRUE)
257+
)
258+
),
259+
"Monetary value adjustment is not supported for AGE"
260+
)
261+
})
262+
})
263+
216264
test_that("Submission of time-use variable with wrong owner throws error", {
217265
skip_if_no_api_access()
218266

vignettes/ipums-api-micro.Rmd

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,33 @@ Each data quality flag corresponds to one or more variables, and the codes for
413413
each flag vary based on the sample. See the documentation for the IPUMS
414414
collection of interest for more information about data quality flag codes.
415415

416+
### Monetary value adjustment
417+
418+
IPUMS CPS and IPUMS USA offer the option to standardize income or other
419+
dollar values to 2010 dollars. This option both retains the original IPUMS
420+
variable in your extract and adds a new, adjusted variable called
421+
`{VARIABLE NAME}_cpiu_2010` that contains the inflation-adjusted values.
422+
Inflation adjusted values are only available for continuous variables that
423+
represent dollar amounts.
424+
425+
To request an adjusted variable in an extract, use the `adjust_monetary_values`
426+
argument:
427+
428+
```{r}
429+
#| eval: false
430+
define_extract_micro(
431+
"cps",
432+
description = "monetary value adjustment example",
433+
samples = "cps2012_03s",
434+
variables = var_spec("HOURWAGE", adjust_monetary_values = TRUE)
435+
)
436+
```
437+
438+
Further information on monetary value adjustment can be found on
439+
the [IPUMS CPS](https://cps.ipums.org/cps/adjusted_monetary_values.shtml)
440+
and [IPUMS USA](https://usa.ipums.org/usa/adjusted_monetary_values.shtml)
441+
websites.
442+
416443
## Time use variables
417444

418445
For IPUMS Time Use collections (ATUS, AHTUS, and MTUS), users can request

0 commit comments

Comments
 (0)