An interactive Shiny web application for exploring PCA plots from RNA-seq analysis across different fibroblast priming experiments.
The easiest way to run the app is using Docker:
# 1. Download and extract the data directory
aws s3 cp s3://ucla-rare-diseases/UCLA-UDN/gcarvalho_test/rnaseq/portal/rnaseq-portal-data.zip .
unzip rnaseq-portal-data.zip
# 2. Build and run with Docker Compose
docker-compose up -d
# 3. Access the app at http://localhost:3838Or using Docker directly:
# Build the image
docker build -t rnaseq-portal .
# Run the container
docker run -d -p 3838:3838 -v $(pwd)/data:/app/data:ro --name rnaseq-portal rnaseq-portal
# Access the app at http://localhost:3838# 1. Download and extract the data directory
aws s3 cp s3://ucla-rare-diseases/UCLA-UDN/gcarvalho_test/rnaseq/portal/rnaseq-portal-data.zip .
unzip rnaseq-portal-data.zip
# 2. Navigate to the main directory
cd /path/to/CCRD-RNAseq-portal/main/
# 3. Launch the Shiny app
R -e "shiny::runApp('app.R')"- Interactive Plot Selection: Switch between different experiment views with a dropdown
- All Experiments Overview: Shows all samples colored by experiment number
- Individual Experiments: Dedicated visualizations for Experiments 4, 5, 6, and 7
- Interactive Gene Selection: Enter custom gene names for FPE6 and FPE7 gene expression plots
- Modular Code Structure: Easy customization of individual experiment plots
- Real-time Updates: Plots change instantly when selections are made
- Intelligent Gene Search: Automatic gene matching with fallback to most expressed genes
- Grouped Box Plots: FPE6 gene counts displayed with separate box plots for TNFΞ±+ and TNFΞ±- samples
install.packages(c("shiny", "ggplot2", "foreach", "doMC", "gridExtra"))if (!require("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("DESeq2")CCRD-RNAseq-portal/
βββ README.md # This comprehensive guide
βββ DOCKER.md # Docker deployment guide
βββ Dockerfile # Docker image definition
βββ docker-compose.yml # Docker Compose configuration
βββ .dockerignore # Docker build exclusions
βββ data/ # Data directory (download from S3)
β βββ gene-counts_FPE/ # Count matrix files (231 files)
β βββ metadata.csv # Sample metadata
β βββ fpe6_deseq_precomputed.rds # Pre-computed FPE6 DESeq analysis
β βββ fpe7_deseq_precomputed.rds # Pre-computed FPE7 DESeq analysis
βββ main/
β βββ app.R # Main Shiny application
β βββ modules/ # Modular plot functions
β βββ plot_all.R # All experiments overview
β βββ plot_fpe4.R # Experiment 4 plot
β βββ plot_fpe5.R # Experiment 5 plot
β βββ plot_fpe6.R # Experiment 6 plot (with gene counts)
β βββ plot_fpe7.R # Experiment 7 plot (with gene counts)
βββ scripts/ # Plotting and pre-computation scripts
βββ PCA-plot_all.R
βββ PCA-plot_FPE4.R
βββ PCA-plot_FPE5.R
βββ PCA-plot_FPE6.R
βββ PCA-plot_FPE7.R
βββ FPE6_plot-counts_by-treatment.R # FPE6 gene count visualization
βββ FPE7_plot-counts_by-treatment.R # FPE7 gene count visualization
βββ precompute_fpe6_deseq.R # Pre-compute FPE6 DESeq analysis
βββ precompute_fpe7_deseq.R # Pre-compute FPE7 DESeq analysis
| Experiment | Visualization | Color | Shape | Special Features |
|---|---|---|---|---|
| All | Overview of all samples | FPE number | TNFΞ± treatment | Complete dataset view |
| Experiment 4 | FPE4 samples only | Source | Treatment | Focus on treatment effects |
| Experiment 5 | FPE5 samples only | Sub-treatment | Co-treatment | Black highlighting for 'none' |
| Experiment 6 | FPE6 PCA + Gene Count | Sub-treatment | TNFΞ± status | Combined: PCA plot + Interactive gene expression with grouped box plots |
| Experiment 7 | FPE7 PCA + Gene Count | Participant ID | Treatment | Combined: PCA plot + Interactive gene expression |
Experiment 6 features interactive gene selection with grouped box plots:
- Select "Experiment 6" from the dropdown
- Enter a gene symbol (e.g.,
CXCL8,DMD) OR an Ensembl ID (e.g.,ENSG00000169429) in the Gene Name text box - Press Enter or click elsewhere to update the plot
- The gene expression plot updates instantly with your selected gene
- Dual Box Plots: Shows two box plots per sub-treatment - one for TNFΞ±+ samples and one for TNFΞ±- samples
- Color Coding: Orange (#f1a340) for TNFΞ±+ and Purple (#998ec3) for TNFΞ±-
- Individual Points: Overlaid jittered points show individual sample values
- Log Scale: Y-axis uses log10 scale for better visualization of expression ranges
- 12 Sub-treatments: TNFa, Rapamycin, TGFb+Rapa, TGFb, TGFb+SB, SB, Rapa+SB, KC7F2, TGFb+KC7F2, EGFRi, EGFRi+EGF, EGF
The app supports both gene symbols and Ensembl IDs using a comprehensive genes reference database:
- Gene Symbols: Direct lookup using
genes$external_gene_nameto find corresponding Ensembl ID - Ensembl IDs: Automatically detected (starting with "ENSG"), mapped to gene symbol
- Fallback Strategy: If gene not found, shows the most highly expressed gene with a warning
Gene Symbols (inflammation and fibrosis markers):
CXCL8: Interleukin-8 (default) - inflammatory chemokineIL6: Interleukin-6 - pro-inflammatory cytokineCOL1A1: Collagen Type I Alpha 1 - fibrosis markerACTA2: Alpha-smooth muscle actin - myofibroblast markerTGFB1: Transforming growth factor beta 1
Ensembl IDs:
ENSG00000169429: CXCL8 (Interleukin-8)ENSG00000136244: IL6 (Interleukin-6)ENSG00000108821: COL1A1 (Collagen Type I Alpha 1)
Experiment 7 includes interactive gene selection with time series analysis:
- Select "Experiment 7" from the dropdown
- Enter a gene symbol (e.g.,
DMD,ACTA1) OR an Ensembl ID (e.g.,ENSG00000198947) in the Gene Name text box - Press Enter or click elsewhere to update the plot
- The gene expression plot updates instantly with your selected gene
The app supports both gene symbols and Ensembl IDs using a comprehensive genes reference database (86,402 entries):
- Direct Lookup: Uses
genes$external_gene_nameto find the corresponding Ensembl ID - Count Matrix Search: Searches count matrix row names using
startsWith()with the Ensembl ID prefix - Exact Matching: Finds genes where row names start with the correct Ensembl ID
- ID Detection: Automatically detects Ensembl IDs (starting with "ENSG")
- Gene Name Lookup: Uses
genes$ensembl_gene_idto find the corresponding gene symbol - Count Matrix Search: Proceeds with normal search using the mapped gene symbol
If gene not found in reference, shows the most highly expressed gene with a warning
DMD: Duchenne muscular dystrophy gene (default)TTR: TransthyretinACTA1: Skeletal muscle alpha-actinMYH7: Cardiac/skeletal muscle myosinGAPDH: Housekeeping gene control
ENSG00000198947: DMD (Duchenne muscular dystrophy)ENSG00000132664: TTR (Transthyretin)ENSG00000143632: ACTA1 (Skeletal muscle alpha-actin)ENSG00000092054: MYH7 (Cardiac/skeletal muscle myosin)
- Open the specific module:
modules/plot_fpe4.R - Make your changes (see examples below)
- Save the file
- Restart the app:
shiny::runApp('app.R')
# In any module, find:
scale_color_brewer(palette = 'Dark2')
# Replace with custom colors:
scale_color_manual(values = c("red", "blue", "green", "purple"))# Find:
ggtitle(label = 'Fibroblast Priming #4')
# Replace with:
ggtitle(label = 'My Custom Experiment 4 Title')# Add sample labels:
+ geom_text(aes(label = sample_id), size = 2, hjust = 1.1)
# Add trend lines:
+ geom_smooth(method = "lm", se = FALSE, alpha = 0.5)
# Modify point size:
geom_point(size = 4) # Change from size = 3# Available Brewer palettes:
scale_color_brewer(palette = 'Set1') # Bright colors
scale_color_brewer(palette = 'Dark2') # Darker colors
scale_color_brewer(palette = 'Set3') # Pastel colors
scale_color_brewer(palette = 'Spectral') # Rainbow colorsβ
Independent Editing: Modify one experiment without affecting others
β
Error Isolation: Problems in one plot won't break the entire app
β
Team Collaboration: Multiple people can work on different experiments
β
Clean Code: Each function is self-contained and well-documented
β
Easy Testing: Test individual modules independently
For detailed Docker documentation, troubleshooting, and production deployment guide, see DOCKER.md.
# Build with docker-compose
docker-compose build
# Or build directly
docker build -t rnaseq-portal .# Start with docker-compose (recommended)
docker-compose up -d
# Or run directly
docker run -d -p 3838:3838 -v $(pwd)/data:/app/data:ro --name rnaseq-portal rnaseq-portal# View logs
docker-compose logs -f
# Or: docker logs -f rnaseq-portal
# Stop the container
docker-compose down
# Or: docker stop rnaseq-portal
# Restart the container
docker-compose restart
# Or: docker restart rnaseq-portal
# Remove the container
docker-compose down -v
# Or: docker rm -f rnaseq-portalOnce running, access the app at: http://localhost:3838
- Base Image:
rocker/r-ver:4.3 - Installed Packages: shiny, ggplot2, foreach, doMC, gridExtra, DESeq2
- Port: 3838
- Data Volume: Mounted at
/app/data(read-only) - Health Check: Enabled with 30s interval
To update the data without rebuilding:
# Stop the container
docker-compose down
# Update your data directory
aws s3 cp s3://ucla-rare-diseases/UCLA-UDN/gcarvalho_test/rnaseq/portal/rnaseq-portal-data.zip .
unzip -o rnaseq-portal-data.zip
# Restart the container
docker-compose up -d- Create new module:
modules/plot_fpe8.R
generate_fpe8_plot <- function(cts, coldata) {
tryCatch({
# Filter for your experiment
selected.samples <- coldata$FPE.num == 'FPE8'
# Check data availability
if(sum(selected.samples) == 0) {
stop("No FPE8 samples found")
}
# Create DESeq2 object
dds <- DESeqDataSetFromMatrix(
countData = cts[, selected.samples],
colData = coldata[selected.samples, ],
design = ~ treatment)
vsd <- vst(dds, blind = FALSE)
# Generate PCA
pcaData <- plotPCA(object = vsd, intgroup = c('treatment'), returnData = TRUE)
percentVar <- round(100 * attr(pcaData, 'percentVar'))
# Create plot
ggplot(pcaData, aes(x = PC1, y = PC2, color = treatment)) +
geom_point(size = 3) +
xlab(paste0('PC1: ', percentVar[1], '% variance')) +
ylab(paste0('PC2: ', percentVar[2], '% variance')) +
coord_fixed() +
ggtitle('Fibroblast Priming #8') +
theme_minimal()
}, error = function(e) {
# Error handling
ggplot(data.frame(x = 1, y = 1), aes(x, y)) +
geom_text(label = paste("Error in FPE8 plot:", e$message), color = "red")
})
}- Update main app.R:
- Add
source("modules/plot_fpe8.R")in the module loading section - Add
"Experiment 8" = "fpe8"to the UI dropdown choices - Add
"fpe8" = generate_fpe8_plot(cts, coldata)to the server switch statement
- Add
# Test a specific module
source("modules/plot_fpe4.R")
# Test with your data (after loading in R console)
plot <- generate_fpe4_plot(cts, coldata)
print(plot)- β
Check Docker is running:
docker ps - β Verify data directory exists and is in the right location
- β
Check logs:
docker-compose logsordocker logs rnaseq-portal - β
Ensure port 3838 is not already in use:
lsof -i :3838(macOS/Linux)
- β
Verify container is running:
docker ps - β
Check health status:
docker inspect rnaseq-portal | grep -A 5 Health - β
Confirm port mapping: should see
0.0.0.0:3838->3838/tcp - β Try accessing: http://localhost:3838
- β
Verify data volume is mounted:
docker inspect rnaseq-portal | grep -A 10 Mounts - β Check data directory contains expected files
- β Ensure data was downloaded and extracted correctly
- β Verify file permissions (data should be readable)
- β
Check all R packages are installed (
DESeq2,shiny,ggplot2, etc.) - β
Verify data files exist:
../data/metadata.csvand../data/gene-counts_FPE/ - β
Ensure you're in the
main/directory when running the app - β Check R console for specific error messages
- β Look for error messages in R console
- β Verify the experiment has samples (check FPE numbers in metadata)
- β
Test individual modules with
source("modules/plot_name.R")
- β Check function syntax (missing commas, unmatched parentheses)
- β Ensure required data columns exist in your metadata
- β
Verify all
aes()mappings reference valid column names
- β
Confirm file paths are correct (
../data/relative tomain/directory) - β Check file permissions and readability
- β Verify count files are in expected format
The complete data/ directory is available from S3:
aws s3 cp s3://ucla-rare-diseases/UCLA-UDN/gcarvalho_test/rnaseq/portal/rnaseq-portal-data.zip .
unzip rnaseq-portal-data.zipThis archive includes all necessary files: count matrices, metadata, pre-computed DESeq analyses, and gene reference databases.
- Format: Tab-separated text files
- Columns:
gene_idand count values - Naming: Must end with
.gene_id.exon.ct.short.txt
- Required columns:
experiment_rna_short_read_id,participant_id,affected_status - Sample IDs should match count file names (after removing suffix)
- FPE numbers extracted from sample IDs (format:
FPE4-...,FPE5-..., etc.)
# Define custom colors for specific values
custom_colors <- c("control" = "#1f77b4", "treated" = "#ff7f0e", "combo" = "#2ca02c")
scale_color_manual(values = custom_colors)# Add hover information (requires plotly)
library(plotly)
ggplotly(your_plot, tooltip = c("x", "y", "colour"))# Save plots programmatically
ggsave("experiment4_plot.png", plot, width = 8, height = 6, dpi = 300)- Data Loading: Count matrix (62,757 genes Γ 231 samples) loads once at startup
- Plot Generation: PCA calculations performed on-demand when switching experiments
- FPE6 & FPE7 Optimization: Pre-computed DESeq analysis loaded at startup for instant plot generation
- Memory Usage: ~250MB RAM for typical dataset size (includes pre-computed results)
- Load Time: ~30-60 seconds initial startup, <2 seconds plot switching (FPE6 & FPE7 now instant!)
Experiments 6 and 7 use pre-computed DESeq2 results for lightning-fast plot generation:
- Pre-computed: DESeq analysis runs once offline (~4 minutes per experiment)
- Runtime: Plot generation now takes <2 seconds instead of 3-4 minutes
- Auto-loading: Pre-computed results loaded automatically at app startup
- Grouped Visualization: FPE6 displays dual box plots (TNFΞ±+ vs TNFΞ±-) for each sub-treatment
If you update your data, regenerate the pre-computed DESeq analysis:
# Navigate to scripts directory
cd scripts/
# Run pre-computation for FPE6 (takes ~4 minutes)
Rscript precompute_fpe6_deseq.R
# Run pre-computation for FPE7 (takes ~4 minutes)
Rscript precompute_fpe7_deseq.R
# Restart your Shiny app to use new resultsWhen to regenerate:
- After adding/removing FPE6 or FPE7 samples
- After updating count data or metadata
- When changing DESeq2 analysis parameters
For questions or issues:
- Check the troubleshooting section above
- Look for error messages in the R console
- Test individual modules independently
- Verify data file formats and paths
𧬠Happy RNA-seq analysis! This modular structure makes your portal highly customizable and maintainable. β¨