docs: 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