Hello all:
I was writing a wrapper to generate multiple variable medians with their min, max and IQR formatted to display with their units. I managed to tokenize the units for each of the variables in order from a passthru in the syntax with a parallel loop. However, I am unable to decide how I can loop in a conditional statement to add a space before the unit text if the unit has a match for any alphabet/text (for e.g. "cm", "years" and such, as opposed to %). I played with some if loops/regexm but can't get the ``u'' to be read with a space if the text matches alphabets. The line below containing
ret local `v'_miqr has the ``u''
Sample return list display formats are below
I was writing a wrapper to generate multiple variable medians with their min, max and IQR formatted to display with their units. I managed to tokenize the units for each of the variables in order from a passthru in the syntax with a parallel loop. However, I am unable to decide how I can loop in a conditional statement to add a space before the unit text if the unit has a match for any alphabet/text (for e.g. "cm", "years" and such, as opposed to %). I played with some if loops/regexm but can't get the ``u'' to be read with a space if the text matches alphabets. The line below containing
ret local `v'_miqr has the ``u''
Code:
*! program dmed v1.0.0 GV 8nov2023
sysuse auto, clear
cap program drop dmed
return clear
program define dmed, rclass
version 18.0
set trace on
syntax varlist(numeric max=7) [if] [, unit(passthru)]
marksample touse
qui count if(`touse')
if "`unit'" != "" {
di "unit is: `unit'"
tokenize `unit', parse("() ")
}
else {
di "unit() is empty"
}
return local tot = `r(N)'
local endash = ustrunescape("\u2013")
// Clyde code to reassign formatting for decimal variables below
*---------------------------------------------------------
local u = 3
foreach v of local varlist {
capture confirm float var `v', exact
if c(rc) == 0 {
local dec "%3.1f"
}
else {
local dec "%8.0g"
}
tabstat `v' if(`touse'), statistic(p25 p50 p75 min max) save
mat list r(StatTotal)
matmap r(StatTotal) B, map(round(@, 0.1)) // Bad idea. Dont round up.
mat list B
local `v'lqr = strltrim("`:di `dec' `=B[1,1]''")
local `v'med = strltrim("`:di `dec' `=B[2,1]''")
local `v'uqr = strltrim("`:di `dec' `=B[3,1]''")
local `v'min = strltrim("`:di `dec' `=B[4,1]''")
local `v'max = strltrim("`:di `dec' `=B[5,1]''")
ret local `v'_miqr `"``v'med'``u'' (IQR: ``v'lqr'`endash'``v'uqr'``u'')"'
ret local `v'_mr `"``v'med'``u'' (range: ``v'min'`endash'``v'max'``u'')"'
ret local `v'lqr = strltrim("`:di `dec' `=B[1,1]''")
ret local `v'med = strltrim("`:di `dec' `=B[2,1]''")
ret local `v'uqr = strltrim("`:di `dec' `=B[3,1]''")
ret local `v'min = strltrim("`:di `dec' `=B[4,1]''")
ret local `v'max = strltrim("`:di `dec' `=B[5,1]''")
local ++u
}
end
dmed turn price if foreign==1, unit(cm %)
ret li
Code:
macros:
r(pricemax) : "12990"
r(pricemin) : "3748"
r(priceuqr) : "7140"
r(pricemed) : "5759"
r(pricelqr) : "4499"
r(price_mr) : "5759% (range: 3748–12990%)"
r(price_miqr) : "5759% (IQR: 4499–7140%)"
r(turnmax) : "38"
r(turnmin) : "32"
r(turnuqr) : "36"
r(turnmed) : "36"
r(turnlqr) : "34"
r(turn_mr) : "36cm (range: 32–38cm)"
r(turn_miqr) : "36cm (IQR: 34–36cm)"
r(tot) : "22"

Comment