Align tabular p values in plaintext output

This commit is contained in:
RunasSudo 2022-10-18 19:23:57 +11:00
parent a484b6205c
commit 62c23efebc
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
2 changed files with 55 additions and 31 deletions

View File

@ -249,10 +249,10 @@ class RegressionResult:
if html: if html:
right_col.append(('<i>F</i>:', format(f_result.statistic, '.2f'))) right_col.append(('<i>F</i>:', format(f_result.statistic, '.2f')))
right_col.append(('<i>p</i> (<i>F</i>):', fmt_p(f_result.pvalue, html=True, tabular=True))) right_col.append(('<i>p</i> (<i>F</i>):', fmt_p(f_result.pvalue, html=True, only_value=True)))
else: else:
right_col.append(('F:', format(f_result.statistic, '.2f'))) right_col.append(('F:', format(f_result.statistic, '.2f')))
right_col.append(('p (F):', fmt_p(f_result.pvalue, html=False, tabular=True))) right_col.append(('p (F):', fmt_p(f_result.pvalue, html=False, only_value=True)))
else: else:
# Otherwise report likelihood ratio test as overall test # Otherwise report likelihood ratio test as overall test
lrtest_result = self.lrtest_null() lrtest_result = self.lrtest_null()
@ -260,9 +260,9 @@ class RegressionResult:
right_col.append(('LL-Model:', format(self.llf, '.2f'))) right_col.append(('LL-Model:', format(self.llf, '.2f')))
right_col.append(('LL-Null:', format(self.llnull, '.2f'))) right_col.append(('LL-Null:', format(self.llnull, '.2f')))
if html: if html:
right_col.append(('<i>p</i> (LR):', fmt_p(lrtest_result.pvalue, html=True, tabular=True))) right_col.append(('<i>p</i> (LR):', fmt_p(lrtest_result.pvalue, html=True, only_value=True)))
else: else:
right_col.append(('p (LR):', fmt_p(lrtest_result.pvalue, html=False, tabular=True))) right_col.append(('p (LR):', fmt_p(lrtest_result.pvalue, html=False, only_value=True)))
return left_col, right_col return left_col, right_col

View File

@ -86,55 +86,79 @@ def do_fmt_p(p):
# Nonsignificant: round up # Nonsignificant: round up
p = config.alpha + 10**-config.pvalue_max_dps p = config.alpha + 10**-config.pvalue_max_dps
return None, '{0:.{dps}f}'.format(p, dps=config.pvalue_max_dps) return '', '{0:.{dps}f}'.format(p, dps=config.pvalue_max_dps)
if p < 10**-config.pvalue_min_dps: if p < 10**-config.pvalue_min_dps:
# Insufficient resolution at pvalue_min_dps # Insufficient resolution at pvalue_min_dps
# We know from earlier comparison that 1 s.f. fits within pvalue_max_dps # We know from earlier comparison that 1 s.f. fits within pvalue_max_dps
return None, '{:.1g}'.format(p) return '', '{:.1g}'.format(p)
# OK to round to pvalue_min_dps # OK to round to pvalue_min_dps
return None, '{0:.{dps}f}'.format(p, dps=config.pvalue_min_dps) return '', '{0:.{dps}f}'.format(p, dps=config.pvalue_min_dps)
def fmt_p(p, *, html, tabular=False): def fmt_p(p, *, html, only_value=False, tabular=False):
""" """
Format p value Format p value
tabular: If true, output in tabular format of p values where decimal points align tabular: If true, output in tabular format of p values where decimal points align
""" """
# FIXME: Make only_value and tabular enums
sign, fmt = do_fmt_p(p) sign, fmt = do_fmt_p(p)
# Strip leading zero if required # Strip leading zero if required
if not config.pvalue_leading_zero: if not config.pvalue_leading_zero:
fmt = fmt.lstrip('0') fmt = fmt.lstrip('0')
# Add significance asterisk if required # Check if significant
if p < config.alpha: if p < config.alpha:
fmt += '*' asterisk = '*'
else:
asterisk = ''
if sign is not None:
if html: if html:
# Escape angle quotes # Escape angle quotes
sign = sign.replace('<', '&lt;') sign = sign.replace('<', '&lt;')
sign = sign.replace('>', '&gt;') sign = sign.replace('>', '&gt;')
if tabular: if only_value:
pfmt = sign + fmt # e.g. "<0.001" return '{}{}{}'.format(sign, fmt, asterisk)
else: elif tabular:
pfmt = sign + ' ' + fmt # e.g. "< 0.001" # Always left-aligned, so reserve space for sign if required to align decimal points
else: if not sign:
if tabular: sign = '<span style="visibility:hidden">=</span>'
# Tabular format with no sign: add a preceding space to get decimal points to line up
if html:
# Insert space with width of '=' which should be width of '<' and '>' too
pfmt = '<span style="visibility:hidden">=</span>' + fmt # e.g. "0.05"
else:
pfmt = ' ' + fmt # e.g. "0.05"
else:
pfmt = '= ' + fmt # e.g. "= 0.05"
return pfmt return '{}{}{}'.format(sign, fmt, asterisk)
else:
# Non-tabular so force a sign
if not sign:
sign = '='
return '{} {}{}'.format(sign, fmt, asterisk)
else:
if only_value:
return '{}{}{}'.format(sign, fmt, asterisk)
elif tabular:
# Right-aligned, so add spaces to simulate left alignment
if not sign:
sign = ' '
# +1 for decimal point
# +1 for sign
# +1 for asterisk
pvalue_max_len = config.pvalue_max_dps + 3
if config.pvalue_leading_zero:
pvalue_max_len += 1
# Now add spaces
rpadding = ' ' * (pvalue_max_len - len(sign + fmt + asterisk))
return '{}{}{}{}'.format(sign, fmt, asterisk, rpadding)
else:
# Non-tabular so force a sign
if not sign:
sign = '='
return '{} {}{}'.format(sign, fmt, asterisk)
# ------------------------------ # ------------------------------
# General result-related classes # General result-related classes