The goal of the {osem} Package is to implement and operationalise the Open Source Empirical Macro (OSEM) Model, developed by Moritz Schwarz, Jonas Kurle, Felix Pretis, and Andrew Martinez. This is an adaptation of the Norwegian Aggregate Model, developed by Gunnar Bardsen and Ragnar Nymoen.
Installation
You can install the development version of {osem} from GitHub with:
# install.packages("devtools")
devtools::install_github("moritzpschwarz/osem")
Basic Workflow
This is an example which shows you how to run the model:
First we load the package:
Specify the model
The we calibrate the model specification and save this in a tibble. Here the column names and the structure of the specification table must follow the basic structure below.
spec <- dplyr::tibble(
type = c(
"n",
"n",
"n",
"n",
"d",
"n",
"n",
"n",
"n"
),
dependent = c(
"Import",
"FinConsExpHH",
"GCapitalForm",
"Emissions",
"GDP",
"GValueAddGov", # as in NAM, technical relationship
"GValueAddManuf", # more complicated in NAM, see 2.3.3 and 6.3.1
"GValueAddConstr" ,
"GValueAddWholesaletrade"
),
independent = c(
"FinConsExpHH + GCapitalForm",
"",
"FinConsExpGov + FinConsExpHH",
"GDP + Export + GValueAddIndus",
"GValueAddGov + GValueAddAgri + GValueAddIndus + GValueAddConstr + GValueAddWholesaletrade + GValueAddInfocom + GValueAddFinance + GValueAddRealest + GValueAddResearch + GValueAddArts",
"FinConsExpGov", # as in NAM, technical relationship
"Export + LabCostManuf", # NAM uses 'export market indicator' not exports - unclear what this is, NAM uses unit labour cost in NOR manufacturing relative to the foreign price level - here is just total labour cost
"LabCostConstr + BuildingPermits", # in NAM some form of YFP2J = 0.3JBOL + 0.2JF P N + 0.3JO + 0.3JOIL. Unclear what this is. Using Building Permits instead
"Export + LabCostService"
))
To summarise this, we can print out the specification table:
type | dependent | independent |
---|---|---|
n | Import | FinConsExpHH + GCapitalForm |
n | FinConsExpHH | |
n | GCapitalForm | FinConsExpGov + FinConsExpHH |
n | Emissions | GDP + Export + GValueAddIndus |
d | GDP | GValueAddGov + GValueAddAgri + GValueAddIndus + GValueAddConstr + GValueAddWholesaletrade + GValueAddInfocom + GValueAddFinance + GValueAddRealest + GValueAddResearch + GValueAddArts |
n | GValueAddGov | FinConsExpGov |
n | GValueAddManuf | Export + LabCostManuf |
n | GValueAddConstr | LabCostConstr + BuildingPermits |
n | GValueAddWholesaletrade | Export + LabCostService |
In order to run this model, we also need a dictionary that translates our model variables to EUROSTAT codes so that the download process can be automated. You can either pass a new dictionary to the model function, or you can use the built in dictionary osem::dict
(here the first few rows):
model_varname | full_name | database | variable_code | dataset_id | var_col | freq | geo | unit | s_adj | nace_r2 | ipcc_sector | cpa2_1 | siec |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
TOTS | Total Supply | NA | TOTS | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
GDP | Gross domestic product at market prices | eurostat | B1GQ | namq_10_gdp | na_item | q | AT | CLV05_MEUR | SCA | NA | NA | NA | NA |
GValueAdd | Value added, gross | eurostat | B1G | namq_10_a10 | na_item | q | AT | CLV05_MEUR | SCA | TOTAL | NA | NA | NA |
Export | Exports of goods and services | eurostat | P6 | namq_10_gdp | na_item | q | AT | CLV05_MEUR | SCA | NA | NA | NA | NA |
Import | Imports of goods and services | eurostat | P7 | namq_10_gdp | na_item | q | AT | CLV05_MEUR | SCA | NA | NA | NA | NA |
GCapitalForm | Gross capital formation | eurostat | P5G | namq_10_gdp | na_item | q | AT | CLV05_MEUR | SCA | NA | NA | NA | NA |
Running the model
Now we are ready to run the model with the run_model()
function:
model_result <- run_model(
specification = spec,
save_to_disk = "inst/extdata/InputData.xlsx",
primary_source = "download",
trend = TRUE,
saturation.tpval = 0.01,
plot = FALSE
)
#> Dataset query already saved in cache_list.json...
#> Reading cache file C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/c567619dc239cdb6c8552d73b75636ff.rds
#> Table namq_10_gdp read from cache file: C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/c567619dc239cdb6c8552d73b75636ff.rds
#> Dataset query already saved in cache_list.json...
#> Reading cache file C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/5f7391f64512e2bcd91dad03fece5d6c.rds
#> Table env_ac_aigg_q read from cache file: C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/5f7391f64512e2bcd91dad03fece5d6c.rds
#> Dataset query already saved in cache_list.json...
#> Reading cache file C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/48c9e378cb4ff9a025f07c2a3c1c802b.rds
#> Table ei_lmlc_q read from cache file: C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/48c9e378cb4ff9a025f07c2a3c1c802b.rds
#> Dataset query already saved in cache_list.json...
#> Reading cache file C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/a48b692dcc3fb2781f39b235c4498221.rds
#> Table namq_10_a10 read from cache file: C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/a48b692dcc3fb2781f39b235c4498221.rds
#> Dataset query already saved in cache_list.json...
#> Reading cache file C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/747ede24fdec507eceea0e73e631fc53.rds
#> Table sts_cobp_q read from cache file: C:\Users\morit\AppData\Local\Temp\RtmpOUIr06/eurostat/747ede24fdec507eceea0e73e631fc53.rds
#> Warning in load_or_download_variables(specification = module_order, dictionary
#> = dictionary, : Unbalanced panel, will lose more than 20\% of data when making
#> balanced
#>
#> --- Estimation begins ---
#> Estimating GValueAddGov = FinConsExpGov
#> Estimating GValueAddManuf = Export + LabCostManuf
#> Estimating GValueAddConstr = LabCostConstr + BuildingPermits
#> Estimating GValueAddWholesaletrade = Export + LabCostService
#> Estimating FinConsExpHH =
#> No Outliers or Step-Shifts detected in the marginal equations to test for Super Exogeneity in ln.FinConsExpHH.
#> Hence not possible to run the test.
#> Constructing GDP = GValueAddGov + GValueAddAgri + GValueAddIndus + GValueAddConstr + GValueAddWholesaletrade + GValueAddInfocom + GValueAddFinance + GValueAddRealest + GValueAddResearch + GValueAddArts
#> Estimating GCapitalForm = FinConsExpGov + FinConsExpHH
#> Estimating Emissions = GDP + Export + GValueAddIndus
#> Estimating Import = FinConsExpHH + GCapitalForm
model_result
#> OSEM Model Output
#> -----------------------
#>
#> Estimation Options:
#> Sample: 2010-01-01 to 2023-07-01
#> Max AR Considered: 4
#> Estimation Option: ardl
#>
#> Relationships considered:
#> # A tibble: 9 × 3
#> Model `Dep. Var.` `Ind. Var`
#> 1 1 Import "FinConsExpHH + GCapitalForm"
#> 2 2 FinConsExpHH ""
#> 3 3 GCapitalForm "FinConsExpGov + FinConsExpHH"
#> 4 4 Emissions "GDP + Export + GValueAddIndus"
#> 5 5 GDP "GValueAddGov + GValueAddAgri + GValueAddIndus …
#> 6 6 GValueAddGov "FinConsExpGov"
#> 7 7 GValueAddManuf "Export + LabCostManuf"
#> 8 8 GValueAddConstr "LabCostConstr + BuildingPermits"
#> 9 9 GValueAddWholesaletrade "Export + LabCostService"
#>
#>
#> Relationships estimated in the order: 6,7,8,9,2,5,3,4,1
#>
#> Diagnostics:
#> # A tibble: 8 × 8
#> `Dependent Variable` AR ARCH `Super Exogeneity` IIS SIS n
#> <chr> <chr> <chr> <chr> <int> <int> <int>
#> 1 GValueAddGov 0.125 0.768 "0.029**" 3 3 53
#> 2 GValueAddManuf 0.663 0.864 "" 6 0 54
#> 3 GValueAddConstr 0.619 0.541 "<0.001***" 3 2 54
#> 4 GValueAddWholesaletrade 0.258 0.001*** "<0.001***" 13 0 54
#> 5 FinConsExpHH 0.870 0.711 "" 7 1 54
#> 6 GCapitalForm 0.602 0.851 "" 0 5 54
#> 7 Emissions 0.009*** 0.070* "0.007***" 0 3 55
#> 8 Import 0.106 0.958 "0.092*" 1 1 54
#> # ℹ 1 more variable: `Share of Indicators` <dbl>
The first time that we run this, all data will be downloaded and saved in the folder data/use/InputData.xlsx
.
The next time that we run the same model, we can save some time and just load the data from our earlier run:
model_result <- run_model(
specification = spec,
primary_source = "local",
inputdata_directory = "inst/extdata",
trend = TRUE,
saturation.tpval = 0.01
)
Forecasting the model
Now that we have run the model, we can forecast the model (here using an AR process for the exogenous values and for 10 time periods):
model_forecast <- forecast_model(model_result, n.ahead = 10, exog_fill_method = "AR", plot = FALSE)
#> No exogenous values provided. Model will forecast the exogenous values with an AR4 process (incl. Q dummies, IIS and SIS w 't.pval = 0.001').
#> Alternative is exog_fill_method = 'last'.
Once we are done, we can plot the forecast:
plot(model_forecast, order.as.run = TRUE)