MarkusTrunschke / GNRProdEst.jl

Implementation of the Gandhi, Navarro, Rievers (2020) production function estimator.
MIT License
4 stars 0 forks source link

GNRProdEst

This package implements the production function estimaton method from Gandhi, Navarro, Rievers (2020).

Installation

Use Julia's integrated package manager Pkg.jl

using Pkg
Pkg.add("GNRProdEst")

Usage

You can use estimation routine in two ways. Either run both stages using gnrprodest or run each estimation stage separately with gnrfirststage and gnrsecondstage. Versions of these functions that end with an ! modify their inputs (most importantly the dataframe).

Using gnrprodest and gnrprodest!

Both versions have exactly the same arguments. The difference is, that gnrprodest modifies its arguments (especially data). fes_returns is a NamedTuple of first stage return objects, ses_returns is the equivalent for the second stage, and estimation_sample is the DataFrame used in the estimation routine.

using GNRProdEst

fes_returns, ses_returns, estimation_sample = gnrprodest(data = DataFrame, output = :revenue, flexible_input = :flexible_input, fixed_inputs = [:fixed_input1 :fixed_input2 ...], id = :id, time = :time)

fes_returns, ses_returns = gnrprodest!(data = DataFrame, output = :gross_output, flexible_input = :flexible_input, fixed_inputs = [:fixed_input1 :fixed_input2 ...], id = :id, time = :time)

Arguments

All arguments in any of the functions are keyword arguments. The necessary arguments are:

Optional Arguments

Using gnrfirststage and gnrfirststage!

Instead of using one command for both stages, you can estimate both stages independently. The command for the estimation of the first stage is gnrfirststage or gnrfirststage!. The difference is that the latter changes its inputs (especially the data). See the list of argument descriptions above.fes_returns is a NamedTuple of first stage return objects and estimation_sample is the DataFrame used in the estimation routine.

using GNRProdEst

fes_returns, estimation_sample = gnrfirststage(data = DataFrame, output = gross_output, flexible_input = :flexible_input, fixed_inputs = [:fixed_input1 :fixed_input2 ...],ln_share_flex_y = :ln_share_flex_y, share_degree = :share_degree, starting_values = :starting_values, opts = opts)

fes_returns = gnrfirststage!(data = DataFrame, output = gross_output, flexible_input = :flexible_input, fixed_inputs = [:fixed_input1 :fixed_input2 ...],ln_share_flex_y = :ln_share_flex_y, share_degree = :share_degree, starting_values = :starting_values, opts = opts)

Using gnrsecondstage and gnrsecondstage!

The command for the estimation of the second stage is gnrsecondstage or gnrsecondstage!. The difference is that the latter changes its inputs (especially the data). See the list of argument descriptions above. The only additional argument is fes_returns representing the object returned from the first stage estimation. Use opts as described above to modify additional options, such as the numerical optimization algorithm. ses_returns is a NamedTuple of return objects from the second stage estimation.

using GNRProdEst

ses_returns, estimation_sample = gnrsecondstage(data = DataFrame,flexible_input = :flexible_input, fixed_inputs = [:fixed_input1 :fixed_input2 ...], id = :id, time = :time, fes_returns = fes_returns, int_const_series_degree = int_const_series_degree, lm_tfp_degree = lm_tfp_degree, starting_values = ses_starting_values, opts = opts)

ses_returns = gnrsecondstage!(data = DataFrame,flexible_input = :flexible_input, fixed_inputs = [:fixed_input1 :fixed_input2 ...], id = :id, time = :time, fes_returns = fes_returns, int_const_series_degree = int_const_series_degree, lm_tfp_degree = lm_tfp_degree, starting_values = ses_starting_values, opts = opts)

Example

This example uses 500 firms from Gandhi, Navarro, Rivers (2020)'s replication package data. It estimates a gross output production function with one flexible input $i$ and one fixed input $k$.


# Load required dependencies (use 'using Pkg' and Pkg.add("DataFrames"), Pkg.add("GNRProdEst") or Pkg.add("CSV") if you do not have any of these packages in your environment.)
using GNRProdEst, DataFrames, CSV

# Read in replication data
rep_data = CSV.read("test/GNR_data_500.csv", DataFrame)

# Define some options to print results
opts = Dict("fes_print_results" => true, "ses_print_results" => true)

# Run both estimation stages at the same time
gnr_res = GNRProdEst.gnrprodest!(data = rep_data, 
                                output = :yg, 
                                flexible_input = :i, 
                                fixed_inputs = :k, 
                                ln_share_flex_y = :si, 
                                id = :id, 
                                time = :time,
                                opts = opts);

Output should be

