R/assemble_pheno_covar.R
assemble_pheno_covar.RdBuild the (sample_id, Y, X, trait, ...) bundle that
fit_null_model / marginal_scan and the GLOW SNV-set
pipeline consume, by merging three sources onto a single GDS sample order:
a raw outcome vector, an external phenotype/covariate table, and (optionally) a
principal-component matrix. Cohort-specific column names and recoding rules are
passed as arguments; the file I/O (opening the GDS, reading the CSV / PCs) is the
caller's responsibility, so this function is pure and testable.
This is the packaged form of the per-cohort "prepare pheno-covariates" step.
Sample order is anchored to sample_ids (typically the GDS sample order);
the returned bundle preserves that order minus any dropped rows.
assemble_pheno_covar(
sample_ids,
outcome,
trait = c("binary", "continuous"),
pheno = NULL,
pheno_id_col = NULL,
covariates = NULL,
pcs = NULL,
drop_incomplete = TRUE,
covar_set = NULL,
verbose = 1
)Character vector: the sample-order anchor (e.g. a GDS's
sample.id). All other sources are aligned to this order.
A list list(values=, map=) giving the raw outcome
values (a vector aligned to sample_ids) and an optional
map: a named vector (e.g. c("1"=0L, "2"=1L); unmapped values
become NA) or a function function(values) -> Y. If map is
NULL, values are used as-is (coerced with as.numeric).
Either "binary" or "continuous" — recorded in the bundle.
Optional data frame: the external phenotype/covariate table from
which covariate columns are drawn. Merged onto sample_ids by pheno_id_col.
Name of the column in pheno matching sample_ids
(required when covariates draws from pheno).
Named list defining the covariate (design) columns of X,
in order. Each element is either a string (a pheno column name, coerced
with as.numeric) or a list list(col=, map=) where map is a
named recode vector (unmapped -> NA) or a function. The list names
become the X column names.
Optional list list(scores=, id_col=, cols=) appending PC columns
to X: scores is a data frame / matrix of PC scores, cols the
PC column names to take, and id_col (optional) a column of scores
matched to sample_ids (if NULL, scores rows are assumed
already in sample_ids order). The taken cols keep their names in X.
If TRUE (default), after dropping NA-outcome
samples, drop any remaining sample with an NA in X
(complete.cases).
Optional label recorded in the bundle (covar_set).
0 = silent, >=1 = progress messages.
A list with:
retained sample IDs (subset of sample_ids, original order)
the outcome for retained samples
numeric covariate matrix (covariate columns then PC columns)
"binary" or "continuous"
length(sample_ids)
n_total minus the number retained
the covar_set label
colnames(X)
extract_pheno_covar_gds (reads pheno/covar from a GDS node),
fit_null_model, marginal_scan
set.seed(1)
ids <- paste0("S", 1:6)
pheno <- data.frame(
iid = ids, status = c(2, 1, 2, 1, 2, -9),
sex = c("F", "M", "F", "M", "F", "F"), age = c(50, 60, 55, 65, 58, 70),
stringsAsFactors = FALSE)
pcs <- data.frame(iid = ids, PC1 = rnorm(6), PC2 = rnorm(6))
b <- assemble_pheno_covar(
sample_ids = ids,
outcome = list(values = pheno$status, map = c("1" = 0L, "2" = 1L)),
trait = "binary",
pheno = pheno, pheno_id_col = "iid",
covariates = list(sex_numeric = list(col = "sex", map = c(F = 1, M = 0)),
age = "age"),
pcs = list(scores = pcs, id_col = "iid", cols = c("PC1", "PC2")),
covar_set = "demo")
#> pheno match: 6 / 6 samples
#> PC match: 6 / 6 samples
#> valid outcome: 5, missing: 1
#> final: 5 samples, 4 covariates [sex_numeric, age, PC1, PC2]
str(b)
#> List of 8
#> $ sample_id : chr [1:5] "S1" "S2" "S3" "S4" ...
#> $ Y : int [1:5] 1 0 1 0 1
#> $ X : num [1:5, 1:4] 1 0 1 0 1 50 60 55 65 58 ...
#> ..- attr(*, "dimnames")=List of 2
#> .. ..$ : NULL
#> .. ..$ : chr [1:4] "sex_numeric" "age" "PC1" "PC2"
#> $ trait : chr "binary"
#> $ n_total : int 6
#> $ n_excluded : int 1
#> $ covar_set : chr "demo"
#> $ covar_names: chr [1:4] "sex_numeric" "age" "PC1" "PC2"