Gene-level test for the Z-score method, with a p-value and a
False Discovery Rate (FDR) for each gene. Each gene gets a score, the
mean (or the median) of the Z-scores of its barcodes, which is compared
with the scores of random sets of barcodes of the same size. Use it on
the table returned by compute_metrics or
compute_barcode_statistics; it replaces
find_zscore_hit.
Usage
find_gene_zscore_hit(
table_treate_vs_control,
score = c("Zscore", "ZscoreRobust"),
direction = c("Down", "Up"),
statistic = c("mean", "median"),
control_genes = NULL,
n_permutations = 1e+05,
min_barcodes = 3,
fdr = 0.05,
fdr_method = c("BH", "storey"),
seed = NULL,
reference = c("random", "empirical"),
empirical_fit = c("central", "one-sided")
)Arguments
- table_treate_vs_control
A table with one row for each barcode and at least the columns Gene, Log2FC and the score column, as returned by
compute_metricsorcompute_barcode_statistics.- score
The column to use as score: "Zscore" (default) or "ZscoreRobust".
- direction
"Down" (default) for depleted genes or "Up" for enriched genes.
- statistic
The gene score: "mean" (default) or "median" of the barcode scores. The median is less affected by single barcodes with a strong effect (for example off-target effects) but has less power.
- control_genes
Optional names of control genes (as in the Gene column), for example "non-targeting". When given, the random barcodes of the permutations are drawn from their barcodes, and they are not tested. Use only controls that behave like genes without effect (see Details); the default (NULL) uses all the barcodes.
- n_permutations
The number of random barcode sets used to compute the p-values (default 1e5, at least 100). Not used with reference = "empirical".
- min_barcodes
Genes with fewer barcodes than this are not tested (default 3).
- fdr
The FDR threshold: only genes with an FDR lower than or equal to this value are returned (default 0.05). Use fdr = 1 to return all the tested genes.
- fdr_method
How the FDR is computed: "BH" (Benjamini-Hochberg, the default) or "storey" (Benjamini-Hochberg multiplied by the estimated proportion of genes without effect, less conservative when many genes have an effect).
- seed
An optional random seed, to make the permutations reproducible. The random number state of the session is restored afterwards.
- reference
How the null is obtained: "random" (default), random sets of barcodes (from all the barcodes, or from those of control_genes), or "empirical", an empirical null of the gene statistics estimated from the data (see Details).
- empirical_fit
With reference = "empirical", how the null is fitted: "central" (default) or "one-sided" (see Details).
Value
A tibble with one row for each hit and the columns Gene, NBarcodes (number of barcodes), Score (mean or median score of the barcodes), Log2FC (median log2 fold change of the barcodes), PValue and FDR, ordered by p-value. With reference = "empirical" it also has the column Statistic (the standardized gene score) and the attribute "null", the mean and standard deviation of the fitted null.
Details
Under the null hypothesis that the gene has no effect, its barcodes behave like barcodes taken at random, so the p-value is computed by permutation: the gene score is compared with the scores of n_permutations random sets of barcodes of the same size. The p-values are continuous (the smallest is 1 / (n_permutations + 1)) and do not depend on the distribution of the barcode scores.
The random barcodes are drawn from all the barcodes or, when
control_genes is given, only from the barcodes of the control genes
(for example the non-targeting shRNAs). With all the barcodes (the
default), the barcodes of the true hits are part of the reference,
which makes the test conservative when many genes have an effect.
Control genes avoid this, but only if their barcodes behave like the
barcodes of genes without effect. This is often not true for
non-targeting shRNAs: targeting shRNAs are usually somewhat depleted
compared with them (off-target effects, toxicity of the RNAi
machinery), so every gene looks depleted. In the K562 essentiality
screen (k562_count_table) the non-targeting reference
called hundreds of non-essential genes, while the default reference did
not. Before using control genes, check that their scores match those
of genes known to have no effect (for example the non-essential
genes); otherwise use the default.
Empirical null (reference = "empirical"). Instead of random
barcodes, the gene scores are compared with the distribution of the
scores of the genes without effect, estimated from the data (an
empirical null, as in Efron's locfdr). Each gene gets a statistic,
its score standardized by the median and the median absolute
deviation of all the barcode scores and by the square root of its
number of barcodes. Most genes have no effect, so the centre of the
distribution of these statistics is the null: a normal distribution is
fitted there (empirical_fit = "central": a parabola fitted to the log
density around its mode; "one-sided": the mode and the spread of the
statistics on the side without hits, above the mode for "Down"), and
the p-values come from it. Two things make it better than the random
barcodes in a dropout screen: the hits do not widen the null, and the
null includes the variation between genes. The barcodes of a gene
often vary together (the same knockdown efficiency, the same position
in the genome), so the scores of genes without effect vary more than
random sets of barcodes; the random barcodes ignore this and give too
small p-values. Use plot_empirical_null to check the fit.
In the benchmarks (core essential and non-essential genes of Hart et al., half of the non-essential genes kept out to count the false calls), in the genome-wide HAP1 CRISPR screen (TKOv3) the default found 58% of the core essential genes at 5% FDR and the empirical null 90% ("central") and 94% ("one-sided"), with 2 and 5 non-essential genes called. In the K562 shRNA screen the random barcodes gave too small p-values: with control_genes 20% of the non-essential genes had a p-value below 0.05 (50 to 57 called), and with the default 13% when the essential genes were as rare as in a genome-wide library. The empirical null kept this below 4% (no non-essential gene called) and found 30% of the essential genes: the shRNAs of many essential genes do not separate them from the genes without effect. "central" never gave too small p-values; "one-sided" has more power when the hits are well separated (CRISPR screens) but was too conservative in the shRNA screen.
The empirical null needs most genes to be without effect, and enough
genes (hundreds) to estimate it. It is not used with control_genes.
The benchmark script is benchmark/realdata/empirical_null.R in the
GitHub repository. The vignette "Choosing the reference of the
gene-level test" (vignette("Empirical_null", package =
"ScreenR")) explains when to use each reference; we suggest
reference = "empirical" for libraries with hundreds of genes, most of
them without effect.
This replaces the rule of find_zscore_hit ("more than
number_barcode barcodes below the median"), which flags about 17% of
the genes without any effect when genes have 10 barcodes and
number_barcode = 6.
Examples
object <- get0("object", envir = asNamespace("ScreenR"))
table <- compute_metrics(object,
control = "Time3", treatment = "TRT",
day = "Time3"
)
find_gene_zscore_hit(table, fdr = 1, n_permutations = 1000, seed = 1)
#> # A tibble: 534 × 6
#> Gene NBarcodes Score Log2FC PValue FDR
#> <chr> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 Gene_377 10 -1.11 -0.259 0.00200 0.934
#> 2 Gene_500 9 -1.17 -0.152 0.00400 0.934
#> 3 Gene_86 10 -0.855 -0.340 0.00699 0.934
#> 4 Gene_511 9 -0.906 -0.203 0.0140 0.934
#> 5 Gene_245 32 -0.402 -0.0162 0.0160 0.934
#> 6 Gene_173 10 -0.724 -0.221 0.0200 0.934
#> 7 Gene_316 10 -0.707 -0.117 0.0220 0.934
#> 8 Gene_116 10 -0.636 -0.275 0.0270 0.934
#> 9 Gene_305 10 -0.634 -0.271 0.0270 0.934
#> 10 Gene_340 10 -0.637 -0.115 0.0270 0.934
#> # ℹ 524 more rows
# Empirical null
find_gene_zscore_hit(table, fdr = 1, reference = "empirical")
#> # A tibble: 534 × 7
#> Gene NBarcodes Score Log2FC Statistic PValue FDR
#> <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Gene_377 10 -1.11 -0.259 -4.86 0.0000963 0.0261
#> 2 Gene_500 9 -1.17 -0.152 -4.86 0.0000978 0.0261
#> 3 Gene_511 9 -0.906 -0.203 -3.77 0.00195 0.274
#> 4 Gene_86 10 -0.855 -0.340 -3.75 0.00205 0.274
#> 5 Gene_173 10 -0.724 -0.221 -3.18 0.00749 0.668
#> 6 Gene_245 32 -0.402 -0.0162 -3.17 0.00767 0.668
#> 7 Gene_316 10 -0.707 -0.117 -3.10 0.00875 0.668
#> 8 Gene_438 9 -0.675 -0.0995 -2.81 0.0157 0.725
#> 9 Gene_340 10 -0.637 -0.115 -2.80 0.0162 0.725
#> 10 Gene_353 10 -0.636 -0.176 -2.79 0.0163 0.725
#> # ℹ 524 more rows
