Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@
^CRAN-SUBMISSION$
^revdep$
^CITATION\.cff$
^[.]?air[.]toml$
^\.vscode$
^CONTRIBUTING\.md$
33 changes: 33 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main, master]
pull_request:

name: lint.yaml

permissions: read-all

jobs:
lint:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::lintr, local::.
needs: lint

- name: Lint
run: lintr::lint_package()
shell: Rscript {0}
env:
LINTR_ERROR_ON_LINT: true
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
*.Rproj
inst/doc
docs
revdep
revdep
/.quarto/
2 changes: 1 addition & 1 deletion .lintr
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
linters: linters_with_defaults(
object_name_linter = object_name_linter(styles = c("snake_case", "symbols", "dotted.case"))
object_name_linter = object_name_linter(styles = c("snake_case", "symbols", "dotted.case", "CamelCase"))
)
5 changes: 5 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"Posit.air-vscode"
]
}
10 changes: 10 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"[r]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "Posit.air-vscode"
},
"[quarto]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "quarto.quarto"
}
}
45 changes: 45 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Contributing

Contributions to `gpindex` are welcome and appreciated. Here are some ways that you
can contribute.

## Reporting bugs

Open an issue with a small reproducible example of the bug. Feel free to
include a PR with a patch.

## Improving documentation

### Typos and corrections

You can fix typos, spelling mistakes, and make other small corrections to
the documentation by editing
the `roxygen2` comments in the corresponding `.R` (not `.Rd`) file.

### Adding documentation

Please open an issue if you feel that any of the
documentation is unclear or if certain functions don't have enough documentation.

## Suggestions for improvement

Open an issue if you have any suggestions for improvements (e.g., feature requests).

## Seeking support

Open an issue (or send me an email) if you're stuck and not able to find an
answer in the documentation. (It may be a bug or problem with the documentation.)

## Making a pull request

When making a pull request, please:

1. Fork the repository on github and make a new branch in your forked copy;

