Thanks @colinbrislawn and @thermokarst for the suggestions, as well as this post.
I have figured out how to get the taxonomy from dada2/phyloseq in the correct format to be added to both biom files correctly and qiime2. Posting the code here for anyone else that might be having troubles.
One note: I needed to install the latest github version of biomformat for R (version 1.7.0)
Starting in R with a phyloseq object (ps):
Format the taxonomy table:
tax<-as(tax_table(ps),"matrix")
tax_cols <- c("Kingdom", "Phylum", "Class","Order","Family","Genus")
tax<-as.data.frame(tax)
tax$taxonomy<-do.call(paste, c(tax[tax_cols], sep=";"))
for(co in tax_cols) tax[co]<-NULL
write.table(tax, "tax.txt", quote=FALSE, col.names=FALSE, sep="\t")
Make an biomformat OTU table:
otu<-t(as(otu_table(ps),"matrix"))
otu_biom<-make_biom(data=otu)
write_biom(otu_biom,"otu_biom.biom")
Optional: In qiime2 to make a biom OTU table with taxonomy:
(this step is not necessary for qiime2, as the taxonomy table is not imported from the biom file)
biom convert -i otu_biom.biom -o otu_biom_HDF5.biom --to-hdf5
biom add-metadata -i otu_biom_HDF5.biom -o otu_wTax.biom --observation-metadata-fp tax.txt --observation-header OTUID,taxonomy --sc-separated taxonomy
Import the OTU table (feature table) to qiime2:
qiime tools import \
--input-path otu_wTax.biom \
--type 'FeatureTable[Frequency]' \
--source-format BIOMV210Format \
--output-path feature-table.qza
Finally, import the taxonomy table:
qiime tools import \
--type 'FeatureData[Taxonomy]' \
--source-format HeaderlessTSVTaxonomyFormat \
--input-path tax.txt \
--output-path taxonomy.qza