*!V1.2 Zihou,Chen etc. *!data: 21 Mar 2022 *!V1.0 Zihou,Chen etc. *! data: 29 Apr 2021 *! Party School of the Guangdong Provincial Committee of CPC,China ** The command is based upon commands( spatgsa and spatlsa ) originally written by Maurizio Pisati,thanks! program define xtmoran, rclass version 11.0 syntax varname(min = 1 max=1), Wname(string) /* */ [Morani(numlist)] /* */ [GRaph] /* */ [SYmbol(varname)] local vvcheck = max(11,c(stata_version)) if `vvcheck' < 11{ di as err "it cannot run version `vvcheck' programs" exit } _xt, trequired local id: char _dta[_TSpanel] local time: char _dta[_TStvar] cy using "`wname'",name(wcname) capture qui matrix list wcname if _rc==111 { di as err "Matrix file `weights' does not exist" exit } local weights wcname local ROWNAME : rownames(`weights') local COLNAME : colnames(`weights') local WTYPE : word 1 of `ROWNAME' local WBINA : word 2 of `ROWNAME' local WSTAN : word 3 of `ROWNAME' qui { preserve keep `id' `time' `varlist' reshape wide `varlist' ,i(`id') j(`time') local N=_N restore local DIM=rowsof(`weights') } if `DIM'!=`N' { di as err "Matrix `weights' is `DIM'x`DIM', the dataset using on the cross section has `N' obs." di as err "To run -xtmoran- weights matrix dimension must equal N. of obs" exit } local W="`weights'" local tc=_N/`N' local NVAR `tc' tempname cname MORAN matrix `cname'=J(`tc',1,0) local k2=1 local yearz=`time' while `k2'<=`tc' { local yearc =`yearz'+`k2'-1 matrix `cname'[`k2',1]=`yearc' local k2=`k2'+1 } local MULT=2 local PVL "*`MULT'-tail test" preserve keep `id' `time' `varlist' qui reshape wide `varlist' ,i(`id') j(`time') local kk=1 local aa `varlist' while `kk'<=`NVAR' { local tvarc=`cname'[`kk',1] tempname m2 m4 b2 M matrix `m2'=J(`NVAR',1,0) matrix `m4'=J(`NVAR',1,0) matrix `b2'=J(`NVAR',1,0) matrix `M'=J(`NVAR',4,0) local k=1 //Prepare for the next update tempname zc mkmat `aa'`tvarc', matrix(`zc') svmat `zc',name(zc`kk') local VAR zc`kk'1 local j=1 while `j'<=4 { tempvar TEMP qui generate `TEMP'=`VAR'^`j' qui summ `TEMP', mean matrix `M'[`k',`j']=r(sum) local j=`j'+1 } qui summ `VAR', mean local MEAN=r(mean) qui replace `VAR'=`VAR'-`MEAN' tempvar Vm2 Vm4 qui generate `Vm2'=`VAR'^2 qui summ `Vm2', mean matrix `m2'[`k',1]=r(mean) local m2k=r(mean) qui generate `Vm4'=`VAR'^4 qui summ `Vm4', mean matrix `m4'[`k',1]=r(mean) local m4k=r(mean) matrix `b2'[`k',1]=`m4k'/(`m2k'^2) tempname Z mkmat zc`kk'1, matrix(`Z') local S0=0 local S1=0 local S2=0 local i=1 while `i'<=`N' { local wi=0 local wj=0 local j=1 while `j'<=`N' { local S0=`S0'+`W'[`i',`j'] local S1=`S1'+(`W'[`i',`j']+`W'[`j',`i'])^2 local wi=`wi'+`W'[`i',`j'] local wj=`wj'+`W'[`j',`i'] local j=`j'+1 } local S2=`S2'+(`wi'+`wj')^2 local i=`i'+1 } local S1=`S1'/2 tempname MORAN matrix `MORAN'=J(`NVAR',5,0) matrix colnames `MORAN'=stat mean sd z p-value local m2k=`m2'[`k',1] local b2k=`b2'[`k',1] tempname Zk matrix `Zk'=`Z'[1...,`k'] matrix `Zk'=`Zk''*`W'*`Zk' local stat=`Zk'[1,1]/(`S0'*`m2k') matrix `MORAN'[`k',1]=`stat' local E=-1/(`N'-1) matrix `MORAN'[`k',2]=`E' local NUM1=`N'*( (`N'^2-3*`N'+3)*`S1' - (`N'*`S2') + (3*`S0'^2) ) local NUM2=`b2k'*( (`N'^2-`N')*`S1' - (2*`N'*`S2') + (6*`S0'^2) ) local DEN=(`N'-1)*(`N'-2)*(`N'-3)*(`S0'^2) local sd=(`NUM1'-`NUM2')/`DEN' - (1/(`N'-1))^2 local sd=sqrt(`sd') matrix `MORAN'[`k',3]=`sd' local z=(`stat'-`E')/`sd' matrix `MORAN'[`k',4]=`z' local pval=(1-normprob(abs(`z')))*`MULT' matrix `MORAN'[`k',5]=`pval' mat mczh`kk'=`MORAN' local kk=`kk'+1 } tempname CC mat `CC'=J(`tc',5,0) local kck=1 while `kck'<=`NVAR' { local kckk=1 while `kckk'<= 5 { mat `CC'[`kck',`kckk']=mczh`kck'[1,`kckk'] local kckk=`kckk'+1 } local kck=`kck'+1 } restore local kckp=1 while `kckp'<=`NVAR' { mat drop mczh`kckp' local kckp =`kckp'+1 } di _newline di as txt "{bf:{err:Welcome to use this command to calculate the Moran's I}}" local ncz=_N dis "" di as res "{title:The results :}" _dispcc "`CC'" "Moran's I" "I" "`cname'" "`id'" "`time'" "`ncz'" /* */ "`N'" "`NVAR'" "`varlist'" *return matrix moran `CC' di as txt "`PVL'" di _newline if "`morani'"!="" { if "`symbol'"=="" { local ID=1 } if "`symbol'"!="" { local TEMP : type `symbol' local TEMP=substr("`TEMP'",1,3) if "`TEMP'"=="str" { local ID=2 } else { local TEMP : value label `symbol' if "`TEMP'"!="" { local ID=3 } else { local ID=4 } } } preserve keep `id' `time' `varlist' qui reshape wide `varlist' ,i(`id') j(`time') local N=_N restore preserve keep `id' `time' `varlist' `symbol' qui reshape wide `varlist' ,i(`id') j(`time') local aca `varlist' foreach varlistc of numlist `morani' { tempname zcx mkmat `aca'`varlistc', matrix(`zcx') svmat `zcx',name(zcx`varlistc') local varlistcx zcx`varlistc'1 tempname M matrix `M'=J(1,4,0) local j=1 while `j'<=4 { tempvar TEMP qui generate `TEMP'=zcx`varlistc'1^`j' qui summ `TEMP', mean matrix `M'[1,`j']=r(sum) local j=`j'+1 } qui summ zcx`varlistc'1, mean local MEAN=r(mean) qui replace zcx`varlistc'1=zcx`varlistc'1-`MEAN' tempvar Vm2 Vm4 qui generate `Vm2'=zcx`varlistc'1^2 qui summ `Vm2', mean local m2=r(mean) qui generate `Vm4'=zcx`varlistc'1^4 qui summ `Vm4', mean local m4=r(mean) local b2=`m4'/(`m2'^2) tempname Z mkmat zcx`varlistc'1, matrix(`Z') tempname Wi Wi2 local N=_N local W="`weights'" matrix `Wi'=J(`N',1,0) matrix `Wi2'=J(`N',1,0) local i=1 while `i'<=`N' { local wi=0 local wi2=0 local j=1 while `j'<=`N' { local w=`W'[`i',`j'] local wi=`wi'+`w' local wi2=`wi2'+`w'^2 local j=`j'+1 } matrix `Wi'[`i',1]=`wi' matrix `Wi2'[`i',1]=`wi2' local i=`i'+1 } tempname MORAN cz cq matrix `MORAN'=J(`N',6,0) matrix `cz'=J(`N',1,0) matrix colnames `MORAN'=stat mean sd z p-value quadrant tempvar Yc qui egen `Yc'=std(zcx`varlistc'1) tempname yc Wyc mkmat `Yc', matrix(`yc') matrix `Wyc'=`W'*`yc' svmat `Wyc', n(_Wyc) qui gen zcx`varlistc'1quadrant=_N local leix zcx`varlistc'1quadrant qui replace `leix'=1 if `Yc'>0 & _Wyc1>0 qui replace `leix'=3 if `Yc'<0 & _Wyc1<0 qui replace `leix'=4 if `Yc'>0 & _Wyc1<0 qui replace `leix'=2 if `Yc'<0 & _Wyc1>0 mkmat zcx`varlistc'1quadrant, matrix(`cq') qui cap drop zcx`varlistc'1quadrant _Wy* local i=1 while `i'<=`N' { local zi=`Z'[`i',1] local wi=`Wi'[`i',1] local wi2=`Wi2'[`i',1] local SUM=0 local j=1 while `j'<=`N' { local wj=`W'[`i',`j'] local zj=`Z'[`j',1] local SUM=`SUM'+`wj'*`zj' local j=`j'+1 } local stat=(`zi'/`m2')*`SUM' matrix `MORAN'[`i',1]=`stat' local E=(-`wi')/(`N'-1) matrix `MORAN'[`i',2]=`E' local T1=(`wi2'*(`N'-`b2')) / (`N'-1) local T2=((`wi'^2-`wi2')*(2*`b2'-`N')) / ((`N'-1)*(`N'-2)) local T3=((-`wi')/(`N'-1))^2 local sd=`T1'+`T2'-`T3' local sd=sqrt(`sd') matrix `MORAN'[`i',3]=`sd' local z=(`stat'-`E')/`sd' matrix `MORAN'[`i',4]=`z' local pval=(1-normprob(abs(`z')))*2 matrix `MORAN'[`i',5]=`pval' matrix `cz'[`i',1]=`pval' matrix `MORAN'[`i',6]=`cq'[`i',1] local i=`i'+1 } _dispcz "`varlist'`varlistc'" "`MORAN'" "Moran's Ii" "Ii" "`N'" "`ID'" /* */ "`symbol'" return mat morani`varlistc' = `MORAN' di as txt "`PVL'" di _newline if "`graph'"!="" { tempvar Y qui egen `Y'=std(zcx`varlistc'1) tempname y Wy mkmat `Y', matrix(`y') local cyc gr tw matrix `Wy'=`W'*`y' svmat `Wy', n(_Wy) qui summ _Wy1, mean local YL=r(mean) local VARLBL : variable label zcx`varlistc'1 if "`VARLBL'"!="" { local VARLBL=usubstr("`VARLBL'",1,78) } else { local VARLBL="`zcx`varlistc'1'" } qui regress _Wy1 `Y',noconstant *local I=string(_b[`Y'],"%5.4f") local t = _b[`Y']/_se[`Y'] local pcp=2*ttail(e(df_r),abs(`t')) *local II=string(`pcp',"%5.4f") qui summ _Wy1, mean local ymin=int(r(min))-1 local ymax=int(r(max))+1 qui summ `Y', mean local xmin=int(r(min))-1 local xmax=int(r(max))+1 if "`symbol'"=="" { local czhc1 msymbol(Oh) } if "`symbol'"!="" { local czhc1 msymbol(i) local varnamec `symbol' local czhc2 mlabel (`varnamec') local czhc3 mlabsize(*1) } local timecyc = `varlistc'-`yearz' +1 mat CC = r(moran) local I =string(`CC'[`timecyc',1],"%5.4f") local II =string(`CC'[`timecyc',5],"%5.4f") *dis `timecyc' `cyc' (sc _Wy1 `Y' ,`czhc1' `czhc2' `czhc3') /* */ (lfit _Wy1 `Y',estopts(nocons)), yline(0) xline(0) xlabel(`xmin'(1)`xmax') /* */ xtitle(z) ylabel(`ymin'(1)`ymax') ytitle(Wz) /* */ legend(off) scheme(s1mono ) /* */ title("Moran scatterplot (Moran's I = `I' and P-value = `II')", /* */ pos(11) size(medium)) /* */ subtitle("`varlist'`varlistc'", pos(11)) /* */ name(picture`varlistc',replace) } } restore } return scalar N = `N' return scalar T = `tc' return matrix moran `CC' mat drop wcname end program define _dispcc version 11.0 args MAT TITLE L cname idc timec Nc nc tcc namecz local LIST : rownames(`MAT') local NVAR : word count `LIST' di as txt _n "`TITLE' (" as res "varname : `namecz'" as txt ")" _col(40) /* */ "Number of obs " _col(38) "=" as res %7.0g `Nc' di in gr "Group variable: " in ye abbrev("`idc'",12) /* */ in gr _col(37) "Number of groups " _col(4) "=" in ye %7.0g `nc' di in gr "Time variable: " in ye abbrev("`timec'",12) /* */ in gr _col(41) in gr "Panel length " _col(50) "=" in ye %7.0g `tcc' di as txt "{hline 20}{c TT}{hline 41}" di as txt _col(11) " year {c |}" _col(26) "`L'" _col(33) "E(`L')" /* */ _col(40) "Sd(`L')" _col(50) "Z" _col(55) "P-value" di as txt "{hline 20}{c +}{hline 41}" local k=1 while `k'<=`NVAR' { local VAR = `cname'[`k',1] local VAR=abbrev("`VAR'",19) di as txt _col(1) %19s "`VAR'" " {c |}" /* */ as res _col(22) %7.4f `MAT'[`k',1] /* */ as res _col(30) %7.4f `MAT'[`k',2] /* */ as res _col(38) %7.4f `MAT'[`k',3] /* */ as res _col(46) %7.4f `MAT'[`k',4] /* */ as res _col(56) %5.4f `MAT'[`k',5] local k=`k'+1 } di as txt "{hline 20}{c BT}{hline 41}" end program define _dispcz,rclass version 11.0 args VAR MAT TITLE L N ID id VARLBLC preserve tempname STAT matrix `STAT'=`MAT' if "`id'"!="" { local header=abbrev("`id'",42) } else { local header="Location" } di as txt "`TITLE' (" as res "`VAR'" as txt ")" di as txt "{hline 20}{c TT}{hline 50}" di as txt _col(1) %19s "`header'" " {c |}" _col(26) "`L'" /* */ _col(32) "E(`L')" _col(39) "Sd(`L')" _col(50) "Z" /* */ _col(55) "P-value" _col(64) "Quadrant" di as txt "{hline 20}{c +}{hline 50}" local i=1 while `i'<=`N' { if `ID'==1 { local ROW=`TEMP'[`i'] } if `ID'==2 { local ROW=substr(`id'[`i'],1,24) } if `ID'==3 { local INDEX=`id'[`i'] local ROW : label(`id') `INDEX' 24 } if `ID'==4 { local ROW=`id'[`i'] } di as txt _col(1) %19s "`ROW'" " {c |}" /* */ as res %7.4f `STAT'[`i',1] /* */ as res %8.4f `STAT'[`i',2] /* */ as res %8.4f `STAT'[`i',3] /* */ as res %8.4f `STAT'[`i',4] /* */ as res %8.4f `STAT'[`i',5] /* */ as res %8.0f `STAT'[`i',6] local i=`i'+1 } return mat morani = `STAT' di as txt "{hline 20}{c BT}{hline 50}" restore end program define cy version 7.0 syntax [using/], Name(string) /* */ [Standardize] /* */ [Eigenval(string)] confirm name `name' local OUTPUT "The following matrix has been created:" if "`using'"!="" { preserve qui use `"`using'"', clear unab VLIST : _all local NVAR : word count `VLIST' local SUM=0 local i=1 while `i'<=`NVAR' { local VAR : word `i' of `VLIST' qui capture assert `VAR'==0 | `VAR'==1 if _rc!=0 { local SUM=`SUM'+1 } local i=`i'+1 } if `SUM'==0 { local binary "binary" } else { local binary "" } qui egen ROWSUM=rsum(_all) qui count if ROWSUM==0 local NN=r(N) qui drop ROWSUM qui mkmat _all, matrix(_W) restore local NROW=rowsof(_W) local NCOL=colsof(_W) if `NROW'!=`NCOL' { di as err "Matrix is not square" exit } local N=`NROW' if "`binary'"!="" { local WT "Imported binary weights matrix" } else { local WT "Imported non-binary weights matrix" } matrix `name'=_W } if `"`using'"'=="" { local LOWER : word 1 of `band' local UPPER : word 2 of `band' local N=_N matrix _W=J(`N',`N',0) matrix _D=J(`N',`N',0) preserve local MAXOBS=(`N'/2)*(`N'-1) qui set obs `MAXOBS' tempvar DISTAN qui generate `DISTAN'=. local d=1 local i=1 while `i'<=`N' { local j=`i'+1 while `j'<=`N' { local A=(`xcoord'[`i']-`xcoord'[`j'])^2 local B=(`ycoord'[`i']-`ycoord'[`j'])^2 local DIST=sqrt(`A'+`B') qui replace `DISTAN'=`DIST' in `d' matrix _D[`i',`j']=`DIST' matrix _D[`j',`i']=`DIST' if `DIST'>`LOWER' & `DIST'<=`UPPER' { if "`binary'"!="" { matrix _W[`i',`j']=1 matrix _W[`j',`i']=1 } else { matrix _W[`i',`j']=1/(`DIST'^`friction') matrix _W[`j',`i']=1/(`DIST'^`friction') } } local d=`d'+1 local j=`j'+1 } local i=`i'+1 } qui summarize `DISTAN', detail local DMIN=r(min) local DP25=r(p25) local DP50=r(p50) local DP75=r(p75) local DMAX=r(max) qui svmat _D qui for varlist _D* : replace X=. if X==0 qui egen ROWMIN=rmin(_D*) qui summ ROWMIN, mean local MAXMIN=r(max) qui egen ROWMAX=rmax(_D*) qui summ ROWMAX, mean local MINMAX=r(min) matrix drop _D restore preserve qui drop _all qui svmat _W qui egen ROWSUM=rsum(_W*) qui count if ROWSUM==0 local NN=r(N) restore if "`binary'"!="" { local WT "Distance-based binary weights matrix" } else { local WT "Inverse distance weights matrix" } matrix `name'=_W } preserve qui drop _all qui svmat _W qui egen ROWSUM=rsum(_W*) qui for varlist _W* : replace X=X/ROWSUM if ROWSUM!=0 qui mkmat _W*, matrix(_WS) restore matrix `name'=_WS if "`using'"!="" & "`binary'"!="" {local ROW="SWMImpo Yes "} if "`using'"!="" & "`binary'"=="" {local ROW="SWMImpo No "} if "`using'"=="" & "`binary'"!="" {local ROW="SWMDist Yes "} if "`using'"=="" & "`binary'"=="" {local ROW="SWMDist No "} local ROW="`ROW'Yes" matrix rownames `name'=`ROW' if "`using'"=="" { local INT=int(`LOWER') local DEC=`LOWER'-`INT' local DEC=string(`DEC') local COL "`INT' `DEC'" local INT=int(`UPPER') local DEC=`UPPER'-`INT' local DEC=string(`DEC') local COL "`COL' `INT' `DEC'" matrix colnames `name'=`COL' } capture matrix drop _W capture matrix drop _WS end