def groupTagData(ref_group=None, ref_regex=None):
    '''compute groups and pairs from tag data table.'''

    if ref_regex is not None and ref_group is None:
        groups = R('''levels(groups)''')
        for g in groups:
            rx = re.compile(ref_regex)
            if rx.search(g):
                ref_group = g

    # Relevel the groups so that the reference comes first
    if ref_group is not None:
        E.info("reference group (control) is '%s'" % ref_group)
        R('''groups <- relevel(groups, ref="%s")''' % ref_group)

    groups = R('''levels(groups)''')
    pairs = R('''levels(pairs)''')
    factors = R('''factors''')

    # JJ - check whether there are additional factors in design file...
    # warning... isintance(df, rpy.robjects.vectors.Vector) returns True
    if isinstance(factors, rpy2.robjects.vectors.DataFrame):
        E.warn("There are additional factors in design file that are ignored"
               " by groupTagData: %s" % factors.r_repr())
    # AH: uncommented as it causes an issue with rpy2 2.7.7
    # else:
    #     # Hack... must be a better way to evaluate r NA instance in python?
    #     import pdb; pdb.set_trace()
    #     assert len(list(factors)) == 1 and bool(list(factors)[0]) is False, \
    #         "factors must either be DataFrame or NA in R global namespace"

    # Test if replicates exist - at least one group must have multiple samples
    max_per_group = R('''max(table(groups)) ''')[0]

    has_replicates = max_per_group >= 2

    # Test if pairs exist:
    npairs = R('''length(table(pairs)) ''')[0]
    has_pairs = npairs == 2

    # at least two samples per pair
    if has_pairs:
        min_per_pair = R('''min(table(pairs)) ''')[0]
        has_pairs = min_per_pair >= 2

    return groups, pairs, has_replicates, has_pairs
dataset/ETHPy150Open CGATOxford/cgat/CGAT/Expression.py/groupTagData/original