diff --git a/yli/regress.py b/yli/regress.py index 4d60464..103cf5c 100644 --- a/yli/regress.py +++ b/yli/regress.py @@ -27,7 +27,7 @@ from datetime import datetime import itertools from .bayes_factors import BayesFactor, bayesfactor_afbf -from .utils import Estimate, check_nan, fmt_p_html, fmt_p_text +from .utils import Estimate, check_nan, fmt_p def vif(df, formula=None, nan_policy='warn'): """ @@ -86,10 +86,10 @@ class LikelihoodRatioTestResult: self.pvalue = pvalue def _repr_html_(self): - return 'LR({}) = {:.2f}; p {}'.format(self.dof, self.statistic, fmt_p_html(self.pvalue)) + return 'LR({}) = {:.2f}; p {}'.format(self.dof, self.statistic, fmt_p(self.pvalue, html=True)) def summary(self): - return 'LR({}) = {:.2f}; p {}'.format(self.dof, self.statistic, fmt_p_text(self.pvalue)) + return 'LR({}) = {:.2f}; p {}'.format(self.dof, self.statistic, fmt_p(self.pvalue, html=False)) class FTestResult: """Result of an F test for regression""" @@ -101,10 +101,10 @@ class FTestResult: self.pvalue = pvalue def _repr_html_(self): - return 'F({}, {}) = {:.2f}; p {}'.format(self.dof_model, self.dof_resid, self.statistic, fmt_p_html(self.pvalue)) + return 'F({}, {}) = {:.2f}; p {}'.format(self.dof_model, self.dof_resid, self.statistic, fmt_p(self.pvalue, html=True)) def summary(self): - return 'F({}, {}) = {:.2f}; p {}'.format(self.dof_model, self.dof_resid, self.statistic, fmt_p_text(self.pvalue)) + return 'F({}, {}) = {:.2f}; p {}'.format(self.dof_model, self.dof_resid, self.statistic, fmt_p(self.pvalue, html=False)) class RegressionResult: """ @@ -220,10 +220,10 @@ class RegressionResult: if html: right_col.append(('F:', format(f_result.statistic, '.2f'))) - right_col.append(('p (F):', fmt_p_html(f_result.pvalue, True))) + right_col.append(('p (F):', fmt_p(f_result.pvalue, html=True, nospace=True))) else: right_col.append(('F:', format(f_result.statistic, '.2f'))) - right_col.append(('p (F):', fmt_p_text(f_result.pvalue, True))) + right_col.append(('p (F):', fmt_p(f_result.pvalue, html=False, nospace=True))) else: # Otherwise report likelihood ratio test as overall test lrtest_result = self.lrtest_null() @@ -231,9 +231,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_html(lrtest_result.pvalue, True))) + right_col.append(('p (LR):', fmt_p(lrtest_result.pvalue, html=True, nospace=True))) else: - right_col.append(('p (LR):', fmt_p_text(lrtest_result.pvalue, True))) + right_col.append(('p (LR):', fmt_p(lrtest_result.pvalue, html=False, nospace=True))) return left_col, right_col @@ -259,7 +259,7 @@ class RegressionResult: if self.exp: beta = np.exp(beta) - out += '{}{:.2f}({:.2f}–{:.2f}){}'.format(term, beta.point, beta.ci_lower, beta.ci_upper, fmt_p_html(self.pvalues[term], True)) + out += '{}{:.2f}({:.2f}–{:.2f}){}'.format(term, beta.point, beta.ci_lower, beta.ci_upper, fmt_p(self.pvalues[term], html=True, nospace=True)) out += '' @@ -293,7 +293,7 @@ class RegressionResult: beta = np.exp(estimate) # Add some extra padding - table_data.append([term + ' ', format(beta.point, '.2f'), '({:.2f}'.format(beta.ci_lower), '-', '{:.2f})'.format(beta.ci_upper), ' ' + fmt_p_text(self.pvalues[term], True)]) + table_data.append([term + ' ', format(beta.point, '.2f'), '({:.2f}'.format(beta.ci_lower), '-', '{:.2f})'.format(beta.ci_upper), ' ' + fmt_p(self.pvalues[term], html=False, nospace=True)]) table2 = SimpleTable(data=table_data, headers=['', 'exp(β)' if self.exp else 'β', '', '\ue000', '', ' p']) # U+E000 is in Private Use Area, mark middle of CI column table2_text = table2.as_text().replace(' \ue000 ', '(95% CI)') # Render heading in the right spot diff --git a/yli/sig_tests.py b/yli/sig_tests.py index bca31b0..e6b12b2 100644 --- a/yli/sig_tests.py +++ b/yli/sig_tests.py @@ -22,7 +22,7 @@ import statsmodels.api as sm import functools import warnings -from .utils import Estimate, as_2groups, check_nan, fmt_p_html, fmt_p_text +from .utils import Estimate, as_2groups, check_nan, fmt_p # ---------------- # Student's t test @@ -42,10 +42,10 @@ class TTestResult: self.delta_direction = delta_direction def _repr_html_(self): - return 't({:.0f}) = {:.2f}; p {}
δ (95% CI) = {}, {}'.format(self.dof, self.statistic, fmt_p_html(self.pvalue), self.delta.summary(), self.delta_direction) + return 't({:.0f}) = {:.2f}; p {}
δ (95% CI) = {}, {}'.format(self.dof, self.statistic, fmt_p(self.pvalue, html=True), self.delta.summary(), self.delta_direction) def summary(self): - return 't({:.0f}) = {:.2f}; p {}\nδ (95% CI) = {}, {}'.format(self.dof, self.statistic, fmt_p_text(self.pvalue), self.delta.summary(), self.delta_direction) + return 't({:.0f}) = {:.2f}; p {}\nδ (95% CI) = {}, {}'.format(self.dof, self.statistic, fmt_p(self.pvalue, html=False), self.delta.summary(), self.delta_direction) def ttest_ind(df, dep, ind, *, nan_policy='warn'): """Perform an independent-sample Student's t test""" @@ -91,14 +91,14 @@ class MannWhitneyResult: self.brunnermunzel = brunnermunzel def _repr_html_(self): - line1 = 'U = {:.1f}; p {}
r = {:.2f}, {}'.format(self.statistic, fmt_p_html(self.pvalue), self.rank_biserial, self.direction) + line1 = 'U = {:.1f}; p {}
r = {:.2f}, {}'.format(self.statistic, fmt_p(self.pvalue, html=True), self.rank_biserial, self.direction) if self.brunnermunzel: return line1 + '
' + self.brunnermunzel._repr_html_() else: return line1 def summary(self): - line1 = 'U = {:.1f}; p {}\nr = {}, {}'.format(self.statistic, fmt_p_text(self.pvalue), self.rank_biserial, self.direction) + line1 = 'U = {:.1f}; p {}\nr = {}, {}'.format(self.statistic, fmt_p(self.pvalue, html=False), self.rank_biserial, self.direction) if self.brunnermunzel: return line1 + '\n' + self.brunnermunzel.summary() else: @@ -112,10 +112,10 @@ class BrunnerMunzelResult: self.pvalue = pvalue def _repr_html_(self): - return 'W = {:.1f}; p {}'.format(self.statistic, fmt_p_html(self.pvalue)) + return 'W = {:.1f}; p {}'.format(self.statistic, fmt_p(self.pvalue, html=True)) def summary(self): - return 'W = {:.1f}; p {}'.format(self.statistic, fmt_p_text(self.pvalue)) + return 'W = {:.1f}; p {}'.format(self.statistic, fmt_p(self.pvalue, html=False)) def mannwhitney(df, dep, ind, *, nan_policy='warn', brunnermunzel=True, use_continuity=False, alternative='two-sided', method='auto'): """ @@ -174,18 +174,18 @@ class PearsonChiSquaredResult: def _repr_html_(self): if self.oddsratio is not None: return '{}
χ2({}) = {:.2f}; p {}
OR (95% CI) = {}
RR (95% CI) = {}'.format( - self.ct._repr_html_(), self.dof, self.statistic, fmt_p_html(self.pvalue), self.oddsratio.summary(), self.riskratio.summary()) + self.ct._repr_html_(), self.dof, self.statistic, fmt_p(self.pvalue, html=True), self.oddsratio.summary(), self.riskratio.summary()) else: return '{}
χ2({}) = {:.2f}; p {}'.format( - self.ct._repr_html_(), self.dof, self.statistic, fmt_p_html(self.pvalue)) + self.ct._repr_html_(), self.dof, self.statistic, fmt_p(self.pvalue, html=True)) def summary(self): if self.oddsratio is not None: return '{}\nχ²({}) = {:.2f}; p {}\nOR (95% CI) = {}\nRR (95% CI) = {}'.format( - self.ct, self.dof, self.statistic, fmt_p_text(self.pvalue), self.oddsratio.summary(), self.riskratio.summary()) + self.ct, self.dof, self.statistic, fmt_p(self.pvalue, html=False), self.oddsratio.summary(), self.riskratio.summary()) else: return '{}\nχ²({}) = {:.2f}; p {}'.format( - self.ct, self.dof, self.statistic, fmt_p_text(self.pvalue)) + self.ct, self.dof, self.statistic, fmt_p(self.pvalue, html=False)) def chi2(df, dep, ind, *, nan_policy='warn'): """ diff --git a/yli/utils.py b/yli/utils.py index bc0840e..64bc842 100644 --- a/yli/utils.py +++ b/yli/utils.py @@ -71,26 +71,25 @@ def do_fmt_p(p): else: return None, '{:.1f}'.format(p) -def fmt_p_text(p, nospace=False): - """Format p value for plaintext""" +def fmt_p(p, *, html, nospace=False): + """Format p value""" sign, fmt = do_fmt_p(p) if sign is not None: if nospace: - return sign + fmt # e.g. "<0.001" + pfmt = sign + fmt # e.g. "<0.001" else: - return sign + ' ' + fmt # e.g. "< 0.001" + pfmt = sign + ' ' + fmt # e.g. "< 0.001" else: if nospace: - return fmt # e.g. "0.05" + pfmt = fmt # e.g. "0.05" else: - return '= ' + fmt # e.g. "= 0.05" - -def fmt_p_html(p, nospace=False): - """Format p value for HTML""" + pfmt = '= ' + fmt # e.g. "= 0.05" - txt = fmt_p_text(p, nospace) - return txt.replace('<', '<') + if html: + pfmt = pfmt.replace('<', '<') + + return pfmt class Estimate: """A point estimate and surrounding confidence interval"""