Hi all,

I am in need of some help with a loop that I am trying to run. I am implementing propensity score matching and, following Imbens (2015), I am looking to match without replacement on the propensity score to create a balanced sample. I have estimated the propensity scores and transformed them into log odds ratios. Imbens (2015) then suggests, given the estimated log odds ratio, the N treated observations are ordered, with the treated unit with the highest value of the estimated log odds ratio scored first. Then, the first treated unit (the one with the highest value of the estimated log odds ratio) is matched with the control unit with the closest value of the estimated log odds ratio. This control observation is then removed from the pool of potential matches. Next, the second treated unit is matched
with the control unit with the closest value of the estimated log odds ratio (excluding the first match).
Continuing this for all t treated units leads to a sample of 2 ⋅ N distinct units, half of them treated and half of them controls.

I have written a loop (below) that I think achieves this. However, when I estimate my results after matching (I am estimating an ITT), the results change every time I re-estimate my matched sample. In other words, I think that I am getting different samples every time I run the loop. I am not changing my data or variables in the propensity score estimation. I was wondering if anyone could help me with this?

Thank you very much!

References: Imbens, G. (2015). Matching Methods in Practice Three Examples.

Code:

****** GENERATING LOGODDS BASED ON PROPENSITY SCORES ****

gen logodds = ln(((_pscore)/(1-_pscore)))

*** RANKING TREATMENT BASED ON LOG ODDS ***

gsort -logodds
gen n = _n
replace n = . if T == 0
sort n
drop n
gen n = _n
replace n = . if T == 0

***** MATCHING BASED ON LOG ODDS ****
count if T == 1
local totaltreated = r(N)

capture gen dist = .
capture gen pair = .
cap gen min = .

replace pair = 0 if T == 1

forvalues i = 1/`totaltreated' {
capture drop log_i
cap drop order
gen log_i = logodds if n == `i'
qui: sum log_i
replace log_i = r(mean)
replace dist = .
replace dist = abs(logodds - log_i) if missing(pair)
bys dist pair: gen order = _n
replace order = . if !missing(pair)
replace dist=. if T==1
sum dist if missing(pair)
replace min = r(min)
qui: replace pair = `i' if dist == min & missing(pair) & order== 1
}

replace pair = . if pair==0

gen matched = .
replace matched=0 if T==1
replace matched=1 if (pair!=.)
tab matched