Here's confirmation that even with missing time periods and some missing values for exret, you can match results from the loop by adjusting the interval that rangestat uses. The following does what you requested, that is a recursive interval that excludes the current observation. The interval of the rangestat call that counts the number of non-missing values for exret is also adjusted to use the previous 12 periods.
Code:
* Example generated by -dataex-. To install: ssc install dataex clear input long(obs permno) float(time exret inflation) 1 1470874 1 .9122462 .51331943 2 1470874 2 .5948181 .3065938 3 1470874 3 .25645664 .4921637 4 1470874 4 .930954 .3914094 5 1470874 5 .9577237 .8338873 6 1470874 6 .5671181 .8355323 7 1470874 7 .2708475 .26582384 8 1470874 8 .34942105 .672545 9 1470874 9 .4345023 .5868091 10 1470874 10 .8107689 .23440893 11 1470874 11 .5516335 .29357833 12 1470874 12 .6561857 .9301422 13 1470874 13 .7671857 .04822804 14 1470874 14 .4452506 .09964211 15 1470874 15 .51762706 .8284212 16 1470874 16 .2166194 .13313739 17 1470874 17 .19157566 .3796502 18 1470874 18 .9459305 .7317557 19 1470874 19 .7275512 .0852162 20 1470874 20 .927551 .6083384 21 1470874 21 .4164995 .4719198 22 1470874 29 . .4488523 23 1470874 30 .4370895 .1835875 24 6879153 1 .6476775 .3955551 25 6879153 2 .4472069 .02203239 end * loop, based on Mohammad's single case gen b = . gen n = . local nobs = _N qui forvalues i = 1/`nobs' { count if !mi(exret) & permno == permno[`i'] /// & inrange(time, time[`i']-12, time[`i']-1) if r(N) >= 8 { gen double ww = exp(-(time[`i'] - time) * log(2)/60) /// if permno == permno[`i'] & time < time[`i'] regress exret inflation [aweight=ww] /// if permno == permno[`i'] & time <time[`i'] drop ww replace n = e(N) in `i' replace b = _b[inflation] in `i' } } * --------------- redo using rangestat ---------------------------------------- * precompute number of non-missing observations in the past 12 periods rangestat (count) exret, interval(time -12 -1) by(permno) * define a Mata function for Weighted Least Squares, original OLS Mata code derived from * http://blog.stata.com/2016/01/12/programming-an-estimation-command-in-stata-an-ols-command-using-mata/ * and adapted using the information on * https://www.mathworks.com/help/curvefit/least-squares-fitting.html?requestedDomain=www.mathworks.com mata: mata clear real rowvector mywls(real matrix Xall) { real colvector y, b, w, wy, t real matrix X, XpX, XpXi, wX real scalar n, k, tau y = Xall[.,1] // dependent var is first X = Xall[.,2::cols(Xall)-1] // independent variables t = Xall[.,cols(Xall)] // time variable n = rows(X) // the number of observations X = X,J(n,1,1) // add a constant k = cols(X) // number of independent variables if (n > k) { // need more than k obs to estimate model and standard errors tau = t[rows(t)] w = exp(-(tau :- t) * log(2)/60) wX = w :* X wy = w :* y XpX = quadcross(X, wX) XpXi = invsym(XpX) if (diag0cnt(XpXi) == 0) { b = XpXi * quadcross(X, wy) } } return(rows(X), b') } end gen high = cond(exret_count >= 8, time-1, 0) rangestat (mywls) exret inflation time, interval(time . high) by(permno) casewise gen reg_n = mywls1 gen reg_b = mywls2 assert n == reg_n assert b == reg_b
Comment