Skip to content

Commit

Permalink
Added match_first argument
Browse files Browse the repository at this point in the history
  • Loading branch information
marberts committed Nov 12, 2023
1 parent 5110687 commit 5d2f66d
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 51 deletions.
21 changes: 17 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
Package: gpindex
Title: Generalized Price and Quantity Indexes
Version: 0.5.0.9008
Version: 0.5.0.9009
Authors@R: c(
person("Steve", "Martin", role = c("aut", "cre", "cph"), email = "[email protected]", comment = c(ORCID = "0000-0003-2544-9480"))
person("Steve", "Martin", role = c("aut", "cre", "cph"),
email = "[email protected]",
comment = c(ORCID = "0000-0003-2544-9480"))
)
Description: A small package for calculating lots of different price indexes, and by extension quantity indexes. Provides tools to build and work with any type of bilateral generalized-mean index (of which most price indexes are), along with a few important indexes that don't belong to the generalized-mean family (e.g., superlative quadratic-mean indexes, GEKS). Implements and extends many of the methods in 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.
Description: Tools to build and work with bilateral generalized-mean
price indexes (and by extension quantity indexes), and indexes composed of
generalized-mean indexes (e.g., superlative quadratic-mean indexes, GEKS).
Covers the core mathematical machinery for making bilateral price indexes,
computing price relatives, detecting outliers, and decomposing indexes,
with wrapper for all common (and many uncommon) index-number
formulas. Implements and extends many of the methods in
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).
Depends: R (>= 3.5)
Imports: stats
Suggests:
Expand All @@ -16,7 +27,9 @@ Encoding: UTF-8
URL: https://marberts.github.io/gpindex/, https://github.com/marberts/gpindex
BugReports: https://github.com/marberts/gpindex/issues
LazyData: true
Collate: 'helpers.R' 'means.R' 'weights.R' 'contributions.R' 'price_indexes.R' 'geks.R' 'operators.R' 'offset_prices.R' 'outliers.R' 'price_data.R' 'gpindex-package.R'
Collate: 'helpers.R' 'means.R' 'weights.R' 'contributions.R' 'price_indexes.R'
'geks.R' 'operators.R' 'offset_prices.R' 'outliers.R' 'price_data.R'
'gpindex-package.R'
Config/testthat/edition: 3
VignetteBuilder: knitr
Roxygen: list(markdown = TRUE)
Expand Down
56 changes: 41 additions & 15 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ anonymous function.

- Added the `walsh_geks()` function.

- `back_period()` and `base_period()` gain a new argument `match_first` to
control whether products in the first period match to themselves or return `NA`.

- Updated documentation.

- Added a vignette.
Expand All @@ -14,58 +17,81 @@ anonymous function.

- `back_price()` and `base_price()` have been removed.

- Functions for transforming weights only keep the attributes of the weights (if any), as documented.
- Functions for transforming weights only keep the attributes of the weights
(if any), as documented.

- `grouped()` no longer mangles names.

## Version 0.4.3

- `back_price()` and `base_price()` are deprecated in favor of the more general `back_period()` and `base_period()` functions. They will be removed in a future version.
- `back_price()` and `base_price()` are deprecated in favor of the more
general `back_period()` and `base_period()` functions. They will be removed in
a future version.

- The algorithm for making GEKS indexes is now much faster with a rolling window.

## Version 0.4.2

- The functions and overall structure of the package should be fairly stable from now on.
- The functions and overall structure of the package should be fairly stable
from now on.

- Added `nested_transmute()` and `nested_transmute2()` for transmuting the weights for nested generalized means. To be consistent with argument names, the first two arguments for `nested_mean()` and `nested_contributions*()` are now `r1` and `r2`.
- Added `nested_transmute()` and `nested_transmute2()` for transmuting the
weights for nested generalized means. To be consistent with argument names, the
first two arguments for `nested_mean()` and `nested_contributions*()` are
now `r1` and `r2`.

- Added the geometric Theil and Rao indexes.

## Version 0.3.9

- Added `back_period()` and `base_period()`, which are more general than `back_price()` and `base_price()`.
- Added `back_period()` and `base_period()`, which are more general
than `back_price()` and `base_price()`.

- Added `lehr_index()`.