2. Follow the [tidyverse style guide](https://style.tidyverse.org/);

3. Use `roxygen2` for documentation;

4. Use `testthat` for unit tests;

5. Ensure your changes pass `R CMD check`.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: gpindex
Title: Generalized Price and Quantity Indexes
Version: 0.6.3
Version: 0.6.3.9001
Authors@R: c(
person("Steve", "Martin", role = c("aut", "cre", "cph"),
email = "marberts@protonmail.com",
Expand Down
30 changes: 21 additions & 9 deletions R/geks.R
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,16 @@
geks <- function(f, r = 0) {
f <- match.fun(f)
gen_mean <- generalized_mean(r)
function(p,
q,
period,
product,
window = nlevels(period),
n = window - 1L,
na.rm = FALSE,
match_method = c("all", "back-price")) {
function(
p,
q,
period,
product,
window = nlevels(period),
n = window - 1L,
na.rm = FALSE,
match_method = c("all", "back-price")
) {
period <- as.factor(period)
product <- as.factor(product)
attributes(product) <- NULL # faster to match on numeric codes
Expand Down Expand Up @@ -177,7 +179,17 @@ geks <- function(f, r = 0) {

#' Make the GEKS matrix
#' @noRd
geks_matrix <- function(index, p, q, period, product, window, n, na.rm, method) {
geks_matrix <- function(
index,
p,
q,
period,
product,
window,
n,
na.rm,
method
) {
p <- split(p, period)
q <- split(q, period)

Expand Down
12 changes: 8 additions & 4 deletions R/operators.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@
quantity_index <- function(f) {
f <- match.fun(f)
concord <- c(
p1 = "q1", p0 = "q0",
q1 = "p1", q0 = "p0",
pb = "qb", qb = "pb",
p = "q", q = "p"
p1 = "q1",
p0 = "q0",
q1 = "p1",
q0 = "p0",
pb = "qb",
qb = "pb",
p = "q",
q = "p"
)

function(...) {
Expand Down
6 changes: 4 additions & 2 deletions R/outliers.R
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,16 @@
#'
#' @references
#' Hutton, H. (2008). Dynamic outlier detection in price index surveys.
#' *Proceedings of the Survey Methods Section: Statistical Society of Canada Annual Meeting*.
#' *Proceedings of the Survey Methods Section: Statistical Society of Canada
#' Annual Meeting*.
#'
#' IMF, ILO, Eurostat, UNECE, OECD, and World Bank. (2020).
#' *Consumer Price Index Manual: Concepts and Methods*.
#' International Monetary Fund.
#'
#' Rais, S. (2008). Outlier detection for the Consumer Price Index.
#' *Proceedings of the Survey Methods Section: Statistical Society of Canada Annual Meeting*.
#' *Proceedings of the Survey Methods Section: Statistical Society of Canada
#' Annual Meeting*.
#'
#' @examples
#' set.seed(1234)
Expand Down
6 changes: 4 additions & 2 deletions R/price_data.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@
#' palgrave = arithmetic_index("Palgrave")(p1, p0, q1),
#' fisher = fisher_index(p1, p0, q1, q0),
#' tornqvist = geometric_index("Tornqvist")(p1, p0, q1, q0),
#' marshall_edgeworth = arithmetic_index("MarshallEdgeworth")(p1, p0, q1, q0),
#' marshall_edgeworth =
#' arithmetic_index("MarshallEdgeworth")(p1, p0, q1, q0),
#' walsh1 = arithmetic_index("Walsh1")(p1, p0, q1, q0),
#' vartia2 = geometric_index("Vartia2")(p1, p0, q1, q0),
#' vartia1 = geometric_index("Vartia1")(p1, p0, q1, q0),
#' stuvel = stuvel_index(2, 2)(p1, p0, q1, q0)
#' )
#' }
#'
#' round(t(mapply(index_formulas, price6, price6[1], quantity6, quantity6[1])), 4)
#' res <- t(mapply(index_formulas, price6, price6[1], quantity6, quantity6[1]))
#' round(res, 4)
#'
NULL
94 changes: 68 additions & 26 deletions R/price_indexes.R
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
#' Factory to make Pythagorean indexes
#' @noRd
pythagorean_index <- function(r) {
types <- switch(r + 2,
types <- switch(
r + 2,
c("Coggeshall", "Laspeyres", "Paasche", "Young"),
c(
"Jevons", "Laspeyres", "Paasche",
"Tornqvist", "Vartia1", "MontgomeryVartia",
"Vartia2", "SatoVartia", "Walsh2",
"Young", "Theil", "Rao"
"Jevons",
"Laspeyres",
"Paasche",
"Tornqvist",
"Vartia1",
"MontgomeryVartia",
"Vartia2",
"SatoVartia",
"Walsh2",
"Young",
"Theil",
"Rao"
),
c(
"Carli", "Dutot", "Laspeyres",
"Palgrave", "Drobisch", "Unnamed",
"Walsh1", "MarshallEdgeworth", "GearyKhamis",
"Lowe", "Young", "HybridCSWD"
"Carli",
"Dutot",
"Laspeyres",
"Palgrave",
"Drobisch",
"Unnamed",
"Walsh1",
"MarshallEdgeworth",
"GearyKhamis",
"Lowe",
"Young",
"HybridCSWD"
)
)
gen_mean <- generalized_mean(r)
Expand All @@ -22,7 +39,8 @@ pythagorean_index <- function(r) {
type <- match.arg(type, types)
weights <- index_weights(type)

switch(type,
switch(
type,
Carli = ,
Dutot = ,
Jevons = ,
Expand Down Expand Up @@ -260,17 +278,37 @@ pythagorean_index <- function(r) {
#' @family price index functions
#' @export
index_weights <- function(
type = c(
"Carli", "Jevons", "Coggeshall", "Dutot",
"Laspeyres", "HybridLaspeyres", "LloydMoulton",
"Palgrave", "Paasche", "HybridPaasche",
"Drobisch", "Unnamed", "Tornqvist",
"Walsh1", "Walsh2", "MarshallEdgeworth",
"GearyKhamis", "Vartia1", "MontgomeryVartia",
"Vartia2", "SatoVartia", "Theil", "Rao",
"Lowe", "Young", "HybridCSWD"
)) {
switch(match.arg(type),
type = c(
"Carli",
"Jevons",
"Coggeshall",
"Dutot",
"Laspeyres",
"HybridLaspeyres",
"LloydMoulton",
"Palgrave",
"Paasche",
"HybridPaasche",
"Drobisch",
"Unnamed",
"Tornqvist",
"Walsh1",
"Walsh2",
"MarshallEdgeworth",
"GearyKhamis",
"Vartia1",
"MontgomeryVartia",
"Vartia2",
"SatoVartia",
"Theil",
"Rao",
"Lowe",
"Young",
"HybridCSWD"
)
) {
switch(
match.arg(type),
Carli = ,
Jevons = ,
Coggeshall = function(p0) {
Expand Down Expand Up @@ -632,9 +670,11 @@ cswd_index <- function(p1, p0, na.rm = FALSE) {
#' @export
cswdb_index <- function(p1, p0, q1, q0, na.rm = FALSE) {
check_pqs(p1, p0, q1, q0)
sqrt(arithmetic_mean(p1 / p0, na.rm = na.rm) /
arithmetic_mean(q1 / q0, na.rm = na.rm) *
arithmetic_mean(p1 * q1 / (p0 * q0), na.rm = na.rm))
sqrt(
arithmetic_mean(p1 / p0, na.rm = na.rm) /
arithmetic_mean(q1 / q0, na.rm = na.rm) *
arithmetic_mean(p1 * q1 / (p0 * q0), na.rm = na.rm)
)
}

#' Balk Walsh index
Expand Down Expand Up @@ -703,8 +743,10 @@ lehr_index <- function(p1, p0, q1, q0, na.rm = FALSE) {
v1 <- p1 * q1
v0 <- p0 * q0
v <- (v1 + v0) / (q1 + q0)
sum(v1, na.rm = na.rm) / sum(v0, na.rm = na.rm) *
sum(v * q0, na.rm = na.rm) / sum(v * q1, na.rm = na.rm)
sum(v1, na.rm = na.rm) /
sum(v0, na.rm = na.rm) *
sum(v * q0, na.rm = na.rm) /
sum(v * q1, na.rm = na.rm)
}

#' Martini index
Expand Down
3 changes: 2 additions & 1 deletion R/weights.R
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ extended_mean_ <- function(r, s) {
#' `nested_transmute()` and `nested_transmute2()` similarly return a
#' function:
#'
#' \preformatted{function(x, w1 = NULL, w2 = NULL, tol = .Machine$double.eps^0.5){...}}
#' \preformatted{function(x, w1 = NULL, w2 = NULL,
#' tol = .Machine$double.eps^0.5){...}}
#'
#' @seealso
#' [generalized_mean()] for the generalized mean and [nested_mean()] for the
Expand Down
9 changes: 8 additions & 1 deletion README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ install.packages("gpindex")
The development version can be installed from R-Universe

```{r, eval = FALSE}
install.packages("gpindex", repos = c("https://marberts.r-universe.dev", "https://cloud.r-project.org"))
install.packages(
"gpindex",
repos = c("https://marberts.r-universe.dev", "https://cloud.r-project.org")
)
```

or directly from GitHub.
Expand Down Expand Up @@ -113,6 +116,10 @@ quadratic_contributions(p2 / p1, s1)

There are a number of R packages on the CRAN that implement the standard index-number formulas (e.g., **IndexNumber**, **productivity**, **IndexNumR**, **micEconIndex**, **PriceIndices**). While there is support for a large number of index-number formulas out-of-the box in this package, the focus is on the tools to easily make and work with any type of generalized-mean price index. Consequently, compared to existing packages, this package is suitable for building custom price/quantity indexes, calculating indexes with sample data, decomposing indexes, and learning about or researching different types of index-number formulas.

## Contributing

All contributions are welcome. Please start by opening an issue on GitHub to report any bugs or suggest improvements and new features. See the contribution guidelines for this project for more information.

## References

Balk, B. M. (2008). *Price and Quantity Index Numbers*. Cambridge University Press.
Expand Down
Loading