** This version implements the Loops In MATA!! ** will try to estimate it with local mata matrix mata:mata clear capture program drop vc_predict program vc_predict, rclass sortpreserve syntax varlist(numeric fv) [if] [in], [vcoeff(varname) bw(real -1) yhat(str) looe(str) res(str) lvrg(str) nobs(str) /// knots(real -1) km(real 1) vcoeff_par(varname) sample(varname) kernel(str) stest nstat ] tokenize `varlist' local y `1' //get the rest of the vars macro shift local varx `*' * confirming IF the variables exist ** foreach i in `yhat' `looe' `res' `lvr' `nobs' { confirm new var `i' } ** Defines Sample, Works with and in addition to IF marksample touse markout `touse' `sample' `varlist' `vcoeff' * sort `touse' ********************************************* ** checking if vcoeff was defined or using "system" if "`vcoeff'"=="" & "$vcoeff_"=="" { display "Need to define vcoeff. variable for varying coefficients" exit } *** this uses system if "`vcoeff'"=="" & "$vcoeff_"!="" { local vcoeff $vcoeff_ } local full_x `vcoeff' ** Defining the running variable. Or the Bins if `knots'>=0 { tempvar _kn qui:egen `_kn'=vbin(`vcoeff') if `touse', knot(`knots') km(`km') local par_x `_kn' } else { if "`vcoeff_par'"=="" { local par_x `vcoeff' } else { local par_x `vcoeff_par' } } ** For future applications that will incorporate Sampling Weights local sweight 1 if "`weight'"!="" { local sweight `weight' } ** Uses Kernel Saved in memory if "$kernel_"!="" & "`kernel'"=="" { local kernel "$kernel_" } if "$kernel_"=="" & "`kernel'"=="" { local kernel gaussian } ** as well as BW if "$opbw_"!="" & `bw'==-1 { local bw $opbw_ } ** tempvar err lvr ** Here is where I will modify the data ** First order it by parx and touse, and create a touse2 tempvar touse2 qui:replace `touse'=. if `touse'==0 qui:bysort `touse' `par_x':gen byte `touse2'=(_n==1)*(`touse'==1) qui:replace `touse'=0 if `touse'==. ** for now we are assuming there are no collinearity problems local fvarx= "`full_x' `varx' c.`full_x'#c.(`varx')" ** need to learn to put them as locals rather than globals tempvar Nobs looerr lev xb /* mata:y = st_data(., "`y'","`touse'") mata:x = st_data(., "`fvarx'","`touse'") mata:x = x,J(rows(x),1,1) mata:fvc= st_data(., "`full_x'","`touse'") mata:pvc= st_data(., "`par_x'","`touse'") mata:vc = st_data(., "`par_x'","`touse2'") mata:bw = `bw' mata:krn= "`kernel'" ** This does regression*/ mata:cvreg2("`y'","`fvarx'","`full_x'","`par_x'","`touse'","`touse2'", /// `bw',"`kernel'","`looerr'","`lev'","`xb'","`Nobs'") ** Final results /*this is where the code for within regressions will go*/ *qui:mata:cvreg2("`looerr'","`lev'","`xb'","`Nobs'") if "`nstat'"=="" { tempvar ssx qui:gen double `ssx'=(`y'-`xb')^2 qui: sum `ssx' if `touse'==1 [aw=`sweight'],meanonly local ssr=r(sum) qui: sum `y' if `touse'==1 [aw=`sweight'],meanonly local mmn=r(mean) qui: replace `ssx'=(`y'-r(mean))^2 qui: sum `ssx' if `touse'==1 [aw=`sweight'], meanonly local sst=r(sum) local r2a=1-`ssr'/`sst' *** r2b Henderson Parmeter 2015 qui:replace `ssx'=(`y'-`mmn')*(`xb'-`mmn') if `touse' qui:sum `ssx' if `touse'==1 [aw=`sweight'], meanonly local r2n=r(sum)^2 qui:replace `ssx'=(`xb'-`mmn')^2 if `touse' qui:sum `ssx' if `touse'==1 [aw=`sweight'], meanonly local sse=r(sum) local r2b=r(sum)^2/(`sst'*`sse') tempvar looerrcv qui:gen double `looerrcv'=`looerr'^2 qui:sum `looerrcv' if `touse'==1 [aw=`sweight'], meanonly local cvv=log(r(mean)) qui: sum `lev' if `touse'==1 [aw=`sweight'], meanonly ** This is basically tr(S). We wil use HT1990 and use the approximation for tr(2S-S'S) local dof=1.25*r(sum)-0.5 local dof2=`r(N)'-`dof' local dofm=r(sum) *** To display R2 of Model display as text "Smooth Varying coefficients model" display as text "Dep variable : " as result "`y'" display as text "Indep variables : " as result "`varx'" display as text "Smoothing variable : " as result "`vcoeff'" display as text "Kernel : " as result "`kernel'" if `knots'!=-2 & `knots'!=-1 { display as text "Bin specification : " as result "knots(`knots') km(`km')" } display as text "Bandwidth : " as result %10.5f `bw' display as text "Log MSLOOER : " as result %10.5f `cvv' display as text "Dof residual : " as result %10.3f `dof2' display as text "Dof model : " as result %10.3f `dofm' display as text "SSR : " as result %10.3f `ssr' display as text "SSE : " as result %10.3f `sse' display as text "SST : " as result %10.3f `sst' display as text "R2-1 1-SSR/SST : " as result %10.5f `r2a' display as text "R2-2 : " as result %10.5f `r2b' qui:sum `Nobs' if `touse' local ekobs=r(mean) display as text "E(Kernel obs) : " as result %10.3f `ekobs' *This only runs if nstat=="" if "`stest'"!="" { display _n display as text "Specification Test approximate F-statistic" display as text "H0: Parametric Model" display as text "H1: SVCM y=x*b(z)+e" display as text "Alternative parametric models:" qui:reg `y' `varx' `full_x' [iw=`sweight'] if `touse'==1 local N=e(N) local sm1= e(rss) local df1=e(df_m) local F1_stat=(`sm1'-`ssr')/`ssr'*((`N'-`dof')/(`dof'-`df1')) qui:reg `y' `varx' c.`full_x' c.(`varx')#c.`full_x' [iw=`sweight'] if `touse'==1 local sm2= e(rss) local df2=e(df_m) local F2_stat=(`sm2'-`ssr')/`ssr'*((`N'-`dof')/(`dof'-`df2')) qui:reg `y' `varx' c.`full_x'##c.`full_x' c.(`varx')#(c.`full_x'##c.`full_x') [iw=`sweight'] if `touse'==1 local sm3= e(rss) local df3=e(df_m) local F3_stat=(`sm3'-`ssr')/`ssr'*((`N'-`dof')/(`dof'-`df3')) qui:reg `y' `varx' c.`full_x'##c.`full_x'##c.`full_x' c.(`varx')#(c.`full_x'##c.`full_x'##c.`full_x') [iw=`sweight'] if `touse'==1 local sm4= e(rss) local df4=e(df_m) local F4_stat=(`sm4'-`ssr')/`ssr'*((`N'-`dof')/(`dof'-`df4')) display as text "Model 0 y=x*b0+g*z+e" display as result "F-Stat: " %7.5f `F1_stat' " with pval " %6.5f Ftail(`dof'-`df1',`N'-`dof',`F1_stat') display as text "Model 1 y=x*b0+g*z+(z*x)b1+e" display as result "F-Stat: " %7.5f `F2_stat' " with pval " %6.5f Ftail(`dof'-`df2',`N'-`dof',`F2_stat') display as text "Model 2 y=x*b0+g*z+(z*x)*b1+(z^2*x)*b2+e" display as result "F-Stat: " %7.5f `F3_stat' " with pval " %6.5f Ftail(`dof'-`df3',`N'-`dof',`F3_stat') display as text "Model 3 y=x*b0+g*z+(z*x)*b1+(z^2*x)*b2+(z^3*x)*b3+e" display as result "F-Stat: " %7.5f `F4_stat' " with pval " %6.5f Ftail(`dof'-`df4',`N'-`dof',`F4_stat') return scalar F1_stat=`F1_stat' return scalar pva_F1=Ftail(`dof'-`df1',`N'-`dof',`F1_stat') return scalar F2_stat=`F2_stat' return scalar pva_F2=Ftail(`dof'-`df2',`N'-`dof',`F2_stat') return scalar F3_stat=`F3_stat' return scalar pva_F3=Ftail(`dof'-`df3',`N'-`dof',`F3_stat') return scalar F4_stat=`F4_stat' return scalar pva_F4=Ftail(`dof'-`df4',`N'-`dof',`F4_stat') } return scalar mslooe=`cvv' return scalar dof_r=`dof2' return scalar dof_m=`dofm' return scalar ssr=`ssr' return scalar sse=`sse' return scalar sst=`sst' return scalar r2_1=`r2a' return scalar r2_2=`r2b' } *** To display CV. For now lets just GET CV and save it in the other site *mata:mata drop x y bw vc fvc pvc krn if "`yhat'"!="" ren `xb' `yhat' if "`looe'"!="" ren `looerr' `looe' if "`lvrg'"!="" ren `lev' `lvrg' if "`res'"!="" gen `res'=`y'-`xb' if "`nobs'"!="" ren `Nobs' `nobs' display "`nobs'" *** Return section Return all outputs! end mata: void cvreg( string scalar nloerr,string scalar lev,string scalar xbhat) { external x,y,w n = rows(y) ixwx=invsym(quadcross(x,w,x)) xwy=quadcross(x,w,y) wx=sqrt(w):*x tr=rowsum(wx*ixwx:*wx) tr2=(tr:*-1):+1 yhat=x*ixwx*xwy loerr=(y-yhat):/tr2 st_addvar("double",nloerr) st_store((1,n),nloerr,loerr) st_addvar("double",lev) st_store((1,n),lev,tr) st_addvar("double",xbhat) st_store((1,n),xbhat,yhat) } void cvreg2(string scalar depvar, string scalar indepvar, string scalar fcsvar, string scalar pcsvar, string scalar touse , string scalar touse2, real scalar bw, string scalar krn, string scalar nloerr,string scalar nlev,string scalar nyhat, string scalar nobs) { real matrix y,x ,fvc,pvc,vc y=st_data(.,depvar,touse) x=st_data(.,indepvar,touse) x=x,J(rows(x),1,1) fvc= st_data(., fcsvar,touse) pvc= st_data(., pcsvar,touse) vc = st_data(., pcsvar,touse2) // external y,x,fvc,bw, pvc, vc // external krn // which kernel? if (krn=="gaussian") k=1 else if (krn=="epan") k=2 else if (krn=="epan2") k=3 else if (krn=="biweight") k=4 else if (krn=="cosine") k=5 else if (krn=="cosine2") k=6 else if (krn=="parzen") k=7 else if (krn=="rectan") k=8 else if (krn=="trian") k=9 else if (krn=="logistic") k=10 else if (krn=="tricube") k=11 else if (krn=="triweight") k=12 n = rows(y) yhat2 =J(rows(y),1,0) loerr2=J(rows(y),1,0) lev2 =J(rows(y),1,0) nnobs =J(rows(y),1,0) for(i=1;i<=rows(vc);i++) { /// point of reference z=(fvc:-vc[i]):/bw /// kernel weight w=kweight(z,1) /// elements of the OLS ixwx=invsym(quadcross(x,w,x)) xwy=quadcross(x,w,y) /// leverage Stat lrv=quadrowsum((x*ixwx):*(x:*w)) /// This info is to be stored yhat=x*(ixwx*xwy) loerr=(y-yhat):/((lrv:*-1):+1) lev2 =lev2+lrv:*(pvc:==vc[i]) yhat2 =yhat2+yhat:*(pvc:==vc[i]) loerr2=loerr2+loerr:*(pvc:==vc[i]) nnobs=nnobs+(J(rows(y),1,0):+quadsum(w)):*(pvc:==vc[i]) } st_addvar("double",nloerr) st_store(.,nloerr,touse,loerr2) st_addvar("double",nlev) st_store(.,nlev,touse,lev2) st_addvar("double",nyhat) st_store(.,nyhat,touse,yhat2) st_addvar("double",nobs) st_store(.,nobs,touse,nnobs) } real matrix kweight(real matrix z,real scalar k) { if (k==1) { kz=normalden(z):/normalden(0) } else if (k==2) { kz=(-0.2*(z:^2):+1):*(abs(z):<(5^.5)) } else if (k==3) { kz= (-z:^2:+1):*(abs(z):<1) } else if (k==4) { kz=(-z:^2:+1):^2:*(abs(z):<1) } else if (k==5) { kz=(cos(2*pi()*z):+1):/2:*(abs(z):<0.5) } else if (k==6) { kz=cos(pi()/2*z):*(abs(z):<1) } else if (k==7) { kz=((-6*z:^2+6*abs(z):^3):+1):*(abs(z):<=0.5)+(-abs(z):+1):^3:*2:*((abs(z):>0.5):*(abs(z):<=1)) } else if (k==8) { kz=abs(z):<=1 } else if (k==9) { kz=(-abs(z):+1):*(abs(z):<=1) } else if (k==10) { kz=(exp(z)+exp(z:*-1):+2):^-1:*4 } else if (k==11) { kz=(-abs(z):^3:+1):^3:*(abs(z):<1) } else if (k==12) { kz=(-abs(z):^2:+1):^3:*(abs(z):<1) } return(kz) } end