Matching LBOs (Julia)

From edegan.com
Jump to navigation Jump to search

Inputs and Outputs

  • Input: tab delimited file "E:/McNair/Projects/LBO/Clean/STATApredictLBOclean.txt"
    • This contains list of LBO and nonLBO firms from compustat 1970-2015, propensity scores, patent data, and other variables generated from stata code "statadatasetup4.do" and "statapredictLBOclean.do"
  • Output: tab delimited file "E:/McNair/Projects/LBO/New matching/matchresults.txt"
    • This is the input file, except with an additional column "matchpair" indicating matched pairs:
    • Positive integers identify pairs matched, negative integers identify matched non-LBOs in years other than the match, -0.1 identifies LBOs that failed to match to any non-LBOs under constraints provided

Running Code

  • Open Julia command line in administrator mode
  • Change directory to E:\McNair\Projects\LBO\New matching\
cd("E:/McNair/Projects/LBO/New\ matching")
  • Run script LBOmatchscript.jl
include("LBOmatchscript.jl")

Options

There are a few options that can be customized in the script before running. Getting the code into a more user-friendly form is a WIP. In fact, some parts might be difficult, if not impossible, to write in a more accessible way.


Specify input file (if using different file than default)

Line 12:

df = readtable("E:/McNair/Projects/LBO/Clean/STATApredictLBOclean.txt", separator = '\t');

Specify which observations are valid for matching

  • For now, we filter out all firms that were never granted a single patent in the period 1970-2015
  • For firms that LBO, we also drop their observations in all other years from the list of candidates to match to other LBOs
  • See inline comments in code for detailed description of what matchfilter2, matchfilter4, etc. represent

Lines 38-48

#Splitting dataset into LBO and non-LBO firms
#Note that we also filter out all firms that were never granted a single patent in the period 1970-2015
LBOs =  @from i in df begin
        @where i.everlbo == 1 && (i.matchfilter4 == 1 ||i.matchfilter2b == 1) && i.lboentry == 1
        @select i
        @collect DataFrame
        end
nonLBOs = @from i in df begin
          @where i.everlbo == 0 && (i.matchfilter4 == 1 ||i.matchfilter2b == 1)
          @select i
          @collect DataFrame
          end

Specify propensity score type to use for matching

  • Options are: logitp (panel logit), probitp (panel probit), or Cox proportional hazard (hr)
  • Alternatively, can use the above options, with regressions performed using winsorized values of regressors (trimmed at 1st and 99th percentiles): logitpw, probitpw, hrw

Line 58:

mscore = :logitpw;

Specify whether matching priority should be deterministic or random

  • If deterministic, priority goes to lower GVKEY

Line 61:

randoption = 0;

Specify additional constraints on valid matches (modify code within function mcexpr as desired)

  • For example, default code forces matches to be within the same industry group, within the same decade, and with patent stocks within +/- 20% of LBO firm.

Lines 69-81:

function mcexpr(i)
 #note that the below syntax is the simplest way to store a long string over multiple lines
 #(i.e., appending additional characters per line)
 #Also, note that order of operations forces us to put each condition in parentheses
 mcriteria = "nonLBOs[:matchsubset] = (nonLBOs[:industrygroup3].== LBOs[$i,:industrygroup3])"
 mcriteria = mcriteria * " .* (nonLBOs[:decade].==LBOs[$i,:decade])"
 mcriteria = mcriteria * " .* (nonLBOs[:patentstock] .>= (LBOs[$i,:patentstock]*.8))"
 mcriteria = mcriteria * " .* (nonLBOs[:patentstock] .<= (LBOs[$i,:patentstock]*1.2))"
 mcriteria = mcriteria * " .* (nonLBOs[:matchpair] .== 0 )"
 return eval(parse(mcriteria))
end