moritzpschwarz / osem

A novel Open-Source Empircial Macro (OSEM) Model to study Climate Policies and the wider Macro-economy that can easily be applied to all EU countries
http://moritzschwarz.org/osem/
GNU Affero General Public License v3.0
5 stars 4 forks source link

osem - Open Source Empirical Macro Model

R-CMD-check Codecov test
coverage

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:

library(osem)

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)