
Write concept features to a DuckDB table, for in-database scoring
Source:R/tidymodels_bridge.R
materialize_concept_features.RdBuilds the same per-row lookback-window features as extract_sparse_concept_matrix(), but as a wide
table inside DuckDB: row_id (1-based parquet position), person_id, index_date, the outcome y if
the parquet has one, and one numeric column per requested concept, named <domain>_<concept_id> exactly as
in as_tidymodels_data(). That is the table to point a scoring query at: a model trained in tidymodels can
be converted to SQL with orbital::orbital() (workflows) or tidypredict::tidypredict_sql() (glm and
friends) and evaluated inside DuckDB on this table, on the training cohort or on any new cohort parquet,
with exactly the same window rules, so training and scoring features cannot drift apart.
Usage
materialize_concept_features(
con,
features_parquet,
concepts,
table = "ml_concept_features",
lookback_days = 365,
value = "count",
include_index_date = FALSE,
person_col = NULL,
index_date_col = NULL,
outcome_col = NULL,
temporary = FALSE,
anchor_date = c("auto", "admit_date", "discharge_date"),
washin_buffer_days = 0,
washin_buffer_hours = 0
)Arguments
- con
Active DBI connection to DuckDB holding the OMOP CDM tables (read-only is fine). If the vocabulary lives in an attached
central_vocabcatalog, concept names are picked up automatically.- features_parquet
Path (or glob) of the cohort parquet, one row per index event, with a person id and an index date column; an outcome column is carried through if present. Columns are auto-detected (
person_id/subject_id/patid;index_date/cohort_start_date/end_date/admit_date...;y/outcome_flag/label) or set withperson_col,index_date_col,outcome_col.- concepts
A data.frame with
domainandconcept_idcolumns: typicallyres$concepts, or the subset returned bymodel_concepts().- table
Name of the table to create (replaced if it exists).
- lookback_days
Window length in days, or
NULLfor all prior history.- value
"count"(records per concept) or"binary"(presence).- include_index_date
Also use events dated exactly on the index date (default
FALSE).- person_col, index_date_col, outcome_col
Optional explicit column names in the parquet.
- temporary
Create a temporary table (default
FALSE).- anchor_date
Strategy for selecting index date column from cohort parquet:
"auto"(default),"admit_date"(prioritizes admission date to prevent in-hospital leakage), or"discharge_date"(prioritizes discharge date).- washin_buffer_days
Post-anchor observation buffer days to include in the window (default 0).
- washin_buffer_hours
Post-anchor observation buffer hours (e.g. 24 for 24h post-admission, default 0).
Details
The SQL has one expression per concept, so request only what the model needs (model_concepts()).
Examples
if (FALSE) { # \dontrun{
used <- model_concepts(fit, res$concepts)
orb <- orbital::orbital(fit)
scores <- orbital::augment(orb, dplyr::tbl(con, "to_score")) |> dplyr::collect()
} # }