Statistical methods for calling hits in CRISPR screens. Covers MAGeCK, BAGEL2, drugZ, and custom approaches for identifying essential and resistance genes. Use when identifying significant genes from screen count data after QC passes.
Before using code patterns, verify installed versions match. If versions differ:
Python: pip show <package> then help(module.function) to check signatures
CLI: <tool> --version then <tool> --help to confirm flags
If code throws ImportError, AttributeError, or TypeError, introspect the installed
package and adapt the example to match the actual API rather than retrying.
CRISPR Screen Hit Calling
"Identify essential genes from my CRISPR screen" → Call significant gene hits from sgRNA count data using statistical methods that account for guide-level variability and multiple testing.
CLI: BAGEL.py bf for Bayes factor essentiality scoring
Python: drugZ for fold-change based analysis
BAGEL2 Analysis
Goal: Identify essential genes using Bayesian classification against reference gene sets.
Approach: Calculate sgRNA fold changes, compute Bayes Factors using known essential and non-essential gene sets as training data, and assess precision-recall at different thresholds.
# For screens with multiple timepoints
def time_course_hits(counts, timepoints, genes):
'''Identify genes with consistent depletion over time'''
lfc_by_time = {}
for t in timepoints:
t0_cols = [c for c in counts.columns if 'T0' in c]
t_cols = [c for c in counts.columns if f'T{t}' in c]
t0_mean = counts[t0_cols].mean(axis=1)
t_mean = counts[t_cols].mean(axis=1)
lfc_by_time[t] = np.log2((t_mean + 1) / (t0_mean + 1))
# Aggregate and check for consistent direction
lfc_df = pd.DataFrame(lfc_by_time)
lfc_df['Gene'] = genes
gene_summary = lfc_df.groupby('Gene').mean()
gene_summary['all_negative'] = (gene_summary < 0).all(axis=1)
gene_summary['trend'] = gene_summary.apply(lambda x: np.polyfit(range(len(timepoints)), x[:-1], 1)[0], axis=1)
return gene_summary[gene_summary['all_negative']].sort_values('trend')
Visualize Results
import matplotlib.pyplot as plt
# Rank plot
fig, ax = plt.subplots(figsize=(10, 6))
results = pd.read_csv('mageck.gene_summary.txt', sep='\t')
results = results.sort_values('neg|score')
results['rank'] = range(1, len(results) + 1)
ax.scatter(results['rank'], -np.log10(results['neg|fdr']),
c=['red' if fdr < 0.05 else 'gray' for fdr in results['neg|fdr']],
alpha=0.5, s=10)
# Label top hits
top = results[results['neg|fdr'] < 0.01].head(10)
for _, row in top.iterrows():
ax.annotate(row['id'], (row['rank'], -np.log10(row['neg|fdr'])))
ax.axhline(-np.log10(0.05), linestyle='--', color='black')
ax.set_xlabel('Gene Rank')
ax.set_ylabel('-log10(FDR)')
ax.set_title('CRISPR Screen Hits')
plt.savefig('hit_ranking.png', dpi=150)
Related Skills
mageck-analysis - MAGeCK workflow
screen-qc - QC before hit calling
pathway-analysis/go-enrichment - Functional analysis of hits