-
Notifications
You must be signed in to change notification settings - Fork 0
/
ivcvscore.ado
70 lines (57 loc) · 2.07 KB
/
ivcvscore.ado
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
cap program drop ivcvscore
program ivcvscore, rclass
syntax varlist [if] [aw], [treatment(varlist numeric)] GENerate(name)
marksample touse
//drop collinear variables
_rmcoll `varlist' if `touse', forcedrop
local varlist = r(varlist)
if "`weight'" != "" {
local wgt [`weight'`exp']
}
di "`wgt'"
//I use the control group for normalization. If no treatment is given, I use everything
if ("`treatment'"=="") {
tempvar treatment
gen `treatment'=0
}
//loop over vars to normalize and check if they vary
foreach var of varlist `varlist'{
tempvar z`var'
qui sum `var' if `treatment'==0 & `touse' `wgt'
if r(sd)==0 {
di as err "no variation in `var', leaving it out of indices"
}
else {
gen `z`var'' = (`var'-r(mean))/r(sd) if `touse'
local usedvars `usedvars' `var'
local components `components' `z`var''
}
}
local varcount: word count `components'
//get cov matrix from control group
di as err "corr `components' `wgt' if `treatment'==0 & `touse', c"
corr `components' `wgt' if `treatment'==0 & `touse', c
matrix Cinv=inv(r(C))
matrix Isrow = vecdiag(I(`varcount'))
matrix weights = Isrow*Cinv
mata st_matrix("rmm",rowminmax(st_matrix("weights")))
if (rmm[1,1]<0 | rmm[1,2]>2) {
di as err "Some of the weights seem a bit odd (outside [0,2]), you might want to check them:"
}
mat colnames weights = `usedvars'
mat list weights
mata : st_matrix("weightsum", rowsum(st_matrix("weights")))
matrix relative_weights = weights/weightsum[1,1]
return matrix relative_weights = relative_weights
//compute weighted average
gen `generate' = 0 if `touse'
foreach var of local usedvars {
mat weight = weights[1,"`var'"]
di "`var'"
qui replace `generate' = `generate'+weight[1,1]*`z`var'' if `touse'
}
//normalize final index to have mean 0 and sd 1 in the control group
qui sum `generate' `wgt' if `treatment'==0 & `touse'
qui replace `generate'= (`generate'-r(mean))/r(sd) if `touse'
label var `generate' "Inverse covariance weighted score of: `usedvars'"
end