📄 tssmooth.ado
字号:
*! version 1.3.5 22mar2004
program define tssmooth, sortpreserve rclass
version 8.0
/* syntax
* tssmooth smoother [type] newvarname = exp [if] [in] , options
*/
gettoken new left : 0, parse("=")
/* left contains = exp [if] [in] , options */
gettoken sm new : new
/* sm contains smoother, new contains [type] newvarname */
local 0 ", `sm'"
capture syntax , [Ma nl Exponential Dexponential Hwinters Shwinters]
if _rc > 0 {
di as err "`sm' is not a valid smoother"
exit 198
}
if "`ma'`nl'`exponential'`dexponential'`hwinters'`shwinters'" /*
*/ == "" {
di as err "Smoother not found"
exit 198
}
/* save off any current e() results */
tempvar esamp
tempname pest
_estimates hold `pest', copy restore nullok varname(`esamp')
cknew , `new'
local 0 "`left'"
syntax =exp [if] [in] [, *]
local opts ", `options'"
local myexp2 `"`exp'"'
marksample touse, novarlist
tempvar count1
gen long `count1' = (`touse' > 0)
qui count if `count1' >0
local Nobs = r(N)
if r(N) ==0 {
di as err "no observations"
exit 198
}
/* must include check for left in case user omits comma */
if "`new'" == "" | "`left'" == "" {
error 198
}
/* check that data is tsset */
qui tsset
local tvar `r(timevar)'
if "`r(panelvar)'" != "" {
local pvar "`r(panelvar)'"
local panel "panel"
qui sum `pvar' if `touse'
if r(min) < r(max) {
local byp " by `pvar' : "
}
else {
local panelp = r(min)
local panelp "panelp(`panelp') "
}
}
qui sort `pvar' `tvar'
qui `byp' replace `count1' = sum(`count1')
qui `byp' replace `count1' = `count1'[_N]
if "`pvar'" == "" {
qui sum `count1'
local Nobs2 = int(r(max)/2)
}
else {
qui xtsum `count1'
local Nobs2 = int(r(max)/2)
}
/* create old from expression */
tempvar old tousef
qui`byp' gen double `old' `myexp2' if `touse'
label variable `old' `"`myexp2'"'
qui tsreport if `touse', panel
local pgaps = r(N_gaps)
qui tsreport if `touse'
local gaps = r(N_gaps)
if `pgaps' != `gaps' & "`nl'" != "" {
di as err "tssmooth , nl() does not work with more" /*
*/ " than one panel in a sample"
exit 198
}
/* parse out replace if present
*
*/
local 0 " `opts'"
syntax [, replace *]
/* check for type
* n=1 => name only set type to float
* n=2 => type specified
* n>2 => syntax error
*/
local n : word count `new'
if `n' == 1 {
local nname "`new'"
local new "float `new'"
}
if `n' == 2 {
tokenize `new'
local nname "`2'"
}
if `n' > 2 {
capture drop `old'
error 198
}
if "`replace'" == "" {
confirm new variable `nname'
}
else {
capture drop `nname'
}
/* local new now contains type
* and local nname contains name of new variable
*/
local 0 " `opts'"
syntax , [ Forecast(numlist min=1 max=1 >=0 <=500) * ]
if "`forecast'" != "" {
myadd `old' if `touse', fcast(`forecast') `panelp'
}
/* define tousef = forecasting sample */
gen byte `tousef'=cond(`touse'<.,`touse',1)
/* update touse = estimation sample, excludes observations added
* for forecasting
*/
qui replace `touse' = 0 if `touse' >=.
/* now parse each smoother and call work program */
if "`ma'" != "" {
local 0 " `opts'"
syntax , [ Window(numlist integer min=1 max=3 >=0 <=`Nobs2')/*
*/ WEights(string) replace]
if "`window'" != "" & "`weights'" != "" {
di as err "specify either window() or weights(), not "/*
*/ "both"
exit 198
}
if "`window'`weights'" == "" {
di as err "either window() or weights() must be "/*
*/ "specified"
exit 198
}
if "`window'" != "" {
local wels : word count `window'
tokenize `window'
if `wels' < 1 {
di as error "window(`window') invalid"
exit 198
}
if `wels' > 3 {
di as error "window(`window') invalid"
exit 198
}
if `wels' == 1 {
local bt `1'
local a0 0
local ft 0
}
if `wels' == 2 {
local bt `1'
local a0 `2'
local ft 0
}
if `wels' == 3 {
local bt `1'
local a0 `2'
local ft `3'
}
if `a0' < 0 | `a0' > 1 {
di as err "coefficient on x(t) specified " /*
*/ "in window() is neither 0 nor 1"
di as err "window(`window') invalid"
exit 198
}
local lbl "`a0'*x(t)"
local terms `a0'
forvalues i = 1/`bt' {
local back "`back' 1 "
local lbl "x(t-`i') + `lbl'"
}
if `bt' >= 1 {
local backward "backward(`back')"
}
else {
local backward
}
forvalues i = 1/`ft' {
local forw "`forw' 1 "
local lbl "`lbl' + x(t+`i')"
}
if `ft' >= 1 {
local forward " forward(`forw') "
}
else {
local forward
}
local terms = `a0' + `bt' + `ft'
local lbl "(1/`terms')*[`lbl']"
local lblen : length local lbl
if `lblen' > 80 {
local lbl0 = "`lbl'"
trs2space, s0("`lbl0'")
local lbl0 "`s(string)'"
local lbl0 "`lbl0' ..."
}
else {
local lbl0 "`lbl'"
}
local lbl "`byp'`lbl'; x(t)`myexp2'"
local lbl0 "`byp'`lbl0'; x(t)`myexp2'"
_tsma `new' `old' , `backward' a0(`a0') /*
*/ `forward' touse(`touse')
ret add
di as txt "The smoother applied was"
di as res "{p 5 5 5}`lbl0'"
char `nname'[tssmoother] `lbl'
local lbl2 "ma: x(t)`myexp2': window(`window')"
label variable `nname' "`lbl2'"
local myexp2 : subinstr local myexp2 "= " ""
local myexp2 : subinstr local myexp2 "=" ""
ret local exp "`myexp2'"
exit
}
/* below is the weights section */
/* begin parse weights*/
local tmp : subinstr local weights "<" "<", count(local bc)
if `bc' != 1 {
di as err "missing < in weights()"
di as err "weights(`weights') invalid"
exit 198
}
local tmp : subinstr local weights ">" ">", count(local bc)
if `bc' != 1 {
di as err "missing > in weights()"
di as err "weights(`weights') invalid"
exit 198
}
gettoken num1 lefta : weights , parse("<")
if "`num1'" != "<" {
local left "`lefta'"
capture numlist "`num1'", max(`Nobs2')
if _rc > 0 {
di as err "First numlist in " /*
*/ "weights(`weights') invalid"
exit 198
}
local back "`r(numlist)'"
}
else {
local left "`weights'"
local back
}
gettoken b1 left : left , parse("<")
gettoken a0 left : left , parse(">")
capture confirm number `a0'
if _rc > 0 {
di as err "coefficient for x(t) in " /*
*/ "weights(`weights') invalid"
exit 198
}
gettoken b2 num2 : left , parse(">")
if "`num2'" != "" {
capture numlist "`num2'" , max(`Nobs2')
if _rc > 0 {
di as err "Second numlist in "/*
*/ "weights(`weights') invalid"
exit 198
}
local forw "`r(numlist)'"
}
else {
local forw
}
/* end parse weights*/
local lbl "`a0'*x(t)"
local terms `a0'
local bcnt : word count `back'
local i 1
foreach b of local back {
local j = `bcnt' - `i' + 1
local bi : word `j' of `back'
local lbl "`bi'*x(t-`i') + `lbl'"
local terms = `terms' + `b'
local i = `i' + 1
}
local backward "backward(`back')"
local i 1
foreach ft of local forw {
local lbl "`lbl' + `ft'*x(t+`i')"
local terms = `terms' + `ft'
local i = `i' + 1
}
local forward " forward(`forw') "
if abs(`terms') < 1e-7 {
di as err "coefficients in weights() sum to zero"
exit 198
}
local lbl "(1/`terms')*[`lbl']"
local lblen : length local lbl
if `lblen' > 80 {
local lbl0 = "`lbl'"
trs2space, s0("`lbl0'")
local lbl0 "`s(string)'"
local lbl0 "`lbl0' ..."
}
else {
local lbl0 "`lbl'"
}
local lbl0 "`byp'`lbl0'; x(t)`myexp2'"
local lbl "`byp'`lbl'; x(t)`myexp2'"
_tsma `new' `old' , `backward' a0(`a0') /*
*/ `forward' touse(`touse')
ret add
di as txt "The smoother applied was"
di as res "{p 5 5 5}`lbl0'"
char `nname'[tssmoother] `lbl'
local lbl2 "ma: x(t)`myexp2': weights(`weights')"
label variable `nname' "`lbl2'"
ret local timevar `tvar'
ret local panelvar `pvar'
local myexp2 : subinstr local myexp2 "= " ""
local myexp2 : subinstr local myexp2 "=" ""
ret local exp "`myexp2'"
ret local method "ma"
exit
}
if "`nl'" != "" {
local 0 " `opts'"
syntax , [ SMoother(string) replace]
_ts_nlsmooth `new' `old' , smoother(`smoother') touse(`touse')
ret add
local lbl "nl: x(t)`myexp2': smoother(`smoother')"
char `nname'[tssmoother] `lbl'
label variable `nname' "`lbl'"
ret local timevar `tvar'
ret local panelvar `pvar'
ret local smoother "`smoother'"
ret local method "nl"
exit
}
if "`exponential'" != "" {
local 0 " `opts'"
syntax , [ Parms(numlist max=1 >0 <1) /*
*/ SAmp0(numlist max=1 >1 <=`Nobs' integer) /*
*/ s0(numlist max=1 ) /*
undocumented */ noDIsplay /*
*/ Forecast(numlist max=1 >=0 <=500 integer ) /*
*/ replace /*
*/ ]
if "`parms'" != "" & "`nls'" != "" {
di as err "specify parms() or nls, not both"
exit 198
}
if "`samp0'" != "" & "`s0'" != "" {
di as err "specify samp0() or s0(), not both"
exit 198
}
if "`samp0'" != "" {
local s0samp "s0samp(`samp0')"
}
if "`s0'" != "" {
local s10 "s10(`s0')"
}
if "`forecast'" != "" {
local fcast "fcast(`forecast')"
}
if "`parms'" != "" {
qui gen `new'=.
capture noi `byp' _ts_exp `new' `old', /*
*/ a(`parms') `s0samp' touse(`touse') /*
*/ `fcast' `s10' `display'
ret add
if _rc > 0 {
local rc = _rc
capture drop `nname'
exit `rc'
}
ret local timevar `tvar'
ret local panelvar `pvar'
local myexp2 : subinstr local myexp2 "= " ""
local myexp2 : subinstr local myexp2 "=" ""
ret local exp "`myexp2'"
ret local method "exponential"
exit
}
/* if here then opt via bi-section assumed */
qui gen `new'=.
capture noi `byp' _ts_exp `new' `old', a(opt) /*
*/ `s0samp' touse(`touse') `fcast' /*
*/ `s10' `display'
ret add
if _rc > 0 {
local rc = _rc
capture drop `nname'
exit `rc'
}
local lbl : var label `nname'
char `nname'[tssmoother] `lbl'
ret local timevar `tvar'
ret local panelvar `pvar'
local myexp2 : subinstr local myexp2 "= " ""
local myexp2 : subinstr local myexp2 "=" ""
ret local exp "`myexp2'"
ret local method "exponential"
exit
}
if "`dexponential'" != "" {
local 0 " `opts'"
syntax , [ Parms(numlist max=1 >0 <1) /*
*/ SAmp0(numlist max=1 >1 <=`Nobs' integer ) /*
*/ s0(numlist min=2 max=2 ) /*
undocumented */ noDIsplay /*
*/ Forecast(numlist max=1 >=0 <=500 integer ) /*
undocumented */ fcomp /*
*/ replace]
/* fcomp forces
* dexponential to compute
* the forecasted series instead
* of the smoothed series
*/
if "`parms'" != "" & "`nls'" != "" {
di as err "specify parms() or nls, not both"
exit 198
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -