Filtering Taxa
After agglomerating taxa, the next step is to remove taxa that should not be included in downstream analysis — unassigned (NA) taxa, human reads (for 12Sv5), synthetic control ASVs, and any cohort-specific taxa that need to be excluded. This is handled by two functions, filter_trnL_taxa() and filter_12S_taxa(), which replace the individual subset_taxa()/prune_taxa() calls previously used for these steps. Cohort-specific removals are still done manually with subset_taxa(), after calling the appropriate function.
filter_trnL_taxa() and filter_12S_taxa() Functions
Both functions compute a lowest_level column (the most specific non-NA taxonomic rank per ASV) and remove unassigned and named control ASVs. filter_12S_taxa() additionally removes Homo sapiens reads. Neither function agglomerates — that happens earlier, in Agglomerating Taxa.
To-do
filter_12S_taxa() currently still performs an internal tax_glom() step and always recomputes lowest_level, even if the column already exists from the Agglomerating Taxa step. Both will be corrected in an upcoming revision — agglomeration will happen only in the Agglomerating Taxa step, and lowest_level will be reused if already present. The downloadable script above has not yet been updated to reflect this.
After reading the appropriate function into your analysis file, run:
Both functions preserve any tax-table columns not used for filtering (e.g. taxa/common_name from assign_common_names()) — these are set aside during filtering and reattached at the end for whichever ASVs survive, so run Assigning Common Names first if you want those columns carried through.
Key inputs:
controls(optional) — exactspeciesvalues to treat as synthetic control ASVs and remove; defaults to"synthetic trnL ASV"/"synthetic 12S ASV". Set toNULLto skip control removal, or pass your own value if your control species differs from the default.tax_cols/tax_coal(optional) — which tax-table columns to use for filtering, and respectively to coalesce intolowest_level; default to trnL's/12Sv5's own rank sets.export_NA_ASVs(optional) — a file path to write a CSV of removed unassigned ASVs (with prevalence and read counts) to, for later review.filter_12S_taxa()also takesexport_human_ASVs(a file path to write removed Homo sapiens ASVs to) andcalculate_human_reads_perc(whether to report the percentage of reads from Homo sapiens before filtering; defaultTRUE).
Manual Review for Ambiguous Human-Matching ASVs (12Sv5)
filter_12S_taxa()'s controls argument only matches ASVs assigned exactly to Homo sapiens or to a named control species. Some ASVs may BLAST to human without being classified that way — for example, ASVs ambiguous between human and a closely related species. If you have identified such ASVs manually (e.g., through the BLAST review process), remove them by sequence after calling filter_12S_taxa():
# Remove specific ASVs identified as human through manual review:
manual_human_asvs <- c("ACGT...", "TGCA...")
ps.12S <- prune_taxa(!taxa_names(ps.12S) %in% manual_human_asvs, ps.12S)
Synthetic controls with a different name
If your sequencing run's synthetic control ASV isn't named exactly "synthetic trnL ASV" or "synthetic 12S ASV", pass the actual value via controls = "[your control's species name]", or filter it out manually with subset_taxa().
Cohort-Specific Removals
Some studies may require removing additional taxa based on the study design, after calling filter_trnL_taxa()/filter_12S_taxa(). Common examples include:
- Environmental contamination — for trnL, taxa like grasses or trees that reflect environmental DNA rather than dietary intake.
- Known contaminants — taxa identified during quality control as likely cross-contamination from positive controls or other samples.
- Study-specific exclusions — taxa that are not relevant to the research question (e.g., removing non-mammalian vertebrates from a study focused on meat consumption).
These removals are study-dependent and should be documented in your analysis scripts. Use subset_taxa() to filter by any column in the taxonomy table: