Skip to content

Commit

Permalink
Added carry_backwards()
Browse files Browse the repository at this point in the history
  • Loading branch information
marberts committed Nov 17, 2023
1 parent a5fff48 commit 637a9a0
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 41 deletions.
30 changes: 16 additions & 14 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
Package: piar
Title: Price Index Aggregation
Version: 0.5.0.9029
Version: 0.5.0.9030
Authors@R: c(
person("Steve", "Martin", role = c("aut", "cre", "cph"),
email = "[email protected]",
comment = c(ORCID = "0000-0003-2544-9480"))
)
Description: Most price indexes are made with a two-step procedure, where
period-over-period elemental indexes are first calculated for a
collection of elemental aggregates at each point in time, and
then aggregated according to a price index aggregation structure.
These indexes can then be chained together to form a time series
that gives the evolution of prices with respect to a fixed base
period. This package contains a collections of functions that
revolve around this work flow, making it easy to build standard
price indexes, and implement the methods described by
Balk (2008, ISBN:978-1-107-40496-0),
von der Lippe (2001, ISBN:3-8246-0638-0),
and the CPI manual (2020, ISBN:978-1-51354-298-0) for bilateral
price indexes.
period-over-period elemental indexes are first calculated for a collection
of elemental aggregates at each point in time, and then aggregated according
to a price index aggregation structure. These indexes can then be chained
together to form a time series that gives the evolution of prices with
respect to a fixed base period. This package contains a collections of
functions that revolve around this work flow, making it easy to build
standard price indexes, and implement the methods described by
Balk (2008, ISBN:978-1-107-40496-0), von der Lippe (2001,
ISBN:3-8246-0638-0), and the CPI manual (2020, ISBN:978-1-51354-298-0)
for bilateral price indexes.
Depends: R (>= 4.0)
Imports: stats, utils, gpindex (>= 0.5.0), Matrix (>= 1.5-0)
Imports:
stats,
utils,
gpindex (>= 0.5.0),
Matrix (>= 1.5-0)
Suggests:
rmarkdown,
knitr,
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export("weights<-")
export(aggregation_structure)
export(as_aggregation_structure)
export(as_index)
export(carry_backwards)
export(carry_forward)
export(chain)
export(contrib)
Expand Down
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

- The `[[` method for index objects has been removed as it created unexpected problems for little gain. `as.matrix(index)[[1, 1]]` is a more explicit and flexible way to get the same behavior as `index[[1, 1]]`.

- `aggregation_structure()` now orders the levels of an aggregation according to the order they appear in the data. Previously the levels were ordered lexicographically, except for the elemental aggregates.
- `aggregation_structure()` now orders the levels of an aggregation according to the order they appear in the data. Previously the levels were ordered lexicographically, except for the elemental aggregates. This can affect the order in which index values appear for an aggregate index.

There are a number of changes to the way product names are handled when making an index and extracting percent-change contributions.

Expand Down Expand Up @@ -32,6 +32,8 @@ There are a number of changes to the way product names are handled when making a

- The `as.matrix()` method for aggregation structures gains a new argument `sparse`. If `sparse = TRUE` then the aggregation matrix is a sparse, rather than dense, matrix. This option can also be used in the `vcov()` method for aggregate price indexes to improve performance for large indexes.

- Added the `carry_backwards()` function to do carry backwards (as opposed to carry forwards) imputation.

## Bug fixes

