diff --git a/yli/regress.py b/yli/regress.py
index 2b78bc6..1e89ccd 100644
--- a/yli/regress.py
+++ b/yli/regress.py
@@ -249,10 +249,10 @@ class RegressionResult:
if html:
right_col.append(('F:', format(f_result.statistic, '.2f')))
- right_col.append(('p (F):', fmt_p(f_result.pvalue, html=True, tabular=True)))
+ right_col.append(('p (F):', fmt_p(f_result.pvalue, html=True, only_value=True)))
else:
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:
# Otherwise report likelihood ratio test as overall test
lrtest_result = self.lrtest_null()
@@ -260,9 +260,9 @@ class RegressionResult:
right_col.append(('LL-Model:', format(self.llf, '.2f')))
right_col.append(('LL-Null:', format(self.llnull, '.2f')))
if html:
- right_col.append(('p (LR):', fmt_p(lrtest_result.pvalue, html=True, tabular=True)))
+ right_col.append(('p (LR):', fmt_p(lrtest_result.pvalue, html=True, only_value=True)))
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
diff --git a/yli/utils.py b/yli/utils.py
index fb40365..5887505 100644
--- a/yli/utils.py
+++ b/yli/utils.py
@@ -86,55 +86,79 @@ def do_fmt_p(p):
# Nonsignificant: round up
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:
# Insufficient resolution at pvalue_min_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
- 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
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)
# Strip leading zero if required
if not config.pvalue_leading_zero:
fmt = fmt.lstrip('0')
- # Add significance asterisk if required
+ # Check if significant
if p < config.alpha:
- fmt += '*'
-
- if sign is not None:
- if html:
- # Escape angle quotes
- sign = sign.replace('<', '<')
- sign = sign.replace('>', '>')
-
- if tabular:
- pfmt = sign + fmt # e.g. "<0.001"
- else:
- pfmt = sign + ' ' + fmt # e.g. "< 0.001"
+ asterisk = '*'
else:
- if tabular:
- # 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 = '=' + fmt # e.g. "0.05"
- else:
- pfmt = ' ' + fmt # e.g. "0.05"
- else:
- pfmt = '= ' + fmt # e.g. "= 0.05"
+ asterisk = ''
- return pfmt
+ if html:
+ # Escape angle quotes
+ sign = sign.replace('<', '<')
+ sign = sign.replace('>', '>')
+
+ if only_value:
+ return '{}{}{}'.format(sign, fmt, asterisk)
+ elif tabular:
+ # Always left-aligned, so reserve space for sign if required to align decimal points
+ if not sign:
+ sign = '='
+
+ 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