Skip to content

Commit

Permalink
Merge pull request #5 from pcorralrodas/weighted_lnskew
Browse files Browse the repository at this point in the history
Added lnskew_w option : Commands have been tested with new option
  • Loading branch information
pcorralrodas authored Feb 23, 2023
2 parents 11fcdc5 + 5922634 commit 66e2dc3
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 8 deletions.
1 change: 1 addition & 0 deletions Sae example do file.do
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ global dpath "C:\Users\\`c(username)'\OneDrive\WPS_2020\7.twofold\"

run "C:\Users\WB378870\GitHub\SAE-Stata-Package\s\sae_mc_bs.ado"
run "C:\Users\WB378870\GitHub\SAE-Stata-Package\l\lsae_povmap.mata"
run "C:\Users\WB378870\GitHub\SAE-Stata-Package\l\lnskew0w.ado"

/*
Do file below is a test for a two fold nested error model. It follows the method
Expand Down
214 changes: 214 additions & 0 deletions l/lnskew0w.ado
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
*! version 1.0 23/02/2023
* Original code from Stata - adjusted to allow for survey weights
cap prog drop lnskew0w
cap prog drop Lnskew0w
program define lnskew0w, rclass sort
version 6, missing
global S_1 . /* Gamma */
global S_2 . /* Lower confidence limit */
global S_3 . /* Upper confidence limit */
global S_4 . /* skewness */

