--- title: "Interactive Analysis with the cellreportR Shiny App" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Interactive Analysis with the cellreportR Shiny App} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} resource_files: - figures/logo.svg - figures/logo-dark.svg --- ```{r setup, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") library(cellreportR) ``` The bundled application walks the same pipeline as the package functions — read segmented exports, specify the design, apply quality control at cell and unit level, standardize, estimate effect sizes with confidence intervals at both levels, export a report — in a browser rather than in a script. It is meant for laboratory personnel without an R background, and for anyone who wants to look at a data set before writing the script. Every analytical step in the app delegates to an exported `cr_*` function, so the app and a scripted analysis produce the same numbers. ## Launching ```{r launch, eval = FALSE} library(cellreportR) cr_run_app() # starts empty; example data is one click away cr_run_app(experiment = my_exp) # start from an experiment already in session ``` `cr_run_app()` needs `shiny`, `bslib`, `DT` and `ggplot2`, all of which are listed under `Suggests`; a missing one raises an error naming it. The upload limit is raised to 512 MB for the duration of the session, because segmented single-cell exports routinely exceed the Shiny default of 5 MB, and the previous value is restored on exit. ```{r args} args(cr_run_app) ``` ## Layout The page has four fixed regions: * a **sidebar**, always visible, holding the three things every tab depends on — where the data comes from, which marker channel the analysis targets, and which level of the design is the control; * a **status card** with a running log of what the app has done, so an analysis can be reconstructed afterwards; * the **tab strip**, in analysis order; * an **About** card. ### The sidebar 1. **Data source** — upload one or more segmented exports, or type the path of a directory and let the app read it with a file pattern and an optional recursive scan. `Load example data` fills the app with a synthetic multi-compound screen (`cr_example_screen()`) when there is nothing to hand. 2. **Design** — upload a design table (`.csv`, `.tsv` or `.xlsx`), or build one in the Design tab. 3. **Analysis target** — the marker channel and the control level. Every tab downstream reads these two selectors, so changing the control level here changes what every later tab compares against. The whole experiment can be downloaded as an `.rds` from the sidebar at any point, which is the bridge from the app back to a script. ### The tabs | Tab | What it does | Backed by | |---|---|---| | **Data** | Cell table, the files that were read, detected channels | `cr_read_cells()`, `cr_read_exports()` | | **Design** | Derive one design row per unit, assign treatment levels, build the experiment | `cr_build_experiment()` | | **Quality control** | Cell filters, doublet removal, and the per-unit gate against each unit's own control | `cr_qc_filter()`, `cr_qc_doublets()`, `cr_qc_gate()`, `cr_apply_gate()` | | **Normalisation** | Robust z-score, z-score, control ratio, background subtraction or quantile, optionally within a batch variable | `cr_normalize()`, `cr_correct_batch()` | | **Effect sizes** | Forest plot and effect table at unit or cell level | `cr_effect_grid()`, `cr_plot_forest()` | | **Dose-response** | 4PL / 3PL / linear fit with the fitted parameters | `cr_dose_response()`, `cr_ic50()` | | **Figures** | Plate map, intensity by treatment, histogram, QC dashboard, spatial map | `cr_plot_plate()` and friends | | **Report** | Pairwise comparisons, queued figures, and the exported report | `cr_report()`, `cr_render_report()` | The Quality control tab is the one worth spending time in. Its sub-panels are the exclusion table, the disputed verdicts (units whose verdict depends on whether the control's median or mean is used as the threshold), the gate figure, the area distribution and the QC log. Rows selected in the exclusion table are dropped together with the units that fail the gate, which is the interactive form of the reviewed exclusion list shown in `vignette("end-to-end")`. ## Cross-tab state The app keeps everything it knows in one `shiny::reactiveValues()` store: the cells, the design, the assembled experiment, the state it was imported in, the gate, the effect grid, the results and the queued figures. Quality control, normalisation and analysis replace the experiment in that store, so every downstream tab reacts without any tab reaching into another. Two consequences worth knowing: * **Reset is real.** `Reset to imported state` in the Quality control and Normalisation tabs restores the experiment as it was imported, not the previous step. * **Figures are queued, not saved.** `Queue for report` adds the current figure to the report assembly; the Report tab exports the queue. ## Deployment The user interface, the server and every helper live inside the package namespace, so the app can be driven in-process by `shiny::testServer()` as well as from a browser. `inst/shiny/cellreportR/` holds only the `www/` assets and a thin `app.R` shim for deployment on a Shiny server. The Effect sizes tab offers **Stratify contrasts by**. Select the design column whose groups must be analyzed separately; `compound` is selected when present. Each stratum uses its own control observations, and tables, CSV downloads and forest facets retain its identity. The declared `metadata$control_level` is the initial control when valid. Changing data, channel, control, stratum, level or confidence clears the previous effect result; press **Estimate effect sizes** again before downloading. Selecting `(none)` explicitly pools the strata.