# Computing Means and Bands

## Procedure

After running a full-distribution forecast, we are often interested in finding means and density bands of the various forecast outputs. This will allow us to plot our estimation of the full distribution of the forecast outputs.

**Main Steps:**

*Load data:*Load and transform data, population data, and population forecast (required for forecast output transformations)*Read in forecast outputs:*Read in the outputs saved by`forecast_one`

, one variable (e.g. one observable) and one`output_type`

at a time.*Transform forecast outputs:*If necessary, use`reverse_transform`

to apply transformations specified in the`Observable`

or`PseudoObservable`

type to the given forecast output series.*Compute means and bands:*Compute the means and density bands of the forecast output.*Write to file:*For each`output_var`

, Write a`MeansBands`

object (see The MeansBands Type below) to the file specified by`get_meansbands_output_file`

.

Computing means and bands is done by calling `compute_meansbands`

. If desired, you can also write your computed means and bands as matrices by calling `meansbands_matrix_all`

.

For example, to compute means and bands for an unconditional, full-distribution forecast of states and observables:

```
m = AnSchorfheide()
compute_meansbands(m, :mode, :none, [:forecaststates, forecastobs])
```

## Weighted Averages of Full-Distribution Forecasts

Sometimes a forecaster may want to combine several different "scenarios" to construct a forecast. For example, there may be uncertainty about the right model to use. Rather than pick just one model, a forecaster would instead want to somehow combine the forecasts from all the models. As another example, a forecaster may not be sure what policies will be implemented in the future, so it may be easier to forecast the future by constructing different plausible scenarios.

We implement forecast combination as a weighted average of forecast paths drawn from different forecasts. A full-distribution forecast is just a matrix of different possible forecast paths, which approximate the true distribution of forecast paths. To construct a weighted average of forecasts from different scenarios, we just need to draw randomly from each scenario's distribution of forecast paths.

For example, suppose `m1`

, `m2`

, `m3`

are three different models with unconditional forecasts identified by `forecast_string1`

, `forecast_string2`

, and `forecast_string3`

. Then an equal weighted average of these forecasts identified by the tag `combo_forecast_string`

can be calculated by running

```
input_types = [:full, :full, :full]
cond_types = [:none, :none, :none]
compute_meansbands([m1, m2, m3], input_types, cond_types, output_vars;
weights = [1/3, 1/3, 1/3],
forecast_strings = [forecast_string1, forecast_string2, forecast_string3],
combo_forecast_string = combo_forecast_string)
```

The results are saved using the file paths implied by the first model in the vector of models passed as the first input argument (`m1`

). To get the resulting `MeansBands`

, run

`mb = read_mb(m1, :full, :none, output_var; forecast_string = combo_forecast_string)`

## Functions for Calculating Means and Bands

`DSGE.compute_meansbands`

— Function```
compute_meansbands(m, input_type, cond_type, output_vars; forecast_string = "",
verbose = :low, kwargs...)
compute_meansbands(m, input_type, cond_type, output_var, df; forecast_string = "",
population_data = DataFrame(), population_forecast = DataFrame(),
verbose = :none, kwargs...)
compute_meansbands(m, input_type, cond_type, output_var, var_name, df;
forecast_string = "", population_data = DataFrame(),
population_forecast = DataFrame(), verbose = :low,
kwargs...)
```

Compute means and bands for pseudo-observables, observables, and shocks, and write the results to a file. Other methods are for one `output_var`

and one `var_name`

respectively.

**Keyword Arguments**

`forecast_string::String = ""`

: forecast identifier string (the value "fcid=value" in the forecast output filename). Required when`input_type == :subset`

`density_bands::Vector{Float64} = [.5, .6, .7, .8 .9]`

: a vector of percent values (between 0 and 1) for which to compute density bands.`minimize::Bool = false`

: if`true`

, choose shortest interval, otherwise just chop off lowest and highest (percent/2)`verbose::Symbol = :low`

: level of error messages to be printed to screen. One of`:none`

,`:low`

,`:high`

`bdd_fcast::Bool = true`

