Author

AS

Published

September 29, 2025

1 What is fpp3?

fpp3 is a meta-package that loads essential time series forecasting tools:

Code
remove(list=ls())

library(fpp3)

Loading fpp3 gives you:

  • tsibble → tidy time series data structures (required format)
  • fable → forecasting models (ETS, ARIMA, etc.)
  • feasts → feature extraction and statistics (ACF, STL decomposition, etc.)

All fpp3 packages require data to be in tsibble format.

2 Tssible

A tsibble is a tidy temporal data frame used in the fpp3 framework. It extends tibble with two essential attributes:

  1. Index → the time variable (Year, Month, Quarter, etc.)
  2. Key → the identifier(s) that distinguish multiple time series (Country, State, Industry, etc.)

Together, index × key uniquely define each observation in a tsibble.

2.1 Long vs Wide Format

Time series should be stored in long (tidy) format, not wide.

2.1.1 Wide Format (not tsibble-friendly)

Each country in its own column:

Year Australia US Japan
2000 400 9500 5000
2001 420 9700 5200

This makes it hard to work with multiple series.

2.1.2 Long Format (tsibble-friendly)

All countries in one column, with Country as the key:

Year Country GDP
2000 Australia 400
2000 US 9500
2000 Japan 5000
2001 Australia 420
2001 US 9700
2001 Japan 5200

This structure is tidy and allows modeling all series in parallel.

2.2 Declaring Keys

2.2.1 Single Key Example

Code
# GDP by country
gdp_ts <- global_economy |>
  select(Country, Year, GDP) |>
  as_tsibble(key = Country, index = Year)

gdp_ts
# A tsibble: 15,150 x 3 [1Y]
# Key:       Country [263]
   Country      Year         GDP
   <fct>       <dbl>       <dbl>
 1 Afghanistan  1960  537777811.
 2 Afghanistan  1961  548888896.
 3 Afghanistan  1962  546666678.
 4 Afghanistan  1963  751111191.
 5 Afghanistan  1964  800000044.
 6 Afghanistan  1965 1006666638.
 7 Afghanistan  1966 1399999967.
 8 Afghanistan  1967 1673333418.
 9 Afghanistan  1968 1373333367.
10 Afghanistan  1969 1408888922.
# ℹ 15,140 more rows
  • Index = Year
  • Key = Country
  • One series per country

2.2.2 Multiple Keys Example

Code
# Retail turnover by State and Industry
retail_ts <- aus_retail |>
  as_tsibble(key = c(State, Industry), index = Month)

retail_ts
# A tsibble: 64,532 x 5 [1M]
# Key:       State, Industry [152]
   State                        Industry           `Series ID`    Month Turnover
   <chr>                        <chr>              <chr>          <mth>    <dbl>
 1 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Apr      4.4
 2 Australian Capital Territory Cafes, restaurant… A3349849A   1982 May      3.4
 3 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Jun      3.6
 4 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Jul      4  
 5 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Aug      3.6
 6 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Sep      4.2
 7 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Oct      4.8
 8 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Nov      5.4
 9 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Dec      6.9
10 Australian Capital Territory Cafes, restaurant… A3349849A   1983 Jan      3.8
# ℹ 64,522 more rows
  • Index = Month
  • Key = (State, Industry)
  • Multiple series (one per state–industry pair)

2.3 Key Declaration Issues

If you don’t specify the key correctly, you may run into:

  • Duplicate rows per index-key → Error: “Keys are not unique”
  • Missing key → Data collapses into a single series

2.3.1 Example: Wrong Declaration (Missing Key)

Code
# Forgetting Industry as a key
retail_wrong <- aus_retail |>
  as_tsibble(key = State, index = Month)
Error in `validate_tsibble()`:
! A valid tsibble must have distinct rows identified by key and index.
ℹ Please use `duplicates()` to check the duplicated rows.
  • This throws an error because within each State, multiple industries share the same Month.

2.4 Why Keys Matter

Keys are essential for several reasons:

  • Keys identify which series is being modeled
  • Forecasting functions in fable automatically fit models per key
  • Keys make it easy to group, summarise, and forecast across many series

3 feasts Package

feasts = “Feature Extraction And Statistics for Time Series”

This package provides tools to:

  • Calculate time series features (trend strength, seasonality strength, etc.)
  • Generate diagnostic plots (ACF, PACF, seasonal plots)
  • Perform decomposition (STL, classical)
  • Compute summary statistics for time series
Code
# Calculate STL features for tourism data
tourism %>%
  features(Trips, feat_stl)
