The database version of draw_stratified_sample(), for populations that
are too large to load into R (the paragraphs of a cleaned text table, the
candidate pairs of a matching step). The draw is done by DuckDB: within
each stratum, rows are ordered by the MD5 hash of their identifier and the
seed, and the first ones are kept.
Usage
draw_stratified_sample_db(
con,
from,
id_col,
strata = NULL,
n_per_stratum = NULL,
n = NULL,
allocation = c("equal", "proportional"),
seed,
columns = NULL
)Arguments
- con
A DBI connection, or the path of a
.duckdbfile.- from
Character. A table name, or a SQL query between parentheses (e.g.
"(SELECT * FROM pair WHERE accepted)").- id_col
Character. Column identifying each row (unique).
- strata
Character or
NULL. Columns defining the strata.- n_per_stratum, n, allocation
As in
draw_stratified_sample().- seed
Integer or string. Seed of the draw.
- columns
Character or
NULL. Columns returned;NULLfor all.
Details
Ordering by md5(id || '|' || seed) gives a draw that is reproducible on
any machine and any DuckDB version (unlike DuckDB's random() or
hash()), and that does not depend on the order of the rows. It is a
simple random sample within each stratum as long as the identifiers are
unrelated to the hash, which MD5 guarantees in practice. The same seed
gives a different sample from draw_stratified_sample(), which uses R's
random numbers.
Examples
con <- db_connect(tempfile(fileext = ".duckdb"))
#> duckdb is storing downloaded extensions and secrets under ~/.duckdb:
#> ℹ /home/agoutsmedt/.duckdb
#> This persists across sessions and is shared with the DuckDB CLI and other clients.
#> ℹ Run duckdb(shared_home = FALSE) to use a temporary directory instead.
#> ℹ See ?duckdb_storage for details and alternatives.
DBI::dbWriteTable(con, "pair", data.frame(
pair_id = sprintf("p%03d", 1:200),
rule = rep(c("doi", "exact_title", "fuzzy_title"), c(150, 40, 10))
))
s <- draw_stratified_sample_db(con, "pair", "pair_id", "rule", n_per_stratum = 5, seed = 7)
s[, .N, by = .(.stratum, .population_n, .weight)]
#> .stratum .population_n .weight N
#> <char> <int> <num> <int>
#> 1: doi 150 30 5
#> 2: exact_title 40 8 5
#> 3: fuzzy_title 10 2 5
db_disconnect(con)