Removes rows from the database based on a filtered tidybreed_table.
Chain after get_table() and dplyr::filter() to target specific rows. Returns
the population invisibly — consistent with all other action functions.
Arguments
- tbl
A
tidybreed_tablefromget_table(), with adplyr::filter()applied.- tables
NULL(default) to delete from the current table only;"all"to delete from everyind_*table (includingind_haplotypeandind_genotype) that exists in the population; or a character vector of specific table names (each must have anid_indcolumn). When notNULL, the source table must also have anid_indcolumn.- confirm_all
Logical. Set to
TRUEto allow deletion of all rows when no filter has been applied. This is a deliberate safeguard — you must explicitly opt in to wiping an entire table. DefaultFALSE.- dry_run
Logical. If
TRUE, report what would be deleted without modifying the database. DefaultFALSE.- verbose
Logical. If
TRUE, print a message after each deletion reporting the row count removed. DefaultTRUE.
Details
A filter is required by default. Calling remove_rows() without a
prior dplyr::filter() will stop with an error explaining how to opt in to
full-table deletion via confirm_all = TRUE.
Single-table mode (tables = NULL): uses the composite row key from
the internal TABLE_ROW_KEYS registry to delete exactly the rows matched
by the filter — no more, no less. For example, filtering ind_tbv by
trait_name == "ADG" deletes only the ADG rows, not all TBV rows for those
animals. Key columns are matched with IS NOT DISTINCT FROM, so rows whose
key is NULL — the default chr_inheritance / chr_recombination rows
seeded by define_genome(), or the shared (line_name IS NULL)
founder_haplotypes pool — delete correctly.
Every system table is registered for single-table deletion except
_schema_meta, which is package-managed; remove_rows() refuses it with a
pointer to define_schema_description() rather than a generic error.
Cross-table mode (tables != NULL): extracts unique id_ind values
from the filtered table and issues a DELETE ... WHERE id_ind IN (...)
for each target table via a temp-table JOIN. tables = "all" targets every
ind_* table (including ind_haplotype, ind_genotype, and
ind_true_index) that currently exists in the population (including
ind_meta).
A temporary DuckDB table is used for both modes to avoid SQL injection risk and to handle large ID sets efficiently.
Examples
if (FALSE) { # \dontrun{
# Delete specific phenotype records for culled animals
pop |>
get_table("ind_phenotype") |>
dplyr::filter(id_ind %in% culled_ids, phenotype_name == "litter_size") |>
remove_rows()
# Remove all data for culled animals across every individual table
pop |>
get_table("ind_meta") |>
dplyr::filter(id_ind %in% culled_ids) |>
remove_rows(tables = "all")
# Delete from an explicit subset of tables only
pop |>
get_table("ind_meta") |>
dplyr::filter(id_ind %in% culled_ids) |>
remove_rows(tables = c("ind_phenotype", "ind_tbv"))
# Preview before deleting
pop |>
get_table("ind_meta") |>
dplyr::filter(id_ind %in% culled_ids) |>
remove_rows(tables = "all", dry_run = TRUE)
# Wipe an entire table (requires confirm_all = TRUE)
pop |>
get_table("ind_phenotype") |>
remove_rows(confirm_all = TRUE)
} # }
