LDH Cytotoxicity Assay Analysis App


User Guide

1. Overview

This Shiny application automates the analysis of Lactate Dehydrogenase (LDH) cytotoxicity assay data. It processes raw 96-well plate reader data to calculate, analyze, and visualize percent cytotoxicity, culminating in a publication-ready interactive plot and a downloadable report.

This version includes several powerful features for flexibility and reproducibility:

2. How to Use the Application

Step 1: Prepare Your Input Files

You need two .csv files: a plate layout file and a raw absorbance file.

A. Plate Layout File (e.g., layout.csv)

This file maps the contents of each well.

Important: Naming Convention for Per-Treatment Controls

To link an experimental group to its specific maximum lysis control, you must name the control using a consistent prefix. The default is Tritonx100-.

For a treatment group named DrugA, its corresponding max lysis control must be named Tritonx100-DrugA. The text that comes after the prefix must match exactly.

Example layout.csv:
1,2,3,4,5,6
empty,empty,empty,Vehicle,Vehicle,Vehicle
empty,empty,empty,DrugA,DrugA,DrugA
untreated,untreated,untreated,Tritonx100-Vehicle,Tritonx100-Vehicle,Tritonx100-Vehicle
untreated,untreated,untreated,Tritonx100-DrugA,Tritonx100-DrugA,Tritonx100-DrugA
...
B. Raw Absorbance File (e.g., absorbance.csv)

This file contains the raw optical density (OD) readings from the plate reader.

Step 2: Upload Files & Define Controls

In the sidebar, upload your two files. After uploading the layout, dynamic dropdowns will appear. Use these to configure your analysis:

  1. Define Calculation Controls:
    • Spontaneous Lysis: Select the group name for your untreated cells.
    • Max Lysis Prefix: Confirm or change the prefix used to identify max lysis groups.
    • Blank: Select the group name for your media-only wells.
  2. Define Analysis Settings:
    • Comparison Control: Select the group that will serve as the baseline for statistical comparisons (e.g., a "Vehicle" or "DMSO" control).
    • Statistical Test Method: Choose "Automatic Selection" to let the app decide between ANOVA and Kruskal-Wallis based on assumption checks, or manually override the choice.

Step 3: Execute and Export

Click the "Run Analysis" button to process the data. Once complete, you can download the final processed data from the "Processed Data Preview" tab or download a complete HTML report using the "Download Report" button.

3. Interpreting the Output Tabs

4. Methodology

The app calculates percent cytotoxicity using the formula:

$$ \text{Cytotoxicity (\%)} = \frac{(\text{Corrected OD}_{\text{Experimental}} - \text{Mean OD}_{\text{Spontaneous}})}{(\text{Mean OD}_{\text{Maximum}} - \text{Mean OD}_{\text{Spontaneous}})} \times 100 $$

Where Corrected OD = OD490nm - OD680nm. The Mean ODMaximum is calculated specifically for each treatment "family", ensuring accurate normalization.


Code Logic Documentation

This section outlines the internal workings of the server function.

1. Dynamic UI Rendering

Reactive expressions read the unique group names from the uploaded layout file. A series of renderUI functions then use this list to populate the choices in the sidebar dropdowns, making the entire interface adapt to the user's data.

2. The Main Analysis Pipeline (eventReactive)

The core logic is wrapped in an eventReactive(), which executes only when the "Run Analysis" button is clicked.

  1. Input Validation: The app first checks if all required files and inputs are present. It then uses validate() and need() to perform a series of checks (e.g., is the file a valid CSV? Do the selected controls exist in the data?) and provides user-friendly error messages if a check fails.
  2. Data Processing: Raw absorbance data is background-corrected (490nm - 680nm). The layout and absorbance data are tidied and merged into a single data frame.
  3. Group-Specific Normalization: This is a key feature. A "treatment family" ID is created for each well by removing the user-defined max lysis prefix. The app then calculates a unique mean maximum lysis absorbance for each family and joins this value back to the main dataset. This ensures every well is normalized against its specific maximum lysis control.
  4. Final Calculation & Filtering: The cytotoxicity formula is applied. All control groups (blank, spontaneous, and max lysis) are then filtered out, leaving a clean dataset for analysis. The group column is re-factored to ensure filtered-out groups do not appear on the plot axis.
  5. Statistical Analysis: Assumption checks (Shapiro-Wilk, Levene's) are performed. Based on these results or the user's choice, the appropriate path (ANOVA or Kruskal-Wallis) is taken.
  6. Plot Generation: An interactive plot is built using ggplot2 and ggiraph. Tooltips are added to the data points, and significance bars are generated using ggpubr.
  7. Return Results: All generated objects (the plot, tables, p-values, processed data, etc.) are collected into a single list and returned by the reactive expression.

3. Output Rendering and Downloads

The final part of the server consists of render functions (renderGirafe, renderDataTable, renderUI) and download handlers (downloadHandler). Each of these functions accesses the required item from the analysis_results() list and displays it in the UI or prepares it for download.