def execute_table(self, _output_type, **kwargs: dict) -> 'SASresults':
        """
        executes a PROC TABULATE statement 

        You must specify an output type to use this method, of 'HTML', 'text', or 'Pandas'.
        There are three convenience functions for generating specific output; see:
            .text_table()
            .table()
            .to_dataframe()

        :param _output_type: style of output to use
        :param left: the query for the left side of the table
        :param top: the query for the top of the table
        :return:
        """

        left = kwargs.pop('left', None)
        top = kwargs.pop('top', None)
        sets = dict(classes=set(), vars=set())
        left._gather(sets)
        if top: top._gather(sets)

        table = top \
                and '%s, %s' % (str(left), str(top)) \
                or str(left)

        proc_kwargs = dict(
            cls=' '.join(sets['classes']),
            var=' '.join(sets['vars']),
            table=table
        )

        # permit additional valid options if passed; for now, just 'where'
        proc_kwargs.update(kwargs)

        # we can't easily use the SASProcCommons approach for submiting, 
        # since this is merely an output / display proc for us;
        # but we can at least use it to check valid options in the canonical saspy way
        required_options = {'cls', 'var', 'table'}
        allowed_options = {'cls', 'var', 'table', 'where'}
        verifiedKwargs = sp.sasproccommons.SASProcCommons._stmt_check(self, required_options, allowed_options,
                                                                      proc_kwargs)

        if (_output_type == 'Pandas'):
            # for pandas, use the out= directive
            code = "proc tabulate data=%s.%s %s out=temptab;\n" % (
            self.data.libref, self.data.table, self.data._dsopts())
        else:
            code = "proc tabulate data=%s.%s %s;\n" % (self.data.libref, self.data.table, self.data._dsopts())

        # build the code
        for arg, value in verifiedKwargs.items():
            code += "  %s %s;\n" % (arg == 'cls' and 'class' or arg, value)
        code += "run;"

        # teach_me_SAS
        if self.sas.nosub:
            print(code)
            return

        # submit the code
        ll = self.data._is_valid()

        if _output_type == 'HTML':
            if not ll:
                html = self.data.HTML
                self.data.HTML = 1
                ll = self.sas._io.submit(code)
                self.data.HTML = html
            if not self.sas.batch:
                self.sas.DISPLAY(self.sas.HTML(ll['LST']))
                check, errorMsg = self.data._checkLogForError(ll['LOG'])
                if not check:
                    raise ValueError("Internal code execution failed: " + errorMsg)
            else:
                return ll

        elif _output_type == 'text':
            if not ll:
                html = self.data.HTML
                self.data.HTML = 1
                ll = self.sas._io.submit(code, 'text')
                self.data.HTML = html
            print(ll['LST'])
            return

        elif _output_type == 'Pandas':
            return self.to_nested_dataframe(code)
def execute_table ( self , _output_type , ** kwargs : dict ) -> 'SASresults' : left = kwargs . pop ( 'left' , None ) top = kwargs . pop ( 'top' , None ) sets = dict ( classes = set ( ) , vars = set ( ) ) left . _gather ( sets ) if top : top . _gather ( sets ) table = top and '%s, %s' % ( str ( left ) , str ( top ) ) or str ( left ) proc_kwargs = dict ( cls = ' ' . join ( sets [ 'classes' ] ) , var = ' ' . join ( sets [ 'vars' ] ) , table = table ) proc_kwargs . update ( kwargs ) required_options = { 'cls' , 'var' , 'table' } allowed_options = { 'cls' , 'var' , 'table' , 'where' } verifiedKwargs = sp . sasproccommons . SASProcCommons . _stmt_check ( self , required_options , allowed_options , proc_kwargs ) if ( _output_type == 'Pandas' ) : code = "proc tabulate data=%s.%s %s out=temptab;\n" % ( self . data . libref , self . data . table , self . data . _dsopts ( ) ) else : code = "proc tabulate data=%s.%s %s;\n" % ( self . data . libref , self . data . table , self . data . _dsopts ( ) ) for arg , value in verifiedKwargs . items ( ) : code += "  %s %s;\n" % ( arg == 'cls' and 'class' or arg , value ) code += "run;" if self . sas . nosub : print ( code ) return ll = self . data . _is_valid ( ) if _output_type == 'HTML' : if not ll : html = self . data . HTML self . data . HTML = 1 ll = self . sas . _io . submit ( code ) self . data . HTML = html if not self . sas . batch : self . sas . DISPLAY ( self . sas . HTML ( ll [ 'LST' ] ) ) check , errorMsg = self . data . _checkLogForError ( ll [ 'LOG' ] ) if not check : raise ValueError ( "Internal code execution failed: " + errorMsg ) else : return ll elif _output_type == 'text' : if not ll : html = self . data . HTML self . data . HTML = 1 ll = self . sas . _io . submit ( code , 'text' ) self . data . HTML = html print ( ll [ 'LST' ] ) return elif _output_type == 'Pandas' : return self . to_nested_dataframe ( code )
executes a PROC TABULATE statement 

        You must specify an output type to use this method, of 'HTML', 'text', or 'Pandas'.
        There are three convenience functions for generating specific output; see:
            .text_table()
            .table()
            .to_dataframe()

        :param _output_type: style of output to use
        :param left: the query for the left side of the table
        :param top: the query for the top of the table
        :return: