def _create_cat_describe(self,data):
        """
        Describe the categorical data.

        Parameters
        ----------
            data : pandas DataFrame
                The input dataset.

        Returns
        ----------
            df_cat : pandas DataFrame
                Summarise the categorical variables.
        """
        group_dict = {}

        for g in self._groupbylvls:
            if self._groupby:
                d_slice = data.loc[data[self._groupby] == g, self._categorical]
            else:
                d_slice = data[self._categorical].copy()

            # create a dataframe with freq, proportion
            df = d_slice.copy()

            # convert type to string to avoid int converted to boolean, avoiding nans
            for column in df.columns:
                df[column] = [str(row) if not pd.isnull(row) else None for row in df[column].values]

            df = df.melt().groupby(['variable','value']).size().to_frame(name='freq')
            df.index.set_names('level', level=1, inplace=True)
            df['percent'] = df['freq'].div(df.freq.sum(level=0),level=0).astype(float)* 100

            # set number of decimal places for percent
            if isinstance(self._decimals,int):
                n = self._decimals
                f = '{{:.{}f}}'.format(n)
                df['percent'] = df['percent'].astype(float).map(f.format)
            elif isinstance(self._decimals,dict):
                df.loc[:,'percent'] = df.apply(self._format_cat, axis=1)
            else:
                n = 1
                f = '{{:.{}f}}'.format(n)
                df['percent'] = df['percent'].astype(float).map(f.format)

            # add n column, listing total non-null values for each variable
            ct = d_slice.count().to_frame(name='n')
            ct.index.name = 'variable'
            df = df.join(ct)

            # add null count
            nulls = d_slice.isnull().sum().to_frame(name='isnull')
            nulls.index.name = 'variable'
            # only save null count to the first category for each variable
            # do this by extracting the first category from the df row index
            levels = df.reset_index()[['variable','level']].groupby('variable').first()
            # add this category to the nulls table
            nulls = nulls.join(levels)
            nulls.set_index('level', append=True, inplace=True)
            # join nulls to categorical
            df = df.join(nulls)

            # add summary column
            df['t1_summary'] = df.freq.map(str) + ' (' + df.percent.map(str) + ')'

            # add to dictionary
            group_dict[g] = df

        df_cat = pd.concat(group_dict,axis=1)
        # ensure the groups are the 2nd level of the column index
        if df_cat.columns.nlevels>1:
            df_cat = df_cat.swaplevel(0, 1, axis=1).sort_index(axis=1,level=0)

        return df_cat
Describe the categorical data.

        Parameters
        ----------
            data : pandas DataFrame
                The input dataset.

        Returns
        ----------
            df_cat : pandas DataFrame
                Summarise the categorical variables.