stargazer icon indicating copy to clipboard operation
stargazer copied to clipboard

Significant digits by column and/or for R^2

Open merubhanot opened this issue 3 years ago • 1 comments

Right now, there seems to be only 1 way to set significant digits that affects the whole table, but frequently I find that I want to set different significant digits by column (depending on variable scale) and/or for R^2 (where you usually want 2 decimal places). Is there a way to add more flexibility to this?

merubhanot avatar Feb 28 '22 22:02 merubhanot

I solved the issue for R2 by overriding HTMLRenderer.generate_r2 and LaTeXRenderer.generate_r2 with my own renderers that use a custom float formatter. My full solution below. I guess the same idea could be utilized in a 'real' solution as well, perhaps even in variable-specific formatting.

def import_stargazer_with_overrides():
    """Import Stargazer with override that allows alternate R2 stats float accuracy vs. sig_digits.

    Returns
    ----------
    Imported Stargazer class.

    Notes
    ----------
    Created Stargazer objects need attribute *sig_digits_r2* set.

    Examples
    ----------
    >>> Stargazer = import_stargazer_with_overrides()
    >>> table = Stargazer([res1, res2])
    >>> table.sig_digits_r2 = 2
    >>> display(table)
    """
    # Create a new float formatter aimed for R2 statistics
    from stargazer.stargazer import Renderer
    def _float_format_r2(self, value):
        """
        Format value to string, using the precision set by the user.
        """
        if value is None:
            return ''

        return '{{:.{prec}f}}'.format(prec=self.sig_digits_r2).format(value)
    Renderer._float_format_r2 = _float_format_r2

    # Override R2 statistics in HTMLRenderer
    from stargazer.stargazer import HTMLRenderer
    def generate_r2_htmlrenderer(self):
        r2_text = ''
        r2_text += '<tr><td style="text-align: left">R<sup>2</sup></td>'
        for md in self.model_data:
            r2_text += '<td>' + self._float_format_r2(md['r2']) + '</td>'
        r2_text += '</tr>'
        return r2_text
    HTMLRenderer.generate_r2 = generate_r2_htmlrenderer
    def generate_r2_adj_htmlrenderer(self):
        r2_text = ''
        r2_text += '<tr><td style="text-align: left">Adjusted R<sup>2</sup></td>'
        for md in self.model_data:
            r2_text += '<td>' + self._float_format_r2(md['r2_adj']) + '</td>'
        r2_text += '</tr>'
        return r2_text
    HTMLRenderer.generate_r2_adj = generate_r2_adj_htmlrenderer

    # Override R2 statistics in LaTeXRenderer
    from stargazer.stargazer import LaTeXRenderer
    def generate_r2_latexrenderer(self):
        r2_text = ' $R^2$ '
        for md in self.model_data:
            r2_text += '& ' + self._float_format_r2(md['r2']) + ' '
        r2_text += '\\\\\n'
        return r2_text
    LaTeXRenderer.generate_r2 = generate_r2_latexrenderer
    def generate_r2_adj_latexrenderer(self):
        r2_text = ' Adjusted $R^2$ '
        for md in self.model_data:
            r2_text += '& ' + self._float_format_r2(md['r2_adj']) + ' '
        r2_text += '\\\\\n'
        return r2_text
    LaTeXRenderer.generate_r2_adj = generate_r2_adj_latexrenderer
    from stargazer.stargazer import Stargazer

    return Stargazer

vvoutilainen avatar Dec 30 '22 11:12 vvoutilainen