def filter_by_sample_pct(otus, nsamples, pct, phyl_level):
if phyl_level not in ['<STR_LIT:k>', '<STR_LIT:p>', '<STR_LIT:c>', '<STR_LIT:o>', '<STR_LIT:f>', '<STR_LIT:g>', '<STR_LIT:s>']:<EOL><INDENT>phyl_level = '<STR_LIT:s>'<EOL><DEDENT>nsamples = float(nsamples)<EOL>sample_counts = defaultdict(set)<EOL>for otuid in otus:<EOL><INDENT>phyl = util.split_phylogeny(otus[otuid][<NUM_LIT:0>], phyl_level)<EOL>samples = {seqid.split('<STR_LIT:_>')[<NUM_LIT:0>] for seqid in otus[otuid][<NUM_LIT:1>]}<EOL>sample_counts[phyl].update(samples)<EOL><DEDENT>sample_counts = {phyl: len(sample_counts[phyl])/nsamples<EOL>for phyl in sample_counts}<EOL>above = {}<EOL>below = {}<EOL>for otuid in otus:<EOL><INDENT>phyl = util.split_phylogeny(otus[otuid][<NUM_LIT:0>], phyl_level)<EOL>if sample_counts[phyl] >= pct:<EOL><INDENT>above[otuid] = otus[otuid]<EOL><DEDENT>else:<EOL><INDENT>below[otuid] = [sample_counts[phyl], '<STR_LIT>',<EOL>otus[otuid][<NUM_LIT:0>], otus[otuid][<NUM_LIT:1>]]<EOL><DEDENT><DEDENT>return above, below<EOL>
Split the list of OTUs (and associated sequence ids) into two lists:
those occurring in more than some percentage of samples and those less than
the cutoff.

:type otus: dict
:param otus: {otuid: [taxonomy, [sequence IDs]]}
:type nsamples: int
:param nsamples: The total number of samples in the data set
:type pct: float
:param pct: The cutoff percentage for inclusion in the filtered
             set of OTUs
:type phyl_level: str
:param phyl_level: The phylogenetic level (e.g. family, group, etc...) at
                   which to combine OTU counts for thresholding. One of
                   the following: ['k','p','c','o','f','g','s']

:rtype: tuple
:return: Two dicts: the OTU IDs and sequence IDs above and below the
          percentage threshold.