: if true, calculate bounded forecasts`skipnan::Bool = false`

: if true, remove any NaNs found in the raw forecast output series`df::DataFrame = DataFrame()`

: if an empty DataFrame, then the function will attempt to load the data using`load_data`

.`check_empty_columns::Bool = true`

: if true, throw an error if calling load_data yields an empty column.`pseudo2data::AbstractDict{Symbol, Symbol} = Dict()`

: Maps the names of pseudo-observables which require historical data during transformation to the name of the required historical series.

```
compute_meansbands(models, input_types, cond_types, output_vars; forecast_strings = [],
verbose = :low, kwargs...)
compute_meansbands(models, input_types, cond_types, output_vars, df; forecast_strings = [],
population_data = DataFrame(), population_forecast = DataFrame(),
verbose = :none, kwargs...)
compute_meansbands(models, input_types, cond_types, output_var, var_name, df;
forecast_strings = [], population_data = DataFrame(),
population_forecast = DataFrame(), verbose = :low,
kwargs...)
```

Compute means and bands for pseudo-observables, observables, and shocks from multiple forecasts, and write the results to a file. Other methods are for one `output_var`

and one `var_name`

respectively.

**Keyword Arguments**

`forecast_strings::Vector{String} = []`

: forecast identifier strings for each forecast (the value "fcid=value" in the forecast output filename for individual forecasts). Required when`input_type == :subset`

`density_bands::Vector{Float64} = [.5, .6, .7, .8 .9]`

: a vector of percent values (between 0 and 1) for which to compute density bands.`minimize::Bool = false`

: if`true`

, choose shortest interval, otherwise just chop off lowest and highest (percent/2)`verbose::Symbol = :low`

: level of error messages to be printed to screen. One of`:none`

,`:low`

,`:high`

`bdd_fcast::Bool = true`

: if true, calculate bounded forecasts`skipnan::Bool = false`

: if true, remove any NaNs found in the raw forecast output series`ndraws::Int = 20000`

: number of draws from the underlying scenarios`df::DataFrame = DataFrame()`

: if an empty DataFrame, then the function will attempt to load the data using`load_data`

.`check_empty_columns::Bool = true`

: if true, throw an error if calling load_data yields an empty column.`pseudo2data::AbstractDict{Symbol, Symbol} = Dict()`

: Maps the names of pseudo-observables which require historical data during transformation to the name of the required historical series.

## The `MeansBands`

type

`DSGE.MeansBands`

— Type`mutable struct MeansBands`

Stores the means and bands of results for a particular set of outputs from the forecast step.

Specifically, forecasts can be made for any element in the Cartesian product of 4 sets:

`input_type`

: some subset of the parameter draws from the estimation step. See`forecast_one`

for all possible options.`cond_type`

: conditional type. See`forecast_one`

for all possible options.*product*: a particular result computed in the forecast. This could be one of the following:

```
- `hist`: smoothed histories
- `forecast`: forecasted values
- `shockdec`: shock decompositions
- `shockdecseq`: shock decompositions
- `irf`: impulse responses
```

- variable
*class*: the category in which a particular variable, like`:y_t`

, falls. Options are:

```
- `state`: state (from `m.endogenous_states` or `m.endogenous_states_augmented`)
- `obs`: observable (from `m.observables`)
- `pseudo`: pseudoobservable (from `pseudo_measurement` equation)
- `shock`: shock (from `m.exogenous_shocks`)
```

Note that the Cartesian product (product x class) is the set of options for `output_vars`

in the `forecast_one`

function signature.

**Fields**

`metadata::Dict{Symbol,Any}`

: Contains metadata keeping track of the`input_type`

,`cond_type`

, product (history, forecast, shockdec, etc), and variable class (observable, pseudoobservable, state, etc) stored in this`MeansBands`

structure.`means::DataFrame`

: a`DataFrame`

of the mean of the time series`bands::Dict{Symbol,DataFrame}`

: a`Dict`

mapping variable names to`DataFrame`

s containing confidence bands for each variable. See`find_density_bands`

for more information.