# A tibble: 304 × 12
   Region State Purpose trend_strength seasonal_strength_year seasonal_peak_year
   <chr>  <chr> <chr>            <dbl>                  <dbl>              <dbl>
 1 Adela… Sout… Busine…          0.464                  0.407                  3
 2 Adela… Sout… Holiday          0.554                  0.619                  1
 3 Adela… Sout… Other            0.746                  0.202                  2
 4 Adela… Sout… Visiti…          0.435                  0.452                  1
 5 Adela… Sout… Busine…          0.464                  0.179                  3
 6 Adela… Sout… Holiday          0.528                  0.296                  2
 7 Adela… Sout… Other            0.593                  0.404                  2
 8 Adela… Sout… Visiti…          0.488                  0.254                  0
 9 Alice… Nort… Busine…          0.534                  0.251                  0
10 Alice… Nort… Holiday          0.381                  0.832                  3
# ℹ 294 more rows
# ℹ 6 more variables: seasonal_trough_year <dbl>, spikiness <dbl>,
#   linearity <dbl>, curvature <dbl>, stl_e_acf1 <dbl>, stl_e_acf10 <dbl>

4 fable Package

fable = “Forecasting models for tidy time series”

This package provides:

  • Multiple forecasting models (ETS, ARIMA, SNAIVE, etc.)
  • Model fitting with model() function
  • Forecast generation with forecast() function
  • Model evaluation and comparison tools
Code
?model
?fpp3

