*! version 1.0.2 31oct2024 I I Bolotov program define xtrevu, rclass version 16.0 /* Reverse the order of values of time series and panel data variables by substituting the original values or by creating new variables with a prefixed identifier. If a "colon" command is provided, an estimation procedure is executed on the inverted variables. The results of this estimation, including predictions, residuals, and others, are stored as either existing variables or new ones. Additionally, a comprehensive post-estimation command can be executed. Author: Ilya Bolotov, MBA, Ph.D. Date: 20 February 2024 */ // syntax if trim(`"`0'"') == "" { di as err "something required" exit 100 } tokenize `"`0'"', parse(":") loc 0 `1' syntax /// varlist [if] [in] [, /// replace PREfix(string) /// Type(string) Xb(string) Residuals(string) Stdp(string) force /// PREestimation(string asis) POSTestimation(string asis) /// ] // adjust and preprocess options if `"`replace'`prefix'"' == "" & trim(`"`3'"') == "" { di as err "must specify either replace/prefix option or a : command" exit 198 } if `"`prefix'"' != "" { qui conf name `prefix' } if `"`xb'`residuals'`stdp'"' != "" { qui conf name `xb' `residuals' `stdp' } foreach var in "`xb'" "`residuals'" "`stdp'" { cap conf var `var', ex if ! _rc & "`var'" != "" & `"`force'"' == "" { di as err "option {bf:force} required for xb(), residuals(), " /// "and stdp() to overwrite existing variables" exit 198 } } tempvar panelvar touse predict tempfile tmpf // invert the value order of xtset data preserve qui xtset if "`r(panelvar)'" != "" loc panelvar `r(panelvar)' else qui g `panelvar' = 1 loc timevar `r(timevar)' qui levelsof `panelvar', l(values) qui g `touse' = . mata: X = . foreach i in `values' { qui replace `touse' = cond(`panelvar' == `i', 1, 0) `if' `in' mata: for (i=1; i<=cols((v = tokens("`varlist'"))); i++) {; /// if (st_isnumvar(v[i])) /// st_view( (x=J(0,0,. )), ., v[i], "`touse'"); /// else st_sview((x=J(0,0,"")), ., v[i], "`touse'"); /// x[.,.] = x[rows(x)..1,.]; /// }; } drop `touse' mata: mata drop i v x /* rename variables */ if `"`prefix'"' != "" { foreach var of varl `varlist' { rename `var' `prefix'`var' } qui ds `=ustrregexra("`varlist'","(^|\s)(.)","$1`prefix'$2",1)' loc varlist `r(varlist)' } // run : command (if specified) if trim(`"`3'"') != "" { `preestimation' di as txt _n " all {bf:lags} should be interpreted as {bf:leads}" /// _n `3' /* run postestimation command/program (= multiple commands) */ `postestimation' cap conf mat e(b) if ! _rc { foreach newvar in "xb" "residuals" "stdp" { if "``newvar''" != "" { qui { predict `type' `predict', `newvar' cap conf var ``newvar'', ex if ! _rc { replace ``newvar'' = `predict' drop `predict' } else rename `predict' ``newvar'' } } } } } // replace/generate new variables qui keep `=cond(! strpos("`panelvar'","_"),"`panelvar'","")' /// `timevar' /// `=cond(`"`replace'`prefix'"'!="", "`varlist'", "")' /// `varlist' `xb' `residuals' `stdp' qui save `tmpf', replace **** restore qui merge 1:1 `=cond(! strpos("`panelvar'","_"),"`panelvar'","")' /// `timevar' using `tmpf', update replace force nogen end