You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
10 KiB
Plaintext
344 lines
10 KiB
Plaintext
10 months ago
|
*! version 1.1.0 05nov2008 Ben Jann
|
||
|
|
||
|
program define eststo, byable(onecall)
|
||
|
version 8.2
|
||
|
local caller : di _caller()
|
||
|
// --- eststo clear ---
|
||
|
if `"`1'"'=="clear" {
|
||
|
if `"`0'"'!="clear" {
|
||
|
di as err "invalid syntax"
|
||
|
exit 198
|
||
|
}
|
||
|
if "`_byvars'"!="" error 190
|
||
|
_eststo_clear
|
||
|
exit
|
||
|
}
|
||
|
// --- update globals ---
|
||
|
_eststo_cleanglobal
|
||
|
// --- eststo dir ---
|
||
|
if `"`1'"'=="dir" {
|
||
|
if `"`0'"'!="dir" {
|
||
|
di as err "invalid syntax"
|
||
|
exit 198
|
||
|
}
|
||
|
if "`_byvars'"!="" error 190
|
||
|
_eststo_dir
|
||
|
exit
|
||
|
}
|
||
|
// --- eststo drop ---
|
||
|
if `"`1'"'=="drop" {
|
||
|
if "`_byvars'"!="" error 190
|
||
|
_eststo_`0'
|
||
|
exit
|
||
|
}
|
||
|
// --- eststo store (no by) ---
|
||
|
if "`_byvars'"=="" {
|
||
|
version `caller': _eststo_store `0'
|
||
|
exit
|
||
|
}
|
||
|
// --- eststo store (by) ---
|
||
|
// - check sorting
|
||
|
local sortedby : sortedby
|
||
|
local i 0
|
||
|
foreach byvar of local _byvars {
|
||
|
local sortedbyi : word `++i' of `sortedby'
|
||
|
if "`byvar'"!="`sortedbyi'" error 5
|
||
|
}
|
||
|
// - parse command on if qualified
|
||
|
capt _on_colon_parse `0'
|
||
|
if _rc error 190
|
||
|
if `"`s(after)'"'=="" error 190
|
||
|
local estcom `"`s(after)'"'
|
||
|
local 0 `"`s(before)'"'
|
||
|
if substr(trim(`"`estcom'"'),1,3)=="svy" {
|
||
|
di as err "svy commands not allowed with by ...: eststo:"
|
||
|
exit 190
|
||
|
}
|
||
|
AddBygrpToIfqualifier `estcom'
|
||
|
// - parse syntax of _eststo_store call in order to determine
|
||
|
// whether title() or missing was specified (note that
|
||
|
// -estimates change- cannot be used to set the titles since
|
||
|
// it does not work with -noesample-)
|
||
|
TitleAndMissing `0'
|
||
|
// - generate byindex
|
||
|
tempname _byindex
|
||
|
qui egen long `_byindex' = group(`_byvars'), label `missing'
|
||
|
qui su `_byindex', meanonly
|
||
|
if r(N)==0 error 2000
|
||
|
local Nby = r(max)
|
||
|
// - loop over bygroups
|
||
|
forv i = 1/`Nby' {
|
||
|
local ibylab: label (`_byindex') `i'
|
||
|
di as txt _n "{hline}"
|
||
|
di as txt `"-> `ibylab'"' // could be improved
|
||
|
if `titleopt'==0 local ibytitle
|
||
|
else if `titleopt'==1 local ibytitle `" title(`ibylab')"'
|
||
|
else if `titleopt'==2 local ibytitle `", title(`ibylab')"'
|
||
|
capture noisily {
|
||
|
version `caller': _eststo_store `0'`ibytitle' : `estcmd'
|
||
|
}
|
||
|
if _rc {
|
||
|
if "`_byrc0'"=="" error _rc
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
|
||
|
prog TitleAndMissing
|
||
|
capt syntax [anything] , Title(string) [ MISsing * ]
|
||
|
if _rc==0 {
|
||
|
c_local titleopt 0
|
||
|
c_local missing "`missing'"
|
||
|
}
|
||
|
else {
|
||
|
syntax [anything] [ , MISsing * ]
|
||
|
if `"`missing'`options'"'!="" c_local titleopt 1
|
||
|
else c_local titleopt 2
|
||
|
c_local missing "`missing'"
|
||
|
}
|
||
|
end
|
||
|
|
||
|
program AddBygrpToIfqualifier
|
||
|
syntax anything(equalok) [if/] [in] [using] [fw aw pw iw] [, * ]
|
||
|
local estcom `"`macval(anything)' if (\`_byindex'==\`i')"'
|
||
|
if `"`macval(if)'"'!="" {
|
||
|
local estcom `"`macval(estcom)' & (`macval(if)')"'
|
||
|
}
|
||
|
if `"`macval(in)'"'!="" {
|
||
|
local estcom `"`macval(estcom)' `macval(in)'"'
|
||
|
}
|
||
|
if `"`macval(using)'"'!="" {
|
||
|
local estcom `"`macval(estcom)' `macval(using)'"'
|
||
|
}
|
||
|
if `"`macval(weight)'"'!="" {
|
||
|
local estcom `"`macval(estcom)' [`macval(weight)'`macval(exp)']"'
|
||
|
}
|
||
|
if `"`macval(options)'"'!="" {
|
||
|
local estcom `"`macval(estcom)', `macval(options)'"'
|
||
|
}
|
||
|
c_local estcmd `"`macval(estcom)'"'
|
||
|
end
|
||
|
|
||
|
program define _eststo_clear
|
||
|
local names $eststo
|
||
|
foreach name of local names {
|
||
|
capt estimates drop `name'
|
||
|
}
|
||
|
global eststo
|
||
|
global eststo_counter
|
||
|
end
|
||
|
|
||
|
program define _eststo_dir
|
||
|
if `"$eststo"'!="" {
|
||
|
estimates dir $eststo
|
||
|
}
|
||
|
end
|
||
|
|
||
|
program define _eststo_cleanglobal
|
||
|
local enames $eststo
|
||
|
if `"`enames'"'!="" {
|
||
|
tempname hcurrent
|
||
|
_return hold `hcurrent'
|
||
|
qui _estimates dir
|
||
|
local snames `r(names)'
|
||
|
_return restore `hcurrent'
|
||
|
}
|
||
|
local names: list enames & snames
|
||
|
global eststo `names'
|
||
|
if "`names'"=="" global eststo_counter
|
||
|
end
|
||
|
|
||
|
program define _eststo_drop
|
||
|
local droplist `0'
|
||
|
if `"`droplist'"'=="" {
|
||
|
di as error "someting required"
|
||
|
exit 198
|
||
|
}
|
||
|
local names $eststo
|
||
|
foreach item of local droplist {
|
||
|
capt confirm integer number `item'
|
||
|
if _rc {
|
||
|
local dropname `item'
|
||
|
}
|
||
|
else {
|
||
|
if `item'<1 {
|
||
|
di as error "`item' not allowed"
|
||
|
exit 198
|
||
|
}
|
||
|
local dropname est`item'
|
||
|
}
|
||
|
local found 0
|
||
|
foreach name in `names' {
|
||
|
if match("`name'",`"`dropname'"') {
|
||
|
local found 1
|
||
|
estimates drop `name'
|
||
|
local names: list names - name
|
||
|
di as txt "(" as res "`name'" as txt " dropped)"
|
||
|
}
|
||
|
}
|
||
|
if `found'==0 {
|
||
|
di as txt "(no matches found for " as res `"`dropname'"' as txt ")"
|
||
|
}
|
||
|
}
|
||
|
global eststo `names'
|
||
|
end
|
||
|
|
||
|
|
||
|
program define _eststo_store, eclass
|
||
|
local caller : di _caller()
|
||
|
capt _on_colon_parse `0'
|
||
|
if !_rc {
|
||
|
local command `"`s(after)'"'
|
||
|
local 0 `"`s(before)'"'
|
||
|
}
|
||
|
syntax [name] [, ///
|
||
|
Title(passthru) ///
|
||
|
Prefix(name) ///
|
||
|
Refresh Refresh2(numlist integer max=1 >0) ///
|
||
|
ADDscalars(string asis) ///
|
||
|
noEsample ///
|
||
|
noCopy ///
|
||
|
MISsing svy /// doesn't do anything
|
||
|
]
|
||
|
if `"`prefix'"'=="" local prefix "est"
|
||
|
|
||
|
// get previous eststo names and counter
|
||
|
local names $eststo
|
||
|
local counter $eststo_counter
|
||
|
if `"`counter'"'=="" local counter 0
|
||
|
|
||
|
// if name provided; set refresh on if name already in list
|
||
|
if "`namelist'"!="" {
|
||
|
if "`refresh2'"!="" {
|
||
|
di as error "refresh() not allowed"
|
||
|
exit 198
|
||
|
}
|
||
|
local name `namelist'
|
||
|
if `:list name in names' local refresh refresh
|
||
|
else {
|
||
|
if "`refresh'"!="" {
|
||
|
di as txt "(" as res "`name'" as txt " not found)"
|
||
|
}
|
||
|
local refresh
|
||
|
}
|
||
|
if "`refresh'"=="" local ++counter
|
||
|
}
|
||
|
// if no name provided
|
||
|
else {
|
||
|
if "`refresh2'"!="" local refresh refresh
|
||
|
if "`refresh'"!="" {
|
||
|
// refresh2 not provided => refresh last (if available)
|
||
|
if "`refresh2'"=="" {
|
||
|
if "`names'"=="" {
|
||
|
di as txt "(nothing to refresh)"
|
||
|
local refresh
|
||
|
}
|
||
|
else local name: word `:list sizeof names' of `names'
|
||
|
}
|
||
|
// refresh2 provided => check availability
|
||
|
else {
|
||
|
if `:list posof "`prefix'`refresh2'" in names' {
|
||
|
local name `prefix'`refresh2'
|
||
|
}
|
||
|
else {
|
||
|
di as txt "(" as res "`prefix'`refresh2'" as txt " not found)"
|
||
|
local refresh
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if "`refresh'"=="" local ++counter
|
||
|
// set default name
|
||
|
if "`name'"=="" local name `prefix'`counter'
|
||
|
}
|
||
|
|
||
|
// run estimation command if provided
|
||
|
if `"`command'"'!="" {
|
||
|
version `caller': `command'
|
||
|
}
|
||
|
|
||
|
// add scalars to e()
|
||
|
if `"`addscalars'"'!="" {
|
||
|
capt ParseAddscalars `addscalars'
|
||
|
if _rc {
|
||
|
di as err `"addscalars() invalid"'
|
||
|
exit 198
|
||
|
}
|
||
|
if "`replace'"=="" {
|
||
|
local elist `: e(scalars)' `: e(macros)' `: e(matrices)' `: e(functions)'
|
||
|
}
|
||
|
local forbidden b V sample
|
||
|
while (1) {
|
||
|
gettoken lhs rest: rest
|
||
|
if `:list lhs in forbidden' {
|
||
|
di as err `"`lhs' not allowed in addscalars()"'
|
||
|
exit 198
|
||
|
}
|
||
|
if "`replace'"=="" {
|
||
|
if `:list lhs in elist' {
|
||
|
di as err `"e(`lhs') already defined"'
|
||
|
exit 110
|
||
|
}
|
||
|
}
|
||
|
gettoken rhs rest: rest, bind
|
||
|
capt eret scalar `lhs' = `rhs'
|
||
|
if _rc {
|
||
|
di as err `"addscalars() invalid"'
|
||
|
exit 198
|
||
|
}
|
||
|
capture local result = e(`lhs')
|
||
|
di as txt "(e(" as res `"`lhs'"' as txt ") = " ///
|
||
|
as res `result' as txt " added)"
|
||
|
if `"`rest'"'=="" continue, break
|
||
|
}
|
||
|
}
|
||
|
// add e(cmd) if missing
|
||
|
if `"`e(cmd)'"'=="" {
|
||
|
if `"`: e(scalars)'`: e(macros)'`: e(matrices)'`: e(functions)'"'!="" {
|
||
|
eret local cmd "."
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// store estimates with e(sample)
|
||
|
estimates store `name' , `copy' `title'
|
||
|
|
||
|
// remove e(sample) if -noesample- specified
|
||
|
if "`esample'"!="" {
|
||
|
capt confirm new var _est_`name'
|
||
|
if _rc {
|
||
|
tempname hcurrent
|
||
|
_est hold `hcurrent', restore estsystem nullok
|
||
|
qui replace _est_`name' = . in 1
|
||
|
_est unhold `name'
|
||
|
capt confirm new var _est_`name'
|
||
|
if _rc qui drop _est_`name'
|
||
|
else {
|
||
|
di as error "somethings wrong; please contact author of -eststo- " ///
|
||
|
"(see e-mail in help {help eststo})"
|
||
|
exit 498
|
||
|
}
|
||
|
_est hold `name', estimates varname(_est_`name')
|
||
|
// varname() only needed so that _est hold does not return error
|
||
|
// if variable `name' exists
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// report
|
||
|
if "`refresh'"=="" {
|
||
|
global eststo `names' `name'
|
||
|
global eststo_counter `counter'
|
||
|
if `"`namelist'"'=="" {
|
||
|
di as txt "(" as res "`name'" as txt " stored)"
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if `"`namelist'"'=="" {
|
||
|
di as txt "(" as res "`name'" as txt " refreshed)"
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
|
||
|
program ParseAddscalars
|
||
|
syntax anything [ , Replace ]
|
||
|
c_local rest `"`anything'"'
|
||
|
c_local replace `replace'
|
||
|
end
|