syntax anything(name=eq equalok) [if] [in] [, Level(passthru) * weight(varname) ]
if "`level'" != "" {
local old `"`eq' `if' `in' , `options'"'
local 0 ", `level'"
syntax [, level(cilevel)]
local 0 `"`old'"'
local ci = `level'/100
}
else {
local ci 0
local level 95
}
syntax newvarname =/exp [if] [in] [, /*
*/ Delta(real 0) Zero(real 0) weight(varname)]

if ("`weight'"==""){
tempvar weight
gen `weight' = 1
}

local exp `=trim(`"`exp'"')' // rm white space, messes up output
tempvar x lnx
quietly {
gen double `lnx'=.
gen double `x' = `exp' `if' `in'
summ `x' [aw=`weight'], detail
local obs = r(N)
if `obs' < 3 { noisily error 2001 }
local skew = r(skewness)
local min = r(min)
local max = r(max)
if `min' == `max' {
noisily di in red "no variance"
exit 409
}
local min0 = r(min)
local range = r(max)-r(min)
/*
Standardize data so that min=0, max=1.
*/
replace `x' = (`x'-`min0')/`range'
local min = 0
local max = 1
/*
Start of Gstar.
*/
local xmed = (r(p50)-`min0')/`range'
local term = `min'+`max'-2.0*`xmed'
local gamma = -4
if `term'>0 {
local g = `min'-(`min'-`xmed')^2/`term'
}
else if `term'<0 {
local g =-`max'+(`max'-`xmed')^2/`term'
}
else {
local g -4
}
local m1 = 1
if `skew'<0 {
local min -1
local max 0
replace `x' = -`x'
local minus "-"
local m1 -1
}
if (`g'>-4) & (`term'<0)==(`skew'<0) { local gamma = `g' }
/*
End of Gstar.
*/
local delta = cond(`delta'<=0, .02, `delta')
local zero = cond(`zero' <=0, .001, `zero')
local target 0
Lnskew0w `x' `gamma' `min' `delta' `zero' `target' `lnx' `weight'
local gamma = r(gamma) /* gamma in transformed units */
local skewg = r(skewness)
/*
Find confidence interval for gamma in transformed units
if n>=8.
*/
if (`obs'>7) & (`ci'>0) {
local z = invnorm(0.5+0.5*`ci')
_crczsku `z' `obs' 1
local target = r(target)
/*
Lower confidence limit (if it exists).
If not, it is taken as missing (minus infinity).
*/
if abs(`skew')<`target' { local gammal . }
else {
Lnskew0w `x' `gamma' `min' /*
*/ `delta' `zero' `target' `lnx' `weight'
local gammal = `m1'*`min0'+r(gamma)*`range'
}
local target = -`target'
Lnskew0w `x' `gamma' `min' `delta' /*
*/ `zero' `target' `lnx' `weight'
local gammah = `m1'*`min0'+r(gamma)*`range'
}
else local ci 0
replace `lnx'=`lnx'+log(`range')
replace `lnx'=log(`x'-`gamma')+log(`range')
local gamma = `m1'*`min0'+`gamma'*`range'
}
local cil `=string(`level')'
local cil `=length("`cil'")'
local spaces ""
if `cil' == 2 {
local spaces " "
}
else if `cil' == 4 {
local spaces " "
}
di _n in smcl in gr _col(8) "Transform" _col(18) "{c |}" /*
*/ _col(29) "k" _col(31) "`spaces'" /*
*/ `"[`=strsubdp("`level'")'% conf. interval] Skewness"' _n /*
*/ "{hline 17}{c +}{hline 50}"
local lhs = "ln(`minus'"+bsubstr("`exp'",1,8)+"-k)"
local l=16-length("`lhs'")
di in smcl in gr _skip(`l') "`lhs' {c |} " /*
*/ in ye %9.0g `gamma' " " _c
if `ci' {
ret scalar lb = `gammal'
ret scalar ub = `gammah'
global S_2 `gammal'
global S_3 `gammah'
if `gammal'>=. {
di "-infinity" _c
}
else di %9.0g `gammal' _c
di " " %9.0g `gammah' _c
}
else {
di in gr " (not calculated) " _c
}
ret scalar skewness = `skewg'
global S_4 `skewg'
di " " %9.0g return(skewness)
ret scalar gamma = `gamma'
global S_1 `gamma'
local gamma : display string(`gamma', "%9.0g")
local gamma = trim(`"`gamma'"')
if `gamma' > 0 {
local label `"ln(`minus'`exp'-`gamma')"'
}
else {
local gamma = -`gamma'
local label `"ln(`minus'`exp'+`gamma')"'
}
gen `typlist' `varlist' = `lnx'
label var `varlist' `"`label'"'
end


program define Lnskew0w, rclass
/*
Args: 1=_x, 2=gamma, 3=`min', 4=`delta', 5=`zero', 6=target skewness.
7=_lnx variable
Returns gamma in r(gamma), skewness in r(skewness)
*/
args X
local gamma = `2'
local min = `3'
local delta = `4'
local zero = `5'
local target = `6'
local lnx "`7'"
local peso "`8'"

local iter 0
local eta = -log(`min'-`gamma')
replace `lnx' = log(`X'-`gamma')
sort `lnx' /* for speed */
summ `lnx' [aw=`peso'], detail
local f0 = r(skewness)-`target'
ret scalar skewness = r(skewness)
* di in red "Iter Gamma Skewness"
while (abs(`f0') > `zero') {
* noisily di in red `iter' " " `gamma' " " `f0'
local iter = `iter'+1
replace `lnx' = log(`X'-`min'+exp(-`eta'-`delta'))
sum `lnx' [aw=`peso'], detail
local m = (r(skewness)-`target'-`f0')/`delta'
if `m' == 0 {
* noisily di in red /*
*/ "(convergence problems, doubling the value of delta)"
local delta = `delta'*2
}
else {
local eta = `eta'-`f0'/`m'
local gamma = `min'-exp(-`eta')
if (`gamma' > `min') {
local gamma = `min'-.0000001
local eta = -log(`min'-`gamma')
}
replace `lnx' = log(`X'-`gamma')
sum `lnx' [aw=`peso'], detail
local f0 = r(skewness)-`target'
ret scalar skewness = r(skewness)
}
}
ret scalar gamma = `gamma'
end
32 changes: 25 additions & 7 deletions s/sae_mc_bs.ado
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*! version 0.3.0 July 3, 2020
*! version 0.3.1 23/02/2023
*! Minh Cong Nguyen - mnguyen3@worldbank.org
*! Paul Andres Corral Rodas - pcorralrodas@worldbank.org
*! Joao Pedro Azevedo - jazevedo@worldbank.org
Expand Down Expand Up @@ -36,6 +36,7 @@ program define sae_mc_bs, eclass byable(recall)
lny
bcox
lnskew
lnskew_w
s2s_spec
Zvar(varlist numeric fv)
yhat(varlist numeric fv)
Expand Down Expand Up @@ -119,12 +120,14 @@ set more off
local wvar `w'
}

if ("`lny'"!="") local lny = 1
else local lny = 0
if ("`bcox'"!="") local bcox = 1
else local bcox = 0
if ("`lnskew'"!="") local lnskew = 1
else local lnskew = 0
if ("`lny'"!="") local lny = 1
else local lny = 0
if ("`bcox'"!="") local bcox = 1
else local bcox = 0
if ("`lnskew'"!="") local lnskew = 1
else local lnskew = 0
if ("`lnskew_w'"!="") local lnskew_w = 1
else local lnskew_w = 0

if (((`lnskew'+`bcox') ==2)){
display as error "lnskew option can's be used with bcox option"
Expand Down Expand Up @@ -153,6 +156,21 @@ set more off
local lhs `Thedep'
local lambda = r(gamma)
}
if (`lnskew_w'==1 & `lny'==1){
tempvar Thedep
lnskew0w double `Thedep' = exp(`lhs') if `touse23'==1, weight(`wvar')
local lhs `Thedep'
local lambda = r(gamma)
local lnskew = 1
}
if (`lnskew_w'==1 & `lny'==0){
tempvar Thedep
lnskew0w double `Thedep' = `lhs' if `touse23'==1, weight(`wvar')
local lhs `Thedep'
local lambda = r(gamma)
local lnskew = 1
}


povmap `lhs' `_Xx' if `touse23'==1 [aw=`wvar'], area(`area') ///
varest(`varest') zvar(`zvar') yhat(`yhat') yhat2(`yhat2') ebest uniq(`uniqid') seed(`seed') stage(first) new
Expand Down
5 changes: 4 additions & 1 deletion s/sae_mc_bs.sthlp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{smcl}
{* *! version 1.0.0 11Jan2020}{...}
{* *! version 1.0.1 23/02/2023}{...}
{cmd:help sae_mc_bs}
{hline}

Expand Down Expand Up @@ -93,6 +93,9 @@ simulated vectors of welfare. Possible indicators are: fgt0, fgt1, fgt2, ge0, ge
{phang}
{opt lnskew} Option tells command to execute lnskew0 (log shift transform - Zero skewness) on the dependent variable of your model.

{phang}
{opt lnskew_w} Option tells command to execute lnskew0 (log shift transform - Zero skewness) on the dependent variable of your model. It allows for the use of survey weights in transformation.

{phang}
{opt s2s_spec} option indicates that the survey is not a subset of the census and allows for cases where an area used for the model is not present in the census.

Expand Down

0 comments on commit 66e2dc3

Please sign in to comment.