- Fixed a rare warning about `sqrt()` making NaNs in `generalized_logmean(-1)` when some inputs were close but not equal, despite no NaNs showing in the result.
- Fixed a rare warning about `sqrt()` making NaNs in
`generalized_logmean(-1)` when some inputs were close but not equal, despite
no `NaN`s showing in the result.

- The `lm_index()` and `*_agmean_index()` functions are now function factories.

## Version 0.3.6

- Added the `balanced()` operator to make it easier to remove NAs with price index functions.
- Added the `balanced()` operator to make it easier to remove NAs with price
index functions.

- Added the `geks()` function for using price-index function (e.g., `fisher_index()`) to makes a GEKS index.
- Added the `geks()` function for using price-index function
(e.g., `fisher_index()`) to makes a GEKS index.

## Version 0.3.4

- Added French translations.

- Made a number of optimizations to make the results of `generalized_mean()`, `extended_mean()`, `lehmer_mean()`, `transmute_weights()`, and `factor_weights()` faster in common cases.
- Made a number of optimizations to make the results
of `generalized_mean()`, `extended_mean()`, `lehmer_mean()`,
`transmute_weights()`, and `factor_weights()` faster in common cases.

- Added the `grouped()` operator to make all functions work with grouped data.

## Version 0.3.1

- Most function names have changed to be less awkward; e.g., `mean_generalized()` is now `generalized_mean()`, and `contributions_geometric()` is now `geometric_contributions()`. This is unfortunately not backwards compatible, but needed to be done.
- Most function names have changed to be less awkward;
e.g., `mean_generalized()` is now `generalized_mean()`,
and `contributions_geometric()` is now `geometric_contributions()`. This is
unfortunately not backwards compatible, but needed to be done.

- Added the `nested_mean()` function to calculate nested generalized means for, e.g., the Fisher index.
- Added the `nested_mean()` function to calculate nested generalized means
for, e.g., the Fisher index.

- The interface for `nested_contributions()` is now much simpler, and the function is focused on making contributions for Fisher indexes. Added the `nested_contributions2()` function that implements a different algorithm.
- The interface for `nested_contributions()` is now much simpler, and the
function is focused on making contributions for Fisher indexes. Added
the `nested_contributions2()` function that implements a different algorithm.

- Added the `arithmetic_agmean_index()` and `geometric_agmean_index()` functions to calculate the AG mean index.
- Added the `arithmetic_agmean_index()` and `geometric_agmean_index()` functions
to calculate the AG mean index.

- Added some functions for standard outlier-detection methods for price relatives.
- Added some functions for standard outlier-detection methods for price
relatives.

