
Changelog
Version 0.1.1
- ✨
find_markers():againstargument for sibling-aware extraction ("nearest"= most-correlated type), balancedtop = c(pos, neg)budgets (defaultc(10, 10)), andmax_pct_outpan-lineage exclusion guard. - ✨ Add model-based scoring:
train_weights(return_models = TRUE)persists per-type linear models (glmnet/lr) andhitype_score_models()scores cells with the model equations (linear predictors) and a margin-based Unknown threshold. - feat: enhance train_weights functions to support class-specific markers and update documentation
Version 0.1.0
- 🐛 Fix
RunHitype()with a metadata-columnident(cluster-level assignments) assigning every cluster the same arbitrary cell type: the column was taken as an unnamed vector, sohitype_assign()could not map the score columns back to cells, every cluster scored all-zero, and the ties collapsed to one cell type. The cluster vector is now named from the cell names (as theIdents()branch already was).
Version 0.0.8
- ✨
train_weights()(andcompile_weights()) gain apos_onlyargument (defaultFALSE): whenTRUE, markers whose trained weight is not positive are dropped from the output, leaving only the markers overexpressed in each cell type (nodirection = "negative"rows). - 🐛 Fix
train_weights()silently returning the rescale midpoint as all weights when a marker gene has no variance across the cells (e.g. an unexpressed gene that still exists in the expression matrix): after scaling, its column is all-NA, every supervised fit fails with “x has missing values”, and eachtryCatch-wrapped fit is silently swallowed (all-zero coefficients -> uniform midpoint weights, e.g.3forrange = c(1, 5)).prepare_data_for_training()now drops zero-variance markers (with a warning) from both the training matrix and the gene sets, so they never reach the model or the compiled weights. - 🐛 Fix
hitype_score()collapsing to a zero-row score matrix when a marker gene has no variance across the given (e.g. small held-out test) cells: its scaled row is all-NA, NA propagates to every cell type sharing the marker, all-NA rows are removed, and downstreamhitype_assign()crashes with “arguments imply differing number of rows”. Zero-variance genes now score as 0. - 🐛 Fix the on-test assignment printed by
train_weights()(withrun_weights_on_test) being all-zero when every cell type shares the same marker pool: the scores were computed with the defaultuse_sensitivity = TRUE, and markers present in every gene set get a sensitivity of 0, zeroing the whole score matrix. On-test scoring now usesuse_sensitivity = FALSE(as recommended for scoring with learned weights, perhitype_score()). - ✨
compile_weights()drops exactly-zero trained weights from the output by default (drop_zero = TRUE, new argument ontrain_weights()), so zero means “no direction”: markers the penalty zeroed out are absent from the cell type’s list. Passdrop_zero = FALSEto keep every candidate marker (withformat = "db"they are then encoded as*). - ✨ The universal output of
train_weights()/compile_weights()(the defaultformat) now keeps the raw trained weights as-is instead of range-rescaling them. The rescale was pure distortion — it erased the sign of genuinely negative markers under a positive-only range likec(1, 5)and injected a per-cell-type offset proportional to marker count — andhitype_score()consumes only signed raw weights anyway.rangenow applies toformat = "db"only: it must be the 4-element sign-split formc(-low, -high, low, high)(defaultc(-5, -1, 1, 5)), which scales positive weights into[low, high]and negative ones into[-high, -low]before rounding, so all-positive training data cannot produce negative db markers. The db weights are integer-encoded so they round-trip exactly throughgs_prepare(): a weight ofwmarkers asgene+"+"× (w− 1), a weight of−wasgene+"-"×w(the decoder counts positive repeats from 1).
Version 0.0.7
✨
train_weights()now derives the training cell types from the data instead of the marker file. With a Seuratexprs,clusterscan beNULL(default, usingSeurat::Idents()) or a column name in themeta.data; with a matrix, it stays a named per-cell vector. A cell type in the marker file with no cells of that type in the data is ignored (with a warning), and its markers are pooled for the cell types in the data that are not covered by the marker file, so those cell types can still be trained. No cells are dropped from the training data, and the returned weights cover only the cell types present in the data.🐛 Fix
train_weights()failing on Seurat input (exprsas a Seurat object): clusters were converted to integer codes whiledata$clustersstayed a factor, so the per-methodclusters == ctcomparisons (againstunique(data$clusters)) were all-FALSE, every supervised fit errored inside atryCatchand was silently swallowed, and all trained weights came out as the rescale midpoint (e.g. uniform3for the defaultrange = c(1, 5)). Clusters now stay as character cell-type labels throughout, whichcompile_weights()also needs to matchoutput_nodeagainst the gene-set cell-type names.
Version 0.0.6
- ✨
gs_prepare()now auto-detects the universal marker format (a long table withcell_typeandgenecolumns, shared with biopipen’sCellTypeAnnotation) in addition to the native wide ScType-style format. Column aliases are matched case-insensitively (celltype/type→cell_type;marker/gene_symbol→gene;sign→direction;tissueType→tissue). Optional columns:direction(positive/negative, aliasespos/neg/+/-),weight(numeric; positive markers getabs(weight), negative markers get-abs(weight), signed weights are used as-is whendirectionis missing),tissue(filtered bytissue_type), andlevel. Marker files can be.txt/.tsv,.csv,.xlsx,.rds, or.qs/.qs2(the latter only when theqs/qs2package is installed). - ✨
train_weights()andfind_markers()gain aformatargument ("universal"by default,"db"for the legacy wide format), and so does the internalcompile_weights(). The default universal output carries exact numeric weights — the legacy db format’s weight-suffix magnitude shift no longer applies to the default flow, includingrun_weights_on_test_data.
Version 0.0.5
- ✨ Add
find_markers()to discover marker genes from your data with dependency-lightfc(default),Seurat, orprestobackends, directly producing a dbdata.frameconsumable bygs_prepare(). - ✨ Add
methodargument totrain_weights()with 7 weight-learning backends:uniform,correlation,lr,glmnet(default, recommended),rf,xgb,lrp.epochsandbatch_sizenow apply to thelrpmethod only. - ✨ Add
cv_foldsargument for cross-validated weight estimation: stratified folds, per-fold weights averaged for stability. Used bylr,glmnet, andlrp. - ✨ Add
normanduse_sensitivityarguments tohitype_score()andhitype_score_level():-
norm = "weight"normalizes scores bysum(abs(weights))(fairer across cell types with different marker numbers); -
use_sensitivity = FALSEdisables marker-sensitivity weighting — recommended when scoring with learned weights to avoid double-penalizing shared markers.
-
- 🔧 Statistical soundness: removed input masking in
prepare_data_for_training()(masked zeros let the model learn the mask pattern instead of expression). - 🔧 Seurat v5 compatibility: use
Seurat::GetAssayData(x, layer = "data")instead of direct@assays$RNA@data/@assays$RNA@scale.dataaccess. - 🧩 New suggested dependencies:
glmnet,ranger,xgboost(required per method, optional overall).