Export metadata and feature data tables - #34
Conversation
In data_curation.R, adding ability to export genome stats and QC metadata into human readable CSVs. `load_tables` allows you to run "example <- exportTables("data/Staphylococcus_aureus/Sau.duckdb", load_tables=TRUE)" and import the tables into R so you can play around with them directly. By default, it just saves the tables as exported CSVs. In data_processing.R, added a similar exporter that allows you to save out all the feature data and other DuckDB-connected tables, with the ability to output sequences too, and append AST phenotype data to the feature tables. Tables can be saved out as csv (default), tsv, Parquet, and xlsx. Added `writexl` to Suggests in DESCRIPTION. Fixed some reversions where I broke things in the PR this branch is based on. Will add those same fixes to that PR momentarily to keep things aligned.
Ran data processing workflow for Campylobacter coli. This can be unzipped and used as the test data for exportProcessedData() rather than having to run it all beforehand. Data curation step still requires that prepareGenomes() be run for a test bug, and Staphylococcus argenteus is a good use case for this.
jananiravi
left a comment
There was a problem hiding this comment.
Few quick comments. Will test it out tomorrow.
Clarified a few names based on code review feedback.
@epbrenner prepareGenomes + exportTables --> they run locally with Sar. |
|
After running the campy -->
what's TET doing in |
|
jananiravi
left a comment
There was a problem hiding this comment.
is this going to be merged to qc_filtering and then qc_filtering --> main? that might be helpful to avoid duplicate reviews.
eboyer221
left a comment
There was a problem hiding this comment.
When I tested this, it looks like genome IDs such as 263.1, 263.10, and 263.100 are being written to the CSV as plain numbers rather than text, since they happen to look numeric. When I read that export back (with readr::read_csv(), pandas, or Excel's defaults) all three collapsed to the same value, since trailing zeros after a decimal don't count (263.1 and 263.10 parse as numerically identical). So the three distinct genomes merged under one ID, and it'll happen for any taxon with more than ~9 genomes. I also tried forcing quotes around every value (quote = "all") to see if that would prevent it, but the collision still happened on read. Quoting only protects against commas breaking the file format, it doesn't tell the reader "treat this as text."
This affects every genome_id-keyed table both export functions produce (genome_data, metadata, amr_phenotype_wide, gene_count, etc.).
Two options I see: (1) add a clear warning telling users to force col_types/dtype=str on ID columns when reading CSV/TSV back, or (2) recommend Parquet as the default/safe export format for programmatic reuse, since arrow preserves the real column type - I verified this did not occur with Parquet.
epbrenner
left a comment
There was a problem hiding this comment.
Oh I have to submit my own review to my own PR to actually post these comments, huh? Oops.
@epbrenner @AbhirupaGhosh didnt we have this fix in already? |
Co-authored-by: Emily Boyer <130874527+eboyer221@users.noreply.github.com>
Yeah, relatively easy solution, just requires special handling of the columns of interest. Patched in the latest commit. |
with `devtools::document()`
| genome_id = as.character(`genome.genome_id`), | ||
| antibiotic = as.character(`genome_drug.antibiotic`), | ||
| phenotype = as.character(`genome_drug.resistant_phenotype`) |
There was a problem hiding this comment.
Need this special treatment for anything else? accessions that end in a.x as well? (all of them?)
There was a problem hiding this comment.
I'll ask around, but I don't think we need to worry about other fields in the trailing zero context.
Edit: Correction, we don't currently need to worry about other fields. If we update to use additional fields, this set may need to be expanded, but this catches our known issues.
Dropping fluff. Since skip_tables takes a list in, this was a silly oversight. Co-authored-by: Janani Ravi <janani.ravi@cuanschutz.edu>
Standardizing trailing zero parsing helper across scripts (thanks @jananiravi). Standardizing warning text across scripts about trailing zeroes, and allowing users to choose the format of their outputs from data_curation.R so it's in line with the options provided in data_curation.R.
…nto export_tables
| @@ -302,8 +326,8 @@ | |||
| #' } | |||
| #' @keywords internal | |||
| .apply_metadata_qc <- function(genome_tbl, | |||
There was a problem hiding this comment.
@eboyer221 Test breakage (for this and newly edited funcs): this rename isn't reflected in tests/testthat/test-apply-metadata-qc.R
| stop("No requested tables were found in the DuckDB.") | ||
| } | ||
|
|
||
| phenotype_wide <- .preserve_export_id_text(build_amr_wide()) |
There was a problem hiding this comment.
When build_amr_wide() returns NULL (no AMR source table, or required columns missing — see its own return(NULL) branches a few lines above), this line feeds NULL straight into .preserve_export_id_text(), silently produces a 0×0 tibble, not NULL. That will likely break downstream is.null(phenotype_wide) guards meant to skip AMR export cleanly (the next branch around line ~2035, and the append-mode check around line ~2059) — instead of skipping with the "no AMR source table found" message, it'll silently write an empty amr_phenotype_wide.csv/.parquet/etc.
Maybe only call .preserve_export_id_text() on build_amr_wide()'s result if it's non-NULL, e.g. wrap the assignment in an if (!is.null(...)).
Note for later beyond this PR -- to check new edited returns map back nicely to downstream calls.
| duckdb_path <- normalizePath(duckdb_path, mustWork = TRUE) | ||
| amr_phenotype_mode <- match.arg(amr_phenotype_mode) | ||
|
|
||
| export_formats <- unique(tolower(export_formats)) |
There was a problem hiding this comment.
Duplicated export-format validation/warning block — exportTables() (R/data_curation.R, ~L2423-2450) and exportProcessedData() (R/data_processing.R, ~L1858-1885) both carry an identical copy of the format-validation (allowed_formats, unknown_formats check) and the trailing-zero CSV/TSV/XLSX warning message. Not a bug, just flagging as a "worth extracting to a shared internal helper" comment if you want to leave it — your call whether it's worth the churn right now. [I think the duplicated definitions were mentioned before either for the export functions or something else.]


Testing:
For this PR, I have included bundled test data in
/inst/extdata/Campy_testdata.zip. Extract this into a single directory of your choosing. This bundled data is not intended to the ultimate example data for final package release.For
data_curation.R:Run
prepareGenomes("Staphylococcus argenteus")then
exportTables("data/Staphylococcus_argenteus/Sar.duckdb")For
data_processing.R:Unzip the Campy test data first, then run
exportProcessedData("inst/extdata/Campy_testdata/Cco_parquet.duckdb")There are several thrilling parameters to fiddle around with.
What this does:
Adds the ability to export basic stats into human readable CSVs from data_curation.R workflow.
Adds the ability to export all the processed feature data into a variety of formats from data_processing.R workflow.
What's the point?
Makes amRdata more independently useful to people even if they don't run the full amR suite. For example, you could export feature matrices for custom modeling workflows outside of ours, or just get an idea of what distributions of different QC and AST labels are across different taxa.