# CLIFF CLIFF (Ce**L**l-type-specific drug sens**I**tivity **F**rom deconvoluted expression pro**F**iles) takes CLIMB's output and integrates it with drug sensitivity data (AUC values) to identify cell-type-specific drug responses, via an Expectation-Maximization algorithm. See [Methods](../methods.md) for the underlying model. This page covers both `cliff()`, the main deconvolution function, and `cliff_gene_selection()`, a helper used to pre-select drug-predictive genes before running it. ## cliff() ### Usage ```r cliff(climb_output, drug_data, mutation_data = NULL, min.mutation = 0, max.em.steps = 100, mode = "highres", regularization = "none", cancer_pattern = "like") ``` ### Parameters **Required** | Parameter | Description | |---|---| | `climb_output` | Output of `climb()`, run with `mode = "expression"` — CLIFF requires `expr.highres`, `expr.overall`, and `props.corrected` to be present | | `drug_data` | Data frame with an `auc` column (drug response values, expected in `[0, 1]`) and a `sample` column matching CLIMB's sample names | ```{note} `drug_data$auc` is internally recentered so its mean is exactly `0.5` before fitting. Predicted sensitivities (`pi_hat` / `PI_hat_nk`) should therefore be interpreted relative to that recentering, not on the raw input AUC scale. ``` **Optional** | Parameter | Description | Default | |---|---|---| | `mutation_data` | Matrix (samples × mutations) of binary mutation status (1/0) | `NULL` | | `min.mutation` | Minimum number of samples with a mutation for it to be included in the model | `0` | | `max.em.steps` | Maximum number of EM iterations | `100` | | `mode` | `"overall"` uses average cell-type expression across all samples (recommended); `"highres"` uses CLIMB's per-sample high-resolution expression | `"highres"` | | `regularization` | `"none"` (unregularized fit) or `"L2"` (ridge). Any other value falls back to `"none"` — lasso (`"L1"`) is not currently implemented | `"none"` | | `cancer_pattern` | String pattern identifying cancer cell types, for mutation attribution | `"like"` | ### Output `cliff()` returns an **unnamed** list of three elements, accessed by position: | Index | Description | |---|---| | `[[1]]` (`PI_hat_nk`) | Cell-type-specific drug sensitivity predictions (samples × cell-types) | | `[[2]]` (`mutation_data`) | The mutation data matrix used in the analysis | | `[[3]]` (`climb_prop`) | Cell-type proportions from CLIMB | ```{note} With thousands of genes and only a handful of bulk samples, `cliff()` is heavily over-parameterized if run on CLIMB's full gene set — cell-type estimates collapse to nearly identical values. Always pre-select a small set of drug-predictive genes with cliff_gene_selection() first, as shown below. ``` ### Example Using the [bundled in-vitro dataset](../example_data.md) (drug sensitivity of the same 6 mixtures, Fig. 4A): ```r data(sc.es); data(bulk.es); data(bulk_auc_data) climb_result <- climb(sc = sc.es, bulk = bulk.es, mode = "expression") # Subset to one drug/timepoint combination — cliff() takes one 'auc' column at a time drug_data <- bulk_auc_data[bulk_auc_data$drug == "Cytarabine_48h", ] # Pre-select genes predictive of this drug, then subset CLIMB's expression output to them bulk_mat <- t(exprs(bulk.es))[drug_data$sample, ] sel.genes <- cliff_gene_selection(bulk_mat, drug_data$auc, min.genes = 10) climb_result$expr.highres <- climb_result$expr.highres[, sel.genes, ] climb_result$expr.overall <- climb_result$expr.overall[sel.genes, ] cliff_result <- cliff(climb_output = climb_result, drug_data = drug_data, mode = "overall") # Averaged across samples, this correlates well (Pearson R > 0.9 for this # drug/timepoint) with the measured pure cell-line AUC head(cliff_result[[1]]) # PI_hat_nk matrix colMeans(cliff_result[[1]]) ``` ## cliff_gene_selection() A standalone helper that selects a small set of genes predictive of a drug-response phenotype, by fitting a lasso path across a decreasing grid of penalties and returning the first gene set that clears a minimum size. It is independent of `climb()`/`cliff()` and can be used to pre-filter genes before building a bulk expression matrix for deconvolution. ### Usage ```r cliff_gene_selection(bulk_mat, drug_d, min.genes = 10) ``` ### Parameters **Required** | Parameter | Description | |---|---| | `bulk_mat` | Matrix of bulk gene expression (samples × genes) | | `drug_d` | Numeric vector of drug sensitivity values (e.g. AUC), one per sample, in the same sample order as `bulk_mat` | **Optional** | Parameter | Description | Default | |---|---|---| | `min.genes` | Minimum number of genes to select before stopping the lasso path search | `10` | ### Output A character vector of selected gene names (column names of `bulk_mat` with a non-zero lasso coefficient), or `NULL` if no penalty in the search grid selects at least `min.genes` genes. ### Example ```r library(Biobase) data(bulk.es); data(bulk_auc_data) drug_data <- bulk_auc_data[bulk_auc_data$drug == "Cytarabine_48h", ] bulk_mat <- t(exprs(bulk.es))[drug_data$sample, ] sel.genes <- cliff_gene_selection(bulk_mat, drug_data$auc, min.genes = 10) length(sel.genes) ```