Calculate statistics for this layers

        This is the top-most computation method for the
        stat. It does not do any computations, but it
        knows how to verify the data, partition it call the
        next computation method and merge results.

        stats should not override this method.

        Parameters
        ----------
        data : panda.DataFrame
            Data points for all objects in a layer.
        params : dict
            Stat parameters
        layout : plotnine.layout.Layout
            Panel layout information

def compute_layer(cls, data, params, layout):
        """
        Calculate statistics for this layers

        This is the top-most computation method for the
        stat. It does not do any computations, but it
        knows how to verify the data, partition it call the
        next computation method and merge results.

        stats should not override this method.

        Parameters
        ----------
        data : panda.DataFrame
            Data points for all objects in a layer.
        params : dict
            Stat parameters
        layout : plotnine.layout.Layout
            Panel layout information
        """
        check_required_aesthetics(
            cls.REQUIRED_AES,
            list(data.columns) + list(params.keys()),
            cls.__name__)

        data = remove_missing(
            data,
            na_rm=params.get('na_rm', False),
            vars=list(cls.REQUIRED_AES | cls.NON_MISSING_AES),
            name=cls.__name__,
            finite=True)

        def fn(pdata):
            """
            Helper compute function
            """
            # Given data belonging to a specific panel, grab
            # the corresponding scales and call the method
            # that does the real computation
            if len(pdata) == 0:
                return pdata
            pscales = layout.get_scales(pdata['PANEL'].iat[0])
            return cls.compute_panel(pdata, pscales, **params)

        return groupby_apply(data, 'PANEL', fn)