str(us_employment)
tbl_ts [143,412 × 4] (S3: tbl_ts/tbl_df/tbl/data.frame)
 $ Month    : mth [1:143412] 1939 Jan, 1939 Feb, 1939 Mar, 1939 Apr, 1939 May, 1939 ...
 $ Series_ID: chr [1:143412] "CEU0500000001" "CEU0500000001" "CEU0500000001" "CEU0500000001" ...
 $ Title    : chr [1:143412] "Total Private" "Total Private" "Total Private" "Total Private" ...
 $ Employed : num [1:143412] 25338 25447 25833 25801 26113 ...
 - attr(*, "key")= tibble [148 × 2] (S3: tbl_df/tbl/data.frame)
  ..$ Series_ID: chr [1:148] "CEU0500000001" "CEU0600000001" "CEU0800000001" "CEU1000000001" ...
  ..$ .rows    : list<int> [1:148] 
  .. ..$ : int [1:969] 1 2 3 4 5 6 7 8 9 10 ...
  .. ..$ : int [1:969] 970 971 972 973 974 975 976 977 978 979 ...
  .. ..$ : int [1:969] 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 ...
  .. ..$ : int [1:969] 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 ...
  .. ..$ : int [1:969] 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 ...
  .. ..$ : int [1:969] 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 ...
  .. ..$ : int [1:969] 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 ...
  .. ..$ : int [1:969] 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 ...
  .. ..$ : int [1:969] 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 ...
  .. ..$ : int [1:969] 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 ...
  .. ..$ : int [1:969] 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 ...
  .. ..$ : int [1:969] 10660 10661 10662 10663 10664 10665 10666 10667 10668 10669 ...
  .. ..$ : int [1:969] 11629 11630 11631 11632 11633 11634 11635 11636 11637 11638 ...
  .. ..$ : int [1:969] 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 ...
  .. ..$ : int [1:969] 13567 13568 13569 13570 13571 13572 13573 13574 13575 13576 ...
  .. ..$ : int [1:969] 14536 14537 14538 14539 14540 14541 14542 14543 14544 14545 ...
  .. ..$ : int [1:969] 15505 15506 15507 15508 15509 15510 15511 15512 15513 15514 ...
  .. ..$ : int [1:969] 16474 16475 16476 16477 16478 16479 16480 16481 16482 16483 ...
  .. ..$ : int [1:969] 17443 17444 17445 17446 17447 17448 17449 17450 17451 17452 ...
  .. ..$ : int [1:969] 18412 18413 18414 18415 18416 18417 18418 18419 18420 18421 ...
  .. ..$ : int [1:969] 19381 19382 19383 19384 19385 19386 19387 19388 19389 19390 ...
  .. ..$ : int [1:969] 20350 20351 20352 20353 20354 20355 20356 20357 20358 20359 ...
  .. ..$ : int [1:969] 21319 21320 21321 21322 21323 21324 21325 21326 21327 21328 ...
  .. ..$ : int [1:969] 22288 22289 22290 22291 22292 22293 22294 22295 22296 22297 ...
  .. ..$ : int [1:969] 23257 23258 23259 23260 23261 23262 23263 23264 23265 23266 ...
  .. ..$ : int [1:969] 24226 24227 24228 24229 24230 24231 24232 24233 24234 24235 ...
  .. ..$ : int [1:969] 25195 25196 25197 25198 25199 25200 25201 25202 25203 25204 ...
  .. ..$ : int [1:969] 26164 26165 26166 26167 26168 26169 26170 26171 26172 26173 ...
  .. ..$ : int [1:969] 27133 27134 27135 27136 27137 27138 27139 27140 27141 27142 ...
  .. ..$ : int [1:969] 28102 28103 28104 28105 28106 28107 28108 28109 28110 28111 ...
  .. ..$ : int [1:969] 29071 29072 29073 29074 29075 29076 29077 29078 29079 29080 ...
  .. ..$ : int [1:969] 30040 30041 30042 30043 30044 30045 30046 30047 30048 30049 ...
  .. ..$ : int [1:969] 31009 31010 31011 31012 31013 31014 31015 31016 31017 31018 ...
  .. ..$ : int [1:969] 31978 31979 31980 31981 31982 31983 31984 31985 31986 31987 ...
  .. ..$ : int [1:969] 32947 32948 32949 32950 32951 32952 32953 32954 32955 32956 ...
  .. ..$ : int [1:969] 33916 33917 33918 33919 33920 33921 33922 33923 33924 33925 ...
  .. ..$ : int [1:969] 34885 34886 34887 34888 34889 34890 34891 34892 34893 34894 ...
  .. ..$ : int [1:969] 35854 35855 35856 35857 35858 35859 35860 35861 35862 35863 ...
  .. ..$ : int [1:969] 36823 36824 36825 36826 36827 36828 36829 36830 36831 36832 ...
  .. ..$ : int [1:969] 37792 37793 37794 37795 37796 37797 37798 37799 37800 37801 ...
  .. ..$ : int [1:969] 38761 38762 38763 38764 38765 38766 38767 38768 38769 38770 ...
  .. ..$ : int [1:969] 39730 39731 39732 39733 39734 39735 39736 39737 39738 39739 ...
  .. ..$ : int [1:969] 40699 40700 40701 40702 40703 40704 40705 40706 40707 40708 ...
  .. ..$ : int [1:969] 41668 41669 41670 41671 41672 41673 41674 41675 41676 41677 ...
  .. ..$ : int [1:969] 42637 42638 42639 42640 42641 42642 42643 42644 42645 42646 ...
  .. ..$ : int [1:969] 43606 43607 43608 43609 43610 43611 43612 43613 43614 43615 ...
  .. ..$ : int [1:969] 44575 44576 44577 44578 44579 44580 44581 44582 44583 44584 ...
  .. ..$ : int [1:969] 45544 45545 45546 45547 45548 45549 45550 45551 45552 45553 ...
  .. ..$ : int [1:969] 46513 46514 46515 46516 46517 46518 46519 46520 46521 46522 ...
  .. ..$ : int [1:969] 47482 47483 47484 47485 47486 47487 47488 47489 47490 47491 ...
  .. ..$ : int [1:969] 48451 48452 48453 48454 48455 48456 48457 48458 48459 48460 ...
  .. ..$ : int [1:969] 49420 49421 49422 49423 49424 49425 49426 49427 49428 49429 ...
  .. ..$ : int [1:969] 50389 50390 50391 50392 50393 50394 50395 50396 50397 50398 ...
  .. ..$ : int [1:969] 51358 51359 51360 51361 51362 51363 51364 51365 51366 51367 ...
  .. ..$ : int [1:969] 52327 52328 52329 52330 52331 52332 52333 52334 52335 52336 ...
  .. ..$ : int [1:969] 53296 53297 53298 53299 53300 53301 53302 53303 53304 53305 ...
  .. ..$ : int [1:969] 54265 54266 54267 54268 54269 54270 54271 54272 54273 54274 ...
  .. ..$ : int [1:969] 55234 55235 55236 55237 55238 55239 55240 55241 55242 55243 ...
  .. ..$ : int [1:969] 56203 56204 56205 56206 56207 56208 56209 56210 56211 56212 ...
  .. ..$ : int [1:969] 57172 57173 57174 57175 57176 57177 57178 57179 57180 57181 ...
  .. ..$ : int [1:969] 58141 58142 58143 58144 58145 58146 58147 58148 58149 58150 ...
  .. ..$ : int [1:969] 59110 59111 59112 59113 59114 59115 59116 59117 59118 59119 ...
  .. ..$ : int [1:969] 60079 60080 60081 60082 60083 60084 60085 60086 60087 60088 ...
  .. ..$ : int [1:969] 61048 61049 61050 61051 61052 61053 61054 61055 61056 61057 ...
  .. ..$ : int [1:969] 62017 62018 62019 62020 62021 62022 62023 62024 62025 62026 ...
  .. ..$ : int [1:969] 62986 62987 62988 62989 62990 62991 62992 62993 62994 62995 ...
  .. ..$ : int [1:969] 63955 63956 63957 63958 63959 63960 63961 63962 63963 63964 ...
  .. ..$ : int [1:969] 64924 64925 64926 64927 64928 64929 64930 64931 64932 64933 ...
  .. ..$ : int [1:969] 65893 65894 65895 65896 65897 65898 65899 65900 65901 65902 ...
  .. ..$ : int [1:969] 66862 66863 66864 66865 66866 66867 66868 66869 66870 66871 ...
  .. ..$ : int [1:969] 67831 67832 67833 67834 67835 67836 67837 67838 67839 67840 ...
  .. ..$ : int [1:969] 68800 68801 68802 68803 68804 68805 68806 68807 68808 68809 ...
  .. ..$ : int [1:969] 69769 69770 69771 69772 69773 69774 69775 69776 69777 69778 ...
  .. ..$ : int [1:969] 70738 70739 70740 70741 70742 70743 70744 70745 70746 70747 ...
  .. ..$ : int [1:969] 71707 71708 71709 71710 71711 71712 71713 71714 71715 71716 ...
  .. ..$ : int [1:969] 72676 72677 72678 72679 72680 72681 72682 72683 72684 72685 ...
  .. ..$ : int [1:969] 73645 73646 73647 73648 73649 73650 73651 73652 73653 73654 ...
  .. ..$ : int [1:969] 74614 74615 74616 74617 74618 74619 74620 74621 74622 74623 ...
  .. ..$ : int [1:969] 75583 75584 75585 75586 75587 75588 75589 75590 75591 75592 ...
  .. ..$ : int [1:969] 76552 76553 76554 76555 76556 76557 76558 76559 76560 76561 ...
  .. ..$ : int [1:969] 77521 77522 77523 77524 77525 77526 77527 77528 77529 77530 ...
  .. ..$ : int [1:969] 78490 78491 78492 78493 78494 78495 78496 78497 78498 78499 ...
  .. ..$ : int [1:969] 79459 79460 79461 79462 79463 79464 79465 79466 79467 79468 ...
  .. ..$ : int [1:969] 80428 80429 80430 80431 80432 80433 80434 80435 80436 80437 ...
  .. ..$ : int [1:969] 81397 81398 81399 81400 81401 81402 81403 81404 81405 81406 ...
  .. ..$ : int [1:969] 82366 82367 82368 82369 82370 82371 82372 82373 82374 82375 ...
  .. ..$ : int [1:969] 83335 83336 83337 83338 83339 83340 83341 83342 83343 83344 ...
  .. ..$ : int [1:969] 84304 84305 84306 84307 84308 84309 84310 84311 84312 84313 ...
  .. ..$ : int [1:969] 85273 85274 85275 85276 85277 85278 85279 85280 85281 85282 ...
  .. ..$ : int [1:969] 86242 86243 86244 86245 86246 86247 86248 86249 86250 86251 ...
  .. ..$ : int [1:969] 87211 87212 87213 87214 87215 87216 87217 87218 87219 87220 ...
  .. ..$ : int [1:969] 88180 88181 88182 88183 88184 88185 88186 88187 88188 88189 ...
  .. ..$ : int [1:969] 89149 89150 89151 89152 89153 89154 89155 89156 89157 89158 ...
  .. ..$ : int [1:969] 90118 90119 90120 90121 90122 90123 90124 90125 90126 90127 ...
  .. ..$ : int [1:969] 91087 91088 91089 91090 91091 91092 91093 91094 91095 91096 ...
  .. ..$ : int [1:969] 92056 92057 92058 92059 92060 92061 92062 92063 92064 92065 ...
  .. ..$ : int [1:969] 93025 93026 93027 93028 93029 93030 93031 93032 93033 93034 ...
  .. ..$ : int [1:969] 93994 93995 93996 93997 93998 93999 94000 94001 94002 94003 ...
  .. ..$ : int [1:969] 94963 94964 94965 94966 94967 94968 94969 94970 94971 94972 ...
  .. .. [list output truncated]
  .. ..@ ptype: int(0) 
  ..- attr(*, ".drop")= logi TRUE
 - attr(*, "index")= chr "Month"
  ..- attr(*, "ordered")= logi TRUE
 - attr(*, "index2")= chr "Month"
 - attr(*, "interval")= interval [1:1] 1M
  ..@ .regular: logi TRUE
Code
# Fit ETS model and generate forecasts
us_employment %>%
  filter(Series_ID=="CEU0500000001") %>%
  model(SNAIVE(Employed),
        ETS(Employed)
        ) %>%
  forecast(h = "10 years") %>%
  autoplot(us_employment)

5 Summary

  • fpp3 loads tsibble, fable, and feasts → all require tsibble data
  • A tsibble = tidy time series with Index (time) + Key (series ID)
  • Always reshape into long format for tsibble
  • Single key → one identifier (e.g., Country)
  • Multiple keys → combinations of identifiers (e.g., State + Industry)
  • Declare keys properly to avoid duplicate or collapsed series