*! Version 1.3.0 2024-03-05 *! Author: Dejin Xie (Nanchang University, China) ** Version 1.3.0 2024-03-05, option "norm" Modified ** Version 1.2.0 2022-06-30, option "base" added ** Version 1.1.0 2019-12-15, option "smooth" added ** Version 1.0.0 2018-11-16, the initial version ****** The Entropy Weight Method (EWM) ****** program define ewm, rclass sortpreserve version 13 syntax varlist (numeric) [if] [in], [ Score(string) UNdes(varlist) By(varlist) /// Norm(string) SHift(numlist max=1 min=1 >0 <=1) /// SMooth(numlist max=1 min=1 >0 <1) Raw Pv BAse List Keep ] local VNUM : word count `varlist' tokenize `varlist' tempvar EWMID gen `EWMID'=_n if `c(stata_version)'>=14 { local ustr "ustr" } marksample touse, novarlist if "`score'"=="" { local score "EW_Score" } if "`by'"~="" { local BY_TIME "bysort `by' (`EWMID') :" local TIME_BY ", by(`by')" if "`base'"~="" { tempvar ByBa egen `ByBa'=group(`by') } } else { if "`base'"~="" { dis as err "The option {it:{ul:ba}se} must be set with option {it:{ul:b}y(varlist)}." exit } } if "`shift'"~="" & "`smooth'"~="" { dis as err "option {it:{ul:sh}ift(#)} not allowed with {it:{ul:sm}ooth(#)}." error 198 } if "`raw'"~="" & "`pv'"~="" { dis as err "option {it:raw} not allowed with {it:pv}." error 198 } if "`norm'"~="" { local norm = upper("`norm'") if inlist("`norm'","MM","MX","L1","L2")==0 { dis as error `"The option {it:{ul:n}orm(method)} must be one of "{it:MM}", "{it:MX}", "{it:L1}" or "{it:L2}" !"' exit(198) } if inlist("`norm'","L1","L2") & "`base'"~="" & "`by'"~="" { dis as text "The option {it:{ul:ba}se} is not worked since option {it:{ul:n}orm(`norm')} is set." } } else { local norm "MM" } quietly { capture drop `score' capture drop *_EW capture assert `touse'==1 local TouSeE=!_rc if `TouSeE'==0 { preserve tempfile myEWMfile keep if `touse' } capture drop *_MNRM forvalues vi=1/`VNUM' { tempvar ``vi''_MAXM ``vi''_MINM ``vi''_pc ``vi''_NMS ``vi''_EJ inlist("`norm'","MM","MX") { if "`base'"=="" { `BY_TIME' egen ```vi''_MAXM'=max(``vi'') `BY_TIME' egen ```vi''_MINM'=min(``vi'') } else { sum ``vi'' if `ByBa'==1 gen ```vi''_MAXM'=`r(max)' gen ```vi''_MINM'=`r(min)' } } if "`norm'"=="MM" { if `ustr'regexm("`undes'","(^| )``vi''( |$)") { gen ``vi''_MNRM=(```vi''_MAXM'-``vi'')/(```vi''_MAXM'-```vi''_MINM') } else { gen ``vi''_MNRM=(``vi''-```vi''_MINM')/(```vi''_MAXM'-```vi''_MINM') } if "`shift'"~="" replace ``vi''_MNRM=``vi''_MNRM+`shift' if "`smooth'"~="" replace ``vi''_MNRM=`smooth'+(1-`smooth')*``vi''_MNRM `BY_TIME' egen ```vi''_pc'=pc(``vi''_MNRM), prop } if "`norm'"=="MX" { if `ustr'regexm("`undes'","(^| )``vi''( |$)") { gen ``vi''_MNRM=1-``vi''/```vi''_MAXM' } else { gen ``vi''_MNRM=``vi''/```vi''_MAXM' } if "`shift'"~="" replace ``vi''_MNRM=``vi''_MNRM+`shift' if "`smooth'"~="" replace ``vi''_MNRM=`smooth'+(1-`smooth')*``vi''_MNRM `BY_TIME' egen ```vi''_pc'=pc(``vi''_MNRM), prop } if "`norm'"=="L1" { `BY_TIME' egen ``vi''_MNRM = pc(``vi'') , prop replace ``vi''_MNRM = 1-``vi''_MNRM if `ustr'regexm("`undes'","(^| )``vi''( |$)") gen ```vi''_pc' = ``vi''_MNRM } if "`norm'"=="L2" { tempvar ``vi''_NMQ `BY_TIME' egen ```vi''_NMQ'=total(``vi''^2) replace ```vi''_NMQ'=(```vi''_NMQ')^0.5 gen ``vi''_MNRM=``vi''/```vi''_NMQ' replace ``vi''_MNRM = 1-``vi''_MNRM if `ustr'regexm("`undes'","(^| )``vi''( |$)") `BY_TIME' egen ```vi''_pc'=pc(``vi''_MNRM), prop } `BY_TIME' egen ```vi''_NMS'=count(``vi'') gen ```vi''_EJ'=-```vi''_pc'*ln(```vi''_pc')/ln(```vi''_NMS') capture drop ``vi''_ET `BY_TIME' egen ``vi''_ET=total(```vi''_EJ') } tempvar VENT egen `VENT'=rowtotal(*_ET) forvalues vi=1/`VNUM' { capture drop ``vi''_EW gen ``vi''_EW=(1-``vi''_ET)/(`VNUM'-`VENT') label var ``vi''_EW "Entropy Weight of ``vi''" drop ``vi''_ET capture drop ``vi''_SCOR if "`raw'"~="" { gen ``vi''_SCOR=``vi''*``vi''_EW replace ``vi''_SCOR=(```vi''_MAXM'-``vi'')*``vi''_EW if `ustr'regexm("`undes'","(^| )``vi''( |$)") } if "`pv'"~="" { gen ``vi''_SCOR=```vi''_pc'*``vi''_EW } if "`raw'"=="" & "`pv'"=="" { if "`norm'"=="MM" | "`norm'"=="MX" { if "`shift'"~="" replace ``vi''_MNRM=``vi''_MNRM-`shift' if "`smooth'"~="" replace ``vi''_MNRM=(``vi''_MNRM-`smooth')/(1-`smooth') } gen ``vi''_SCOR=``vi''_MNRM*``vi''_EW } } capture drop `score' egen `score'=rowtotal(*_SCOR) if "`raw'"~="" { label var `score' "Comprehensive Score (by raw data)" } if "`pv'"~="" { label var `score' "Comprehensive Score (by proportional data)" } if "`raw'"=="" &"`pv'"=="" { label var `score' "Comprehensive Score (by Min-Max data)" } order *_EW, after(`score') drop *_SCOR drop *_MNRM if `TouSeE'==0 { save `myEWMfile', replace restore merge 1:1 `EWMID' using `myEWMfile', nogenerate } preserve collapse (mean) *_EW if `touse' `TIME_BY' tempname EntW if "`by'"=="" { mkmat *_EW, matrix(`EntW') matrix colnames `EntW' = `varlist' matrix rownames `EntW' = EWeight local ew "" foreach vw of varlist *_EW { local ew "`ew' `=`vw'[1]'" } local ew=trim("`ew'") return local ew `ew' } else { mkmat *_EW, matrix(`EntW') rownames(`by') matrix colnames `EntW' = `varlist' } return matrix EW = `EntW' if "`list'"~="" { noisily dis as green "The entropy weight of {res:`varlist'} are as follows: " noisily list } restore if "`keep'"=="" { drop *_EW } } /* Close brace of quietly */ end