- Viewing index objects in the RStudio viewer longer gives an error.
Expand Down
5 changes: 3 additions & 2 deletions R/as_aggregation_structure.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
#' aggregates. The default is to give each elemental aggregate the same weight.
#' @param ... Further arguments passed to or used by methods.
#'
#' @returns A price index aggregation structure that inherits from
#' [`piar_aggregation_structure`]..
#' @returns
#' A price index aggregation structure that inherits from
#' [`piar_aggregation_structure`].
#'
#' @seealso
#' [`as.matrix()`][as.matrix.piar_aggregation_structure] and
Expand Down
6 changes: 3 additions & 3 deletions R/contrib.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
#'
#' @returns
#' A matrix of percent-change contributions with a column for each
#' `period` and a row for each product for which there are contributions
#' in `level`. Contributions are padded with 0 to fit into a rectangular
#' array when products differ over time.
#' `period` and a row for each product (sorted) for which there are
#' contributions in `level`. Contributions are padded with 0 to fit into a
#' rectangular array when products differ over time.
#'
#' @examples
#' prices <- data.frame(
Expand Down
25 changes: 16 additions & 9 deletions R/impute_prices.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
#' The carry forward method replaces a missing price for a product by the price
#' for the same product in the previous period. It tends to push an index value
#' towards 1, and is usually avoided; see paragraph 6.61 in the CPI manual
#' (2020).
#' (2020). The carry backwards method does the opposite, but this is rarely
#' used in practice.
#'
#' The shadow price method recursively imputes a missing price by the value of
#' the price for the same product in the previous period multiplied by the
Expand Down Expand Up @@ -40,13 +41,13 @@
#' imputes from elemental indexes only (i.e., not recursively).
#' @param weights A numeric vector of weights for the prices in `x` (i.e.,
#' product weights). The default is to give each price equal weight.
#' @param r1 Order of the price index used to calculate the elemental price
#' indexes: 0 for a geometric index (the default), 1 for an arithmetic index,
#' or -1 for a harmonic index. Other values are possible; see
#' @param r1 Order of the generalized-mean price index used to calculate the
#' elemental price indexes: 0 for a geometric index (the default), 1 for an
#' arithmetic index, or -1 for a harmonic index. Other values are possible; see
#' [gpindex::generalized_mean()] for details.
#' @param r2 Order of the price index used to aggregate the elemental price
#' indexes: 0 for a geometric index, 1 for an arithmetic index (the default),
#' or -1 for a harmonic index. Other values are possible; see
#' @param r2 Order of the generalized-mean price index used to aggregate the
#' elemental price indexes: 0 for a geometric index, 1 for an arithmetic index
#' (the default), or -1 for a harmonic index. Other values are possible; see
#' [gpindex::generalized_mean()] for details.
#'
#' @returns
Expand Down Expand Up @@ -109,8 +110,7 @@ shadow_price <- function(x, period, product, ea,
price <- res[[t]]
# calculate indexes
epr <- elemental_index(price / back_price,
ea = ea[[t]],
weights = w[[t]], na.rm = TRUE, r = r1
ea = ea[[t]], weights = w[[t]], na.rm = TRUE, r = r1
)
if (!is.null(pias)) {
epr <- aggregate(epr, pias, na.rm = TRUE, r = r2)
Expand Down Expand Up @@ -156,3 +156,10 @@ carry_forward <- function(x, period, product) {
attributes(res) <- attributes(x)
res
}

#' @rdname impute_prices
#' @export
carry_backwards <- function(x, period, product) {
period <- as.factor(period)
carry_forward(x, factor(period, rev(levels(period))), product)
}
2 changes: 1 addition & 1 deletion man/as_aggregation_structure.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions man/contrib.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 11 additions & 7 deletions man/impute_prices.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/Examples/piar-Ex.Rout.save
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ b 2.828427 6.928203
>
> ### Name: impute_prices
> ### Title: Impute missing prices
> ### Aliases: impute_prices shadow_price carry_forward
> ### Aliases: impute_prices shadow_price carry_forward carry_backwards
>
> ### ** Examples
>
Expand Down
7 changes: 7 additions & 0 deletions tests/testthat/test-impute-prices.R
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,10 @@ test_that("jumbling prices does nothing", {
sp[jumble]
)
})

test_that("carrying forward/backwards imputation works", {
expect_equal(carry_forward(c(NA, 1, 2, NA, 3), gl(5, 1), gl(1, 5)),
c(NA, 1, 2, 2, 3))
expect_equal(carry_backwards(c(NA, 1, 2, NA, 3), gl(5, 1), gl(1, 5)),
c(1, 1, 2, 3, 3))
})

0 comments on commit 637a9a0

Please sign in to comment.