docs: def _create_tableone(self,data):
          """
          Create table 1 by combining the continuous and categorical tables.
  
          Returns
          ----------
          table : pandas DataFrame
              The complete table one.
          """
          if self._continuous and self._categorical:
  
              # support pandas<=0.22
              try: 
                  table = pd.concat([self.cont_table,self.cat_table],sort=False)
              except: 
                  table = pd.concat([self.cont_table,self.cat_table])
          elif self._continuous:
              table = self.cont_table
          elif self._categorical:
              table = self.cat_table
  
          # round pval column and convert to string
          if self._pval and self._pval_adjust:
              table['pval (adjusted)'] = table['pval (adjusted)'].apply('{:.3f}'.format).astype(str)
              table.loc[table['pval (adjusted)'] == '0.000', 'pval (adjusted)'] = '<0.001'
          elif self._pval:
              table['pval'] = table['pval'].apply('{:.3f}'.format).astype(str)
              table.loc[table['pval'] == '0.000', 'pval'] = '<0.001'
  
          # sort the table rows
          table.reset_index().set_index(['variable','level'], inplace=True)
          if self._sort:
              # alphabetical
              new_index = sorted(table.index.values)
          else:
              # sort by the columns argument
              new_index = sorted(table.index.values,key=lambda x: self._columns.index(x[0]))
          table = table.reindex(new_index)
  
          # if a limit has been set on the number of categorical variables
          # then re-order the variables by frequency
          if self._limit:
              levelcounts = data[self._categorical].nunique()
              levelcounts = levelcounts[levelcounts >= self._limit]
              for v,_ in levelcounts.iteritems():
                  count = data[v].value_counts().sort_values(ascending=False)
                  new_index = [(v, i) for i in count.index]
                  # restructure to match orig_index
                  new_index_array=np.empty((len(new_index),), dtype=object)
                  new_index_array[:]=[tuple(i) for i in new_index]
                  orig_index = table.index.values.copy()
                  orig_index[table.index.get_loc(v)] = new_index_array
                  table = table.reindex(orig_index)
  
          # inserts n row
          n_row = pd.DataFrame(columns = ['variable','level','isnull'])
          n_row.set_index(['variable','level'], inplace=True)
          n_row.loc['n', ''] = None
  
          # support pandas<=0.22
          try:
              table = pd.concat([n_row,table],sort=False)
          except:
              table = pd.concat([n_row,table])
  
          if self._groupbylvls == ['overall']:
              table.loc['n','overall'] = len(data.index)
          else:
              for g in self._groupbylvls:
                  ct = data[self._groupby][data[self._groupby]==g].count()
                  table.loc['n',g] = ct
  
          # only display data in first level row
          dupe_mask = table.groupby(level=[0]).cumcount().ne(0)
          dupe_columns = ['isnull']
          optional_columns = ['pval','pval (adjusted)','ptest']
          for col in optional_columns:
              if col in table.columns.values:
                  dupe_columns.append(col)
  
          table[dupe_columns] = table[dupe_columns].mask(dupe_mask).fillna('')
  
          # remove empty column added above
          table.drop([''], axis=1, inplace=True)
  
          # remove isnull column if not needed
          if not self._isnull:
              table.drop('isnull',axis=1,inplace=True)
  
          # replace nans with empty strings
          table.fillna('',inplace=True)
  
          # add column index
          if not self._groupbylvls == ['overall']:
              # rename groupby variable if requested
              c = self._groupby
              if self._alt_labels:
                  if self._groupby in self._alt_labels:
                      c = self._alt_labels[self._groupby]
  
              c = 'Grouped by {}'.format(c)
              table.columns = pd.MultiIndex.from_product([[c], table.columns])
  
          # display alternative labels if assigned
          table.rename(index=self._create_row_labels(), inplace=True, level=0)
  
          # if a limit has been set on the number of categorical variables
          # limit the number of categorical variables that are displayed
          if self._limit:
              table = table.groupby('variable').head(self._limit)
  
          # re-order the columns in a consistent fashion
          if self._groupby:
              cols = table.columns.levels[1].values
          else:
              cols = table.columns.values
  
          if 'isnull' in cols:
              cols = ['isnull'] + [x for x in cols if x != 'isnull']
  
          # iterate through each optional column
          # if they exist, put them at the end of the dataframe
          # ensures the last 3 columns will be in the same order as optional_columns
          for col in optional_columns:
              if col in cols:
                  cols = [x for x in cols if x != col] + [col]
  
          if self._groupby:
              table = table.reindex(cols, axis=1, level=1)
          else:
              table = table.reindex(cols, axis=1)
  
          return table