*! 3.0.0 NJC 11 January 2024 *! 2.0.2 NJC 29 June 2021 *! 2.0.1 NJC 15 June 2020 *! 2.0.0 NJC 5 July 2018 *! 1.0.0 NJC 20 November 2016 program entropyetc, sortpreserve version 8.2 syntax varname [if] [in] [aweight fweight/] /// [, GENerate(str) by(varlist) list Format(str) * ] if "`generate'`list'" == "" { di "nothing to do" exit 0 } quietly { marksample touse, strok if "`by'" != "" markout `touse' `by', strok count if `touse' if r(N) == 0 error 2000 if "`by'" == "" { tempvar by gen byte `by' = `touse' label def `by' 1 "all" label val `by' `by' char `by'[varname] " " } if "`generate'" != "" parsegenerate `generate' tempvar freq total S p Shannon Simpson Shannon2 Simpson2 if "`exp'" == "" local exp = 1 bysort `touse' `by' `varlist' : gen double `freq' = sum(`touse' * `exp') by `touse' `by' `varlist' : replace `freq' = cond(_n == _N, `freq'[_N], .) by `touse' `by' `varlist' : gen `S' = cond(_n == _N, `freq'[_N] > 0, .) bysort `touse' `by' (`S') : replace `S' = sum(`S') by `touse' `by' : replace `S' = `S'[_N] by `touse' `by' : gen double `total' = sum(`freq') by `touse' `by' : replace `total' = `total'[_N] gen double `p' = `freq' / `total' by `touse' `by': gen double `Shannon' = sum(`p' * ln(1/`p')) by `touse' `by': replace `Shannon' = `Shannon'[_N] gen double `Shannon2' = exp(`Shannon') by `touse' `by': gen double `Simpson' = sum(`p'^2) by `touse' `by': replace `Simpson' = `Simpson'[_N] gen double `Simpson2' = 1/`Simpson' label var `S' "distinct" label var `Shannon' "Shannon H" label var `Shannon2' "exp(H)" label var `Simpson' "Simpson" label var `Simpson2' "1/Simpson" if "`format'" == "" local format "%4.3f" format `S' %1.0f format `Shannon' `Shannon2' `Simpson' `Simpson2' `format' } tokenize `S' `Shannon' `Shannon2' `Simpson' `Simpson2' if "`list'" != "" { forval j = 1/5 { char ``j''[varname] "`: var label ``j'''" } tempvar tolist egen `tolist' = tag(`touse' `by') list `by' `S' `Shannon' `Shannon2' `Simpson' `Simpson2' if `touse' & `tolist', /// abbrev(9) subvarname noobs `options' } forval j = 1/5 { if "`var_`j''" != "" { gen `var_`j'' = ``j'' if `touse' } } end program parsegenerate tokenize `0' if "`6'" != "" { di as err "generate() should specify 1 to 5 tokens" exit 134 } forval j = 1/5 { if "``j''" != "" { gettoken no rest : `j', parse(=) capture numlist "`no'", max(1) int range(>=1 <=4) if _rc { di as err "generate() error: ``j''" exit _rc } gettoken eqs rest : rest, parse(=) confirm new var `rest' c_local var_`no' "`rest'" } } end