First stage results:
┌──────────┬──────────┬──────────┐
│ Variable │        γ │       γ' │
├──────────┼──────────┼──────────┤
│ constant │  0.65239 │  0.67590 │
│        k │ -0.00146 │ -0.00152 │
│      k⋅k │ -0.00050 │ -0.00052 │
│    k⋅k⋅k │ -0.00033 │ -0.00035 │
│    k⋅k⋅i │  0.00111 │  0.00115 │
│      k⋅i │  0.00123 │  0.00128 │
│    k⋅i⋅i │ -0.00112 │ -0.00116 │
│        i │ -0.02119 │ -0.02195 │
│      i⋅i │  0.00476 │  0.00494 │
│    i⋅i⋅i │ -0.00005 │ -0.00005 │
└──────────┴──────────┴──────────┘
Integration constant series parameters
┌──────────┬──────────┐
│ Variable │ Estimate │
├──────────┼──────────┤
│        k │  0.38825 │
│      k⋅k │ -0.02485 │
│    k⋅k⋅k │  0.00247 │
└──────────┴──────────┘
All output elasticities:
┌──────────┬─────────┬─────────┬─────────┬─────────┐
│ Variable │    Mean │      SD │     Min │     Max │
├──────────┼─────────┼─────────┼─────────┼─────────┤
│        k │ 0.28670 │ 0.01767 │ 0.27269 │ 0.38782 │
│        i │ 0.62627 │ 0.00454 │ 0.60449 │ 0.65235 │
└──────────┴─────────┴─────────┴─────────┴─────────┘
Productivity:
┌──────────┬──────────┬─────────┬──────────┬─────────┐
│ Variable │     Mean │      SD │      Min │     Max │
├──────────┼──────────┼─────────┼──────────┼─────────┤
│        ω │  0.80982 │ 0.34225 │ -0.47409 │ 1.67487 │
│        Ω │  2.38170 │ 0.82280 │  0.62245 │ 5.33810 │
│        v │ -0.00007 │ 0.23424 │ -1.27870 │ 1.25506 │
└──────────┴──────────┴─────────┴──────────┴─────────┘
Productivity Law of Motion:
┌──────────┬──────────┐
│ Variable │ Estimate │
├──────────┼──────────┤
│ constant │  0.16803 │
│        ω │  0.76907 │
│       ω² │  0.06544 │
│       ω³ │ -0.03980 │
└──────────┴──────────┘

Alternatively, you can estimate both stages sparately with

# Load required dependencies (use 'using Pkg' and Pkg.add("DataFrames"), Pkg.add("GNRProdEst") or Pkg.add("CSV") if you do not have any of these packages in your environment.)
using GNRProdEst, DataFrames, CSV

# Read in replication data
rep_data = CSV.read("test/GNR_data_500.csv", DataFrame)

# Define some options to print results
opts = Dict("fes_print_results" => true, "ses_print_results" => true)

# Run the first estimation stage
fes_return_obj, est_sample = GNRProdEst.gnrfirststage(data = rep_data,
                                                      output = :yg,
                                                      flexible_input = :i,
                                                      fixed_inputs = :k,
                                                      ln_share_flex_y = :si,
                                                      opts = opts);

Output should be

First stage results:
┌──────────┬──────────┬──────────┐
│ Variable │        γ │       γ' │
├──────────┼──────────┼──────────┤
│ constant │  0.65239 │  0.67590 │
│        k │ -0.00146 │ -0.00152 │
│      k⋅k │ -0.00050 │ -0.00052 │
│    k⋅k⋅k │ -0.00033 │ -0.00035 │
│    k⋅k⋅i │  0.00111 │  0.00115 │
│      k⋅i │  0.00123 │  0.00128 │
│    k⋅i⋅i │ -0.00112 │ -0.00116 │
│        i │ -0.02119 │ -0.02195 │
│      i⋅i │  0.00476 │  0.00494 │
│    i⋅i⋅i │ -0.00005 │ -0.00005 │
└──────────┴──────────┴──────────┘

Afterwards, you can run the second estimation step with


ses_res = GNRProdEst.gnrsecondstage(data = est_sample,
                                    flexible_input = :i,
                                    fixed_inputs = :k,
                                    id = :id,
                                    time = :time,
                                    fes_returns = fes_return_obj,
                                    opts = opts);

The output should be

Integration constant series parameters
┌──────────┬──────────┐
│ Variable │ Estimate │
├──────────┼──────────┤
│        k │  0.38825 │
│      k⋅k │ -0.02485 │
│    k⋅k⋅k │  0.00247 │
└──────────┴──────────┘
All output elasticities:
┌──────────┬─────────┬─────────┬─────────┬─────────┐
│ Variable │    Mean │      SD │     Min │     Max │
├──────────┼─────────┼─────────┼─────────┼─────────┤
│        k │ 0.28670 │ 0.01767 │ 0.27269 │ 0.38782 │
│        i │ 0.62627 │ 0.00454 │ 0.60449 │ 0.65235 │
└──────────┴─────────┴─────────┴─────────┴─────────┘
Productivity:
┌──────────┬──────────┬─────────┬──────────┬─────────┐
│ Variable │     Mean │      SD │      Min │     Max │
├──────────┼──────────┼─────────┼──────────┼─────────┤
│        ω │  0.80982 │ 0.34225 │ -0.47409 │ 1.67487 │
│        Ω │  2.38170 │ 0.82280 │  0.62245 │ 5.33810 │
│        v │ -0.00007 │ 0.23424 │ -1.27870 │ 1.25506 │
└──────────┴──────────┴─────────┴──────────┴─────────┘
Productivity Law of Motion:
┌──────────┬──────────┐
│ Variable │ Estimate │
├──────────┼──────────┤
│ constant │  0.16803 │
│        ω │  0.76907 │
│       ω² │  0.06544 │
│       ω³ │ -0.03980 │
└──────────┴──────────┘

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

Please cite this package if you use it for published research.

MIT