- Dropped the `scale` argument for `generalized_mean()`, as it really wasn't needed and had the potential to make more problems than it solved.
- Dropped the `scale` argument for `generalized_mean()`, as it really wasn't
needed and had the potential to make more problems than it solved.
31 changes: 20 additions & 11 deletions R/offset_prices.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
offset_period <- function(f) {
f <- match.fun(f)

function(period, product = gl(1, length(period))) {
function(period, product = gl(1, length(period)), match_first = TRUE) {
if (length(period) != length(product)) {
stop("'period' and 'product' must be the same length")
}
Expand All @@ -19,6 +19,9 @@ offset_period <- function(f) {
warning("there are duplicated period-product pairs")
}
m <- .mapply(match, list(product, f(product)), list(incomparables = NA))
if (!match_first) {
m[[1L]][] <- NA
}
res <- split(seq_along(period), period)
unsplit(.mapply(`[`, list(f(res), m), list()), period)
}
Expand All @@ -37,16 +40,22 @@ offset_period <- function(f) {
#' @param product A factor, or something that can be coerced into one, that
#' gives the product identifier for each transaction. The default is to assume
#' that all transactions are for the same product.
#' @return `back_period()` and `base_period()` return a numeric
#' vector of indices for the back/base periods. With `back_period()`, for
#' all periods after the first, the resulting vector gives the location of the
#' corresponding product in the previous period. The locations are unchanged
#' for the first time period. With `base_period()`, the resulting vector
#' gives the location of the corresponding product in the first period.
#' @note By definition, there must be at most one transaction for each product
#' in each time period to determine a back period. If multiple transactions
#' correspond to a period-product pair, then the back period at a point in time
#' is always the first position for that product in the previous period.
#' @param match_first Should products in the first period match with
#' themselves (the default)?
#'
#' @returns
#' Both functions return a numeric vector of indices for the back/base periods.
#' With `back_period()`, for all periods after the first, the resulting vector
#' gives the location of the corresponding product in the previous period.
#' With `base_period()`, the resulting vector gives the location of the
#' corresponding product in the first period. The locations are unchanged for
#' he first time period if `match_first = TRUE`, `NA` otherwise.
#'
#' @note
#' By definition, there must be at most one transaction for each product
#' in each time period to determine a back/base period. If multiple transactions
#' correspond to a period-product pair, then the back/base period at a point in
#' time is always the first position for that product in the previous period.
#'
#' @seealso
#' [outliers] for common methods to detect outliers for price relatives.
Expand Down
2 changes: 1 addition & 1 deletion README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ knitr::opts_chunk$set(
[![codecov](https://codecov.io/gh/marberts/gpindex/branch/master/graph/badge.svg?token=lHDHsGHsLd)](https://app.codecov.io/gh/marberts/gpindex)
[![DOI](https://zenodo.org/badge/261861375.svg)](https://zenodo.org/doi/10.5281/zenodo.10097742)

A small package for calculating lots of different price indexes, and by extension quantity indexes. Provides tools to build and work with any type of bilateral generalized-mean index (of which most price indexes are), along with a few important indexes that don't belong to the generalized-mean family (e.g., superlative quadratic-mean indexes, GEKS). Implements and extends many of the methods in Balk (2008), von der Lippe (2001), and the CPI manual (2020) for bilateral price indexes.
Tools to build and work with bilateral generalized-mean price indexes (and by extension quantity indexes), and indexes composed of generalized-mean indexes (e.g., superlative quadratic-mean indexes, GEKS). Covers the core mathematical machinery for making bilateral price indexes, computing price relatives, detecting outliers, and decomposing indexes, with wrapper for all common (and many uncommon) index-number formulas. Implements and extends many of the methods in Balk (2008), von der Lippe (2001), and the CPI manual (2020).

## Installation

Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ badge](https://marberts.r-universe.dev/badges/gpindex)](https://marberts.r-unive
[![codecov](https://codecov.io/gh/marberts/gpindex/branch/master/graph/badge.svg?token=lHDHsGHsLd)](https://app.codecov.io/gh/marberts/gpindex)
[![DOI](https://zenodo.org/badge/261861375.svg)](https://zenodo.org/doi/10.5281/zenodo.10097742)

A small package for calculating lots of different price indexes, and by
extension quantity indexes. Provides tools to build and work with any
type of bilateral generalized-mean index (of which most price indexes
are), along with a few important indexes that don’t belong to the
generalized-mean family (e.g., superlative quadratic-mean indexes,
GEKS). Implements and extends many of the methods in Balk (2008), von
der Lippe (2001), and the CPI manual (2020) for bilateral price indexes.
Tools to build and work with bilateral generalized-mean price indexes
(and by extension quantity indexes), and indexes composed of
generalized-mean indexes (e.g., superlative quadratic-mean indexes,
GEKS). Covers the core mathematical machinery for making bilateral price
indexes, computing price relatives, detecting outliers, and decomposing
indexes, with wrapper for all common (and many uncommon) index-number
formulas. Implements and extends many of the methods in Balk (2008), von
der Lippe (2001), and the CPI manual (2020).

## Installation

Expand Down
25 changes: 14 additions & 11 deletions man/back_period.Rd

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

2 changes: 1 addition & 1 deletion man/gpindex-package.Rd

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

9 changes: 8 additions & 1 deletion tests/testthat/test-offset-prices.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ test_that("offsetting periods works", {
c(NA, NA, 3L, 4L, 5L, 5L, 4L, 3L, NA, NA))
})

test_that("ambiguous products trigger a wanring", {
test_that("not matching the first period works", {
expect_identical(back_period(period, id, FALSE),
c(rep(NA, 5), 5:1))
expect_identical(base_period(period, id, FALSE),
c(rep(NA, 5), 5:1))
})

test_that("ambiguous products trigger a warning", {
expect_warning(base_period(c(1, 1, 2, 3)))
})

Expand Down

0 comments on commit 5d2f66d

Please sign in to comment.