
Change Over Time
Calculating change over
time with percent_change()
and
annualize_change()
from {econanalyzr}
Source: vignettes/calc-change-over-time.Rmd
calc-change-over-time.Rmd
Introduction
This vignette demonstrates how to compute change over time with two core functions:
-
percent_change(start_value, end_value)
: computes the simple relative change. -
annualize_change(start_values, end_values, time_elapsed, time_unit, year_length = 365.2425)
: converts growth over a period to an annualized rate.
A small monthly time series to illustrate computations:
set.seed(42)
df <- tibble::tibble(
date = seq(as.Date("2025-01-01"), by = "month", length.out = 12),
value = round(100 * cumprod(1 + rnorm(12, mean = 0.01, sd = 0.01)), 2)
)
df
#> # A tibble: 12 × 2
#> date value
#> <date> <dbl>
#> 1 2025-01-01 102.
#> 2 2025-02-01 103.
#> 3 2025-03-01 104.
#> 4 2025-04-01 106.
#> 5 2025-05-01 107.
#> 6 2025-06-01 108.
#> 7 2025-07-01 111.
#> 8 2025-08-01 112.
#> 9 2025-09-01 115.
#> 10 2025-10-01 117.
#> # ℹ 2 more rows
Percent Change
percent_change()
expects starting and ending
values. A natural workflow is using [dplyr::lag()] to use different
values in the same vector in a vectorized manner:
df_pct <- df |>
arrange(date) |>
mutate(
# vectorized, preserves NA on first row
pct_mom = percent_change(lag(value), value)
)
#> Warning: There was 1 warning in `mutate()`.
#> ℹ In argument: `pct_mom = percent_change(lag(value), value)`.
#> Caused by warning:
#> ! NA values detected; returning NA for those positions.
df_pct |> select(date, value, pct_mom)
#> # A tibble: 12 × 3
#> date value pct_mom
#> <date> <dbl> <dbl>
#> 1 2025-01-01 102. NA
#> 2 2025-02-01 103. 0.00440
#> 3 2025-03-01 104. 0.0136
#> 4 2025-04-01 106. 0.0163
#> 5 2025-05-01 107. 0.0141
#> 6 2025-06-01 108. 0.00894
#> 7 2025-07-01 111. 0.0251
#> 8 2025-08-01 112. 0.00900
#> 9 2025-09-01 115. 0.0302
#> 10 2025-10-01 117. 0.00935
#> # ℹ 2 more rows
Annualized Change
The annualize_change()
function is versatile enough to
be able to calculate the annualized change for differing time
units (e.g. monthly, weekly, daily) as well as periods
of those units. This also plays nicely with [dplyr::lag()]:
Annualized rates from 1-month and 3-month intervals.
df_ann <- df |>
arrange(date) |>
mutate(
ann_1m = annualize_change(
lag(value),
value,
time_elapsed = 1,
time_unit = "monthly"
),
ann_3m = annualize_change(
lag(value, 3),
value,
time_elapsed = 3,
time_unit = "monthly"
)
)
df_ann |> select(date, value, ann_1m, ann_3m)
#> # A tibble: 12 × 4
#> date value ann_1m ann_3m
#> <date> <dbl> <dbl> <dbl>
#> 1 2025-01-01 102. NA NA
#> 2 2025-02-01 103. 0.0540 NA
#> 3 2025-03-01 104. 0.176 NA
#> 4 2025-04-01 106. 0.214 0.146
#> 5 2025-05-01 107. 0.182 0.191
#> 6 2025-06-01 108. 0.113 0.169
#> 7 2025-07-01 111. 0.346 0.210
#> 8 2025-08-01 112. 0.114 0.186
#> 9 2025-09-01 115. 0.430 0.289
#> 10 2025-10-01 117. 0.118 0.212
#> # ℹ 2 more rows