--- title: "Using the gtstats App" description: "A beginner-friendly manual for the menu-driven gtstats Shiny app." output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Using the gtstats App} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", eval = FALSE) ``` # gtstats App Manual The `gtstats` app is a menu-driven companion to the package. It is designed for users who want to understand a dataset, create publication-ready tables, run common group comparisons and correlation analyses, and generate reproducible R code without first memorising every argument. The app does not replace a reproducible analysis script. Its best use is: 1. Load or upload data. 2. Work through the analysis one tab at a time. 3. Review the publication-ready result and its audit information. 4. Copy or download the generated R code. 5. Run and save that code in RStudio or a Quarto document. Each analysis includes a **Code** panel with **Copy code** and **Download .R** buttons. The app is intended to teach the workflow while making the final analysis reproducible and shareable. ## Launch the app Install and load gtstats, then run: ```r library(gtstats) gtstats_app() ``` When started from RStudio, the default is the RStudio Viewer. Outside RStudio, the app opens in a browser during an interactive R session. To explicitly use your browser: ```r gtstats_app(launch.browser = TRUE) ``` To start the local app without opening a window automatically: ```r gtstats_app(launch.browser = FALSE) ``` ## Close the app safely While a Shiny app is open, the R console displays text such as: ```text Listening on http://127.0.0.1:6783 ``` This is normal: R is running the local app server. Use the **Close app** button in the bottom-right corner of the app to end it cleanly and return to the R prompt. Avoid interrupting it with RStudio's Stop button. If R ever enters a `Browse[1]>` prompt after an interrupted session, type: ```r Q ``` and press Enter. ## App dependencies The app is only launched when `gtstats_app()` is called, so users who prefer ordinary R code do not need its optional dependencies. | Purpose | Package | |---|---| | App interface | `shiny` | | RStudio Viewer support | `rstudioapi` where available | | Table display and export | `gt`, `flextable` | | Excel upload | `rio` (optional) | For Excel input, install `rio` once: ```r install.packages("rio") ``` # Recommended app workflow The tabs are deliberately ordered to follow a safe statistical workflow. 1. **Data** — choose a teaching dataset, a data frame already in the R environment, or upload a file. 2. **Data Prep** — optionally make safe, reversible changes before analysis. 3. **Understand** — inspect types, completeness, distribution, and spread. 4. **Summary table** — create the descriptive table for a report. 5. **Epi table** — estimate outbreak and surveillance measures using an explicit event and denominator. 6. **Customise table** — refine the completed Summary or epidemiology table without changing results. 7. **Compare groups** — answer one focused inferential question. 8. **Correlation** — analyse a continuous pair or build a correlation matrix. 9. **Crosstabs** — inspect categorical association and 2×2 measures. 10. **History** — see which analyses were run during this session. 11. **Help** — revisit the safe beginner workflow. The app will not run a summary table, comparison, correlation, or cross-tab until you press the relevant action button. This prevents accidental analysis while the app is loading or while a browser restores an earlier session. The original imported dataset is active automatically. Opening Data Prep does not silently replace it. After making changes, click **Use prepared data** only when you want later tabs to analyse the working copy; otherwise analyses carry forward the original data. On a phone or narrow screen, use the menu icon in the top-right to open the full tab list. The numbered workflow strip remains visible below it and can be swiped sideways; no analysis tab is hidden or removed on smaller screens. # Data tab
Screenshot 1 — App overview and Data tab Replace this block with a wide screenshot showing the top menu, numbered workflow, teaching-dataset selector, upload control, active-data message, and Close app button.
Suggested file: vignettes/images/app-01-overview-data.png
Use the **Data** tab first. Choose a labelled teaching dataset, select a data frame or tibble that already exists in the current R environment, or upload a file. **Refresh data-frame list** detects objects created after the app was opened. Only data-frame-like objects are offered, which prevents accidental selection of models, functions, or vectors. Uploads support CSV, Excel (`.xlsx`/`.xls`), R data (`.rds`), Stata (`.dta`), and SPSS (`.sav`). Excel, Stata, and SPSS files use the optional `rio` package. Environment selection is intended for the locally launched app; a remotely hosted app cannot inspect objects in a visitor's desktop R session. # Data Prep tab
Screenshot 2 — Data Prep command bar and preview Show the explicit preparation menus, structured action form, before/after preview, change log, Undo/Redo, and Use prepared data button.
Suggested file: vignettes/images/app-02-data-prep.png
**Data Prep** is optional. It is for small, auditable changes before analysis, not a replacement for a full data-management workflow. The imported dataset is kept unchanged; each action changes an independent working copy. The command bar lists every available action explicitly. Click the task you need, complete the structured fields that appear, then click **Apply this change**. The current version provides eight common operations: | Operation | Use it for | Safety check | |---|---|---| | Rename variable | Clearer variable names | Blank, duplicate, and invalid R names are rejected | | Recode values | Give every recorded value a clear label, for example `0/1` to `No/Yes` | The mapping grid shows source and new labels side by side; ordered mode uses the displayed order | | Set type and order | Make values categorical, ordered categorical, numeric, or text | The display-order grid appears only for ordered categorical values; every level must have one different position | | Manage missing values | Convert recorded codes such as `999` or `Unknown` to `NA`, or show existing `NA` values as a labelled category | The app reports affected cells and warns that a Missing category changes analysis | | Create calculation | Adjust one variable, combine two numeric variables, or calculate a ratio with a powered denominator (for example BMI) | Source variables are retained; preview shows usable rows | | Create groups | Build a two-, three-, or four-group variable from one source variable | Give every group a label; conditions are checked top to bottom and the first match wins | | Filter observations | Keep records meeting one or two inclusion criteria | A second condition is optional; preview shows kept, excluded, and unknown counts | | Keep variables | Choose the columns for a smaller analysis dataset | Searchable multi-select, Keep all, and Clear selection controls; Undo restores removed columns | The **Quick starts** buttons are fill-only helpers. **Age groups** proposes a two-group age variable using a 65-year cut-off; **0/1 to No/Yes** opens a matching binary recode when a variable coded exactly `0` and `1` is found; **BMI-style calculation** sets up `numerator / (denominator ^ 2)`; and **99/999 to missing** opens the missing-code workflow. None of these buttons applies a change. They are deliberately starting points, so verify the selected variable, coding, units, cut-offs, and labels before pressing **Apply this change**. For numeric grouping, choose equal to, not equal to, greater/less than, greater/less than or equal to, **between (inclusive)**, or **outside a range**. Range rules show a second field for the upper bound. Between means `x >= lower & x <= upper`; outside means `x < lower | x > upper`. Both bounds must be numeric, the lower bound cannot exceed the upper bound, and range rules are unavailable for non-numeric variables. The preview shows each proposed group's count and blocks an Apply action if any group would be empty. The final group is always everyone else, and rules are evaluated from top to bottom. Before applying, the panel states the expected impact: for example, how many values will be recoded, how many codes will become missing, or how many rows a filter will keep. For recoding, missing-value changes, group creation, and filtering, it also shows a compact **Before you apply** table with the exact values or row counts expected to change. The right-hand preview and the **Change log** update immediately after you click **Apply this change**. Use **Undo**, **Redo**, or **Reset all** to reverse work safely. When an action uses a categorical variable, the panel also shows its exact recorded values and offers **Copy values**. Recode values creates a mapping grid with one row per observed value and pre-fills each new label with its existing value. Edit only the labels that need changing. This avoids guessing whether a dataset records a value as `Yes`, `yes`, `Y`, or `1`. Tick **Treat as ordered categorical, in the order shown** only if that order has a genuine meaning. For numeric variables, it shows the range, number of unique values, and any short list of observed values. When ready, choose one of these deliberately: - **Continue without changes** makes all later tabs use the original data. - **Use prepared data** makes all later tabs use the working copy. The **Reusable code** panel records the applied actions. Copy or download this code and use it as the starting point for a reproducible R script. Data Prep does not evaluate arbitrary user-supplied R code. Use **Download prepared data** to save the current working dataset as CSV, Excel, RDS, or Stata. CSV and RDS work without additional packages; Excel and Stata export use the optional `rio` package. The **History** tab also provides **Download complete R script**. It combines the data import, applied Data Prep changes, and only the analyses run during that session. For an uploaded file, it uses a clear file-path placeholder rather than the temporary upload path used by the app. | Choice | Best use | |---|---| | Birth-weight example | Table 1, independent group comparisons, and 2×2 epidemiology | | Three-arm trial | Three-group comparisons, rates, and categorical outcomes | | Paired-data example | Learning the structure of paired analyses | | Upload a CSV or Excel file | Your own analysis dataset | ## Uploading files For CSV files, select the file and, if needed, use **Keep text columns as text**. For Excel files (`.xlsx` or `.xls`), enter a worksheet name or number when the relevant data are not on the first sheet. Uploaded data remain in the current browser session only. They are not written to the package or to a remote server. ## Preview and data dictionary The **Preview** panel shows the first eight rows. Check it before proceeding: - Are column names correct? - Did numeric variables import as numeric values? - Are Yes/No and category labels readable? - Are blank strings actually meaningful categories, or should they be recoded? The **Data dictionary** panel is a concise working overview. It shows the source name, label, detected type, completeness, number of unique values, and range or observed levels. The app displays an observed empty category (`""`) as **`(blank)`** in tables. This is distinct from missing data (`NA`). It is safe for exploration, but a meaningful label should usually be created before final reporting. ## Reusable data code The bottom code card shows the matching data-loading code. For example, the birth-weight example generates: ```r data("birthwt", package = "gtstats") data <- birthwt ``` Copy this code first when creating a permanent R script. # Understand tab
Screenshot 3 — Understand the data Show Describe data, Distribution, and Variance controls, the plot selector, one diagnostic table, and its download controls.
Suggested file: vignettes/images/app-03-understand.png
The **Understand** tab has two jobs: give a compact overview of the data and inspect selected continuous variables before choosing their descriptive display. Its controls are arranged side by side: dataset overview on the left and distribution/spread assessment on the right. Results use separate **Overview**, **Distribution**, **Variance**, and **Plot** tabs, so wide tables and figures do not form one long page. ## Describe data Click **Describe data** to run `describe_data()`. The result identifies likely continuous, binary, categorical, ordinal, and possible coded variables. It also gives completeness and a compact value summary. Start here before making a Table 1 or a comparison. In particular, confirm that a numerical code is really continuous rather than a category or an ordinal scale. ## Assess distribution Select one or more continuous variables under **Distribution / spread**, then optionally choose a grouping variable and click **Assess distribution**. The result reports: - usable observations, missing values, and non-finite values; - sample skewness and a readable shape band; - Shapiro-Wilk p-values as supporting information; and - a suggested descriptive presentation. The recommendation is for **descriptive reporting**, not test selection. Shapiro-Wilk is sensitive to sample size; interpret it alongside skewness, plots, and subject-matter knowledge. Turn on **Create visual distribution diagnostics** to inspect any selected variable as a histogram, density plot, Q-Q plot, or boxplot. Change the plot type without rerunning the assessment, then download the current view as PNG or PDF. Advanced controls expose the Shapiro-Wilk switch, skewness threshold, minimum subgroup size, and precision used by `assess_distribution()`. ## Show spread by group Check **Also assess spread by group** only when a grouping variable is selected. The app will also run `assess_variance()` and show group SDs, variances, and spread ratios. These are descriptive diagnostics. They do not impose an equal-variance requirement: Welch methods are the package's parametric default for independent groups. ## Code panel The Understand code card contains the exact `describe_data()`, `assess_distribution()`, and, when selected, `assess_variance()` calls. Copy this into a script if these checks informed a reporting decision. # Summary table tab
Screenshot 4 — Summary table ribbon and persistent preview Show the Foundation–Design ribbon, Create / update table button, publication preview with download buttons, and the Table recipe rail.
Suggested file: vignettes/images/app-04-summary-ribbon.png
The **Summary table** workspace behaves like a familiar document editor. Its ribbon contains five explicit tabs while the table preview remains in the same place: 1. **Foundation** keeps the current data, variable selection, grouping variable and Overall column together. 2. **Statistics** controls continuous summaries, categorical presentation, denominators, missing values and layout. 3. **P-values** adds inferential tests and exposes transparent Auto settings and test-specific exceptions. 4. **Add** layers CIs, total N, a selected proportion, a rate, or a custom row. 5. **Design** changes appearance without changing the statistics. Downloads sit beside the persistent preview rather than in a separate workflow tab. Expand **Reusable R code** beneath the preview to copy or download the complete recipe for RStudio. The recipe rail confirms the active data, selected variables, column structure, added layers, and theme. Changing a control does not destroy the current table: click **Create / update table** when the revised recipe is ready. ## Choose a group **Group columns by** is optional. Select `low` in the birth-weight example to create one column per birth-weight outcome. The selected group is automatically removed from the variable tickboxes; it should define the columns, not appear as one of the rows. ## Select variables Search for variables in the compact multi-select, or use **Select all** / **Clear**. The line beneath it reports how many variables are selected and previews variables still available. Removing a variable with × does not delete it from the data: click **Add variables** to reopen the complete searchable list and add it again. You can mix continuous, binary, categorical, and ordered variables in one selection. The app calls `summary_table()` once and lets gtstats detect their types. For binary variables, **Binary variables** can retain both levels or show one compact event row. When one row is selected, the app displays an event-level selector for every selected binary variable. It uses the second declared level by default, but the user can explicitly choose, for example, `Yes` for smoking and `No` for hypertension. The generated script records these choices with `show_dichotomous` and `value`. There is no need to separately select “continuous variables” and “categorical variables.” Use one meaningful set of summary-table variables. ## Optional ingredients The ingredient section exposes the builder helpers without requiring users to write a pipeline manually: | Ingredient | GUI options | Generated function | |---|---|---| | Total N | Label and first/last position | `add_total()` | | Selected proportion | Variable, event level, label, display, CI level/method, precision | `add_proportion()` | | Rate | Event count, person-time, label, multiplier, time label, CI and precision | `add_rate()` | | Custom row | Label, optional level, Overall and group-specific text | `add_row()` | The Add ribbon keeps specialist rows distinct from ordinary summaries. A selected proportion highlights one clinically important event; it is not needed merely to add CIs to existing categorical levels. For example, choose Summary table, group by `smoke`, place Overall first, use Separate columns, untick ordinary summaries, and add the `low = Low birth weight` proportion to generate: ```r summary_table( data, by = smoke, overall = "first", layout = "separate" ) |> add_proportion( var = low, level = "Low birth weight", display = "n_percent" ) ``` ## Summary-statistic overrides The app does not create a long row of dropdowns for every selected variable. Unlisted continuous variables use **Recommended** automatically. Add only exceptions to the compact override box, one per line: ```text age = mean_sd lwt = median_iqr bwt = mean_ci ``` Supported summary values are `recommended`, `mean_sd`, `mean_ci`, `median_iqr`, and `both`. Quotes and commas are not required. Blank lines and lines beginning with `#` are ignored. **Insert example** uses selected continuous variables; **Clear overrides** returns every variable to Recommended. A live message reports how many overrides were recognised. For `mean_ci`, a cell is displayed concisely as `mean (lower–upper)`. The footnote defines the interval as a 95% CI (or the selected confidence level), so “95% CI” is not repeated inside every table cell. ## Presentation controls | Control | Meaning | |---|---| | Overall column | No overall column, or an Overall column first/last | | Summary-statistic overrides | Optional exceptions; unlisted continuous variables use Recommended | | Categorical display | n (%), n/N (%), n only, or percentage only | | Categorical columns | Keep n (%) together, or separate n and % for categorical-only tables without CIs | | Percentage denominator | Column, row, or the entire dataset | | Overall categorical display | Automatic, n (%), n/N (%), n only, or percentage only | | Missing values | `ifany`, `always`, and `no` control only whether a missingness row is shown and retain non-missing denominators; `as_category` treats Missing as a displayed category included in categorical percentages | | Decimal places | Number of displayed decimal places | Choose the percentage denominator intentionally. **Within each column** answers “what percentage of this group has this level?” and is the usual Table 1 choice. **Within each row** answers a different question: how a level is distributed across the displayed groups. When row percentages and an Overall column are combined, **Automatic** shows Overall categorical counts and grouped row percentages. This prevents a whole-sample percentage from appearing to use the same denominator as the grouped cells. Users can override it when their reporting plan explicitly requires another Overall display. With separate categorical columns, the app omits the unused Overall percentage child column rather than leaving it blank. ## Build the table layer by layer The Summary table ribbon follows the same onion-like model as the R API: 1. Use **Foundation** to confirm the data, select variables, group columns and place Overall. 2. Use **Statistics** to choose summaries, missing-value display and layout. 3. Use **P-values** only when the table needs comparisons; Auto remains transparent and overridable. 4. Use **Add** to layer confidence intervals globally or only for selected variables, then add specialist rows only when they answer the report question. 5. Use **Design** to finish the publication table; download the result or its R script directly from the preview. Selecting confidence intervals generates a visible `add_ci()` layer. The app does not hide that choice inside `summary_table()`. Categorical levels receive proportion intervals, continuous means receive mean intervals, and median-only summaries remain unchanged. ```r summary_table( birthwt_data, by = low, include = c(age, lwt, race, smoke), overall = "first", layout = "separate" ) |> add_ci(vars = c(age, race)) ``` ## Add p-values Check **Add p-values (when grouped)** if a p-value for each selected variable is appropriate for your table. A grouping variable is required. The app uses `add_p()` with its documented automatic selection policy. Once p-values are enabled, the **P-value test overrides** box appears. Unlisted variables use Auto. Add only exceptions: ```text age = welch_t lwt = wilcox race = fisher bwt = none ``` Use `none` when a displayed variable should remain descriptive without a p-value. The app validates variable names, duplicate entries, supported option names, and compatibility with the detected variable type. Errors identify the specific line and list valid choices. Generated code uses a named `method` vector and an `include` selection when any variable is set to `none`. ## Customise appearance Choose a default, journal, classic, minimal, or compact theme. Optional title, subtitle, font size, bold labels, footnotes, and alternate-row shading are applied through `customise_table()`. The preview and every downloaded table use the same styling choices. ## Preview, export, and code Every visible table in the app—data preview, data dictionary, dataset description, diagnostics, summary table, comparison audits, crosstabs, and history—has download buttons for DOCX, HTML, PDF, and RTF. PDF needs a working browser/webshot setup; DOCX or HTML are the easiest choices for most users. Open the **Code** panel to copy or download the complete `summary_table()` pipeline and every selected layer, including the base summaries, `add_ci()`, `add_p()`, `add_total()`, `add_proportion()`, `add_rate()`, `add_row()`, and `customise_table()`. This is the route from a point-and-click table to a reproducible manuscript table. # Epi table tab
Screenshot — Epi table recipe Show Data structure, Ingredients and Reporting, together with the persistent preview, denominator audit and generated code.
Suggested file: vignettes/images/app-epi-table.png
This workspace is deliberately separate from Summary table. A Summary table describes participants; this workflow estimates disease occurrence and must make the numerator and denominator explicit. 1. Choose **One row per person/record** for a line list or **Numerator and denominator columns** for aggregate surveillance data. 2. Choose proportion, prevalence, attack rate or incidence rate and its reporting scale. 3. Optionally group by a ward, site, exposure or another meaningful stratum. 4. For a line list, select outcomes and explicitly choose the event value for each one. For aggregate data, map the numerator and denominator columns. 5. Review the denominator explanation before running the table. 6. Add p-values only when the question compares groups. Add epidemiological effect measures only for exactly two groups. Confidence intervals are always present: Wilson is the default for risk-like measures, exact binomial is optional, and incidence rates use exact Poisson intervals. The generated code records every event, denominator, scale and optional comparison. `$denominators`, `$p_values`, and `$effects` remain available for audit. The app prevents a case-only line list from being presented as an attack rate. When only cases are present, switch to aggregate data and provide the eligible population denominator. # Customise table tab
Screenshot 5 — Customise the completed table Show the carried-forward Summary table beside theme, labels, spanner, borders, density, font, colours, footnotes, p-value style, and export controls.
Suggested file: vignettes/images/app-05-customise.png
Use this tab when a table's presentation needs to match a manuscript, journal, report, or local wording convention. It follows the same post-processing idea as the gtregression app. Choose the source at the top of the tab: - **Completed Summary table** carries forward the most recently generated `summary_table()` result. - **Current data are final calculated results** treats every current row and column as a final value. It does not recalculate descriptive summaries or p-values. Do not choose this route for participant-level raw data. The second route is useful after `dplyr::summarise()` or when an analyst has received a calculated results sheet. Generated code wraps the data with `as_stats_table(data)` before applying `customise_table()`, so the workflow is fully reproducible. For already summarised data, tick **Calculate a confidence interval from aggregate columns** only when the data contain the required ingredients. Pick the calculation type, then map its columns: successes/total for a proportion, events/exposure for a rate, mean/SD/N for a mean, or estimate/SE for a normal interval. The app previews the completed table and generates the matching `as_stats_table() |> add_ci()` code. It never guesses these meanings from a column name. The most recently completed Summary table is carried forward and displayed automatically. If no Summary table exists, either return to the preceding tab or deliberately choose the already-summarised-data route. 1. Review the Summary table already displayed in the preview. 2. Optionally provide a title, subtitle, or additional note. 3. Relabel columns, variable/row labels, or category levels using one `current = new` mapping per line. 4. Choose a theme, font size, label emphasis, footnotes, or row shading. 5. Optionally hide named columns. 6. Click **Apply table changes**. The controls are grouped by purpose so beginners can work from top to bottom: | Group | Available controls | What they affect | |---|---|---| | Theme | Default/journal/classic/minimal/compact | Overall visual preset; app previews use gt and Office downloads use the appropriate export renderer | | Headings | Title, subtitle, spanning header | Table caption and grouped column heading | | Wording | Column, row, and level mappings | Displayed labels only; source data remain unchanged | | Notes | Source note, extra footnotes, show/hide package footnotes | Explanatory material below the table | | Typography | Font, font size, bold labels | Readability and emphasis | | Layout | Standard/compact/spacious density and table width | Row spacing and overall table dimensions | | Rules and colour | Horizontal/all/minimal borders, accent colour, row striping and stripe colour | Publication styling | | Column control | Left/centre/right alignment, hide, bold, or italic columns | Fine-grained completed-column formatting | | P-values | Threshold/fixed/scientific style, digits, threshold, optional `p =` | Display only; the selected tests and numeric p-values do not change | Use **compact** density for a long manuscript table and **standard** for most reports. The package already uses smaller footnote text, so footnotes remain visually subordinate to the data. Use **Show footnotes** unless the same definitions are supplied in the manuscript caption or methods. The original Summary-table result remains unchanged. Only its display is modified. The preview and DOCX, HTML, PDF, and RTF downloads therefore contain the same estimates, confidence intervals, denominators, and p-values as the selected source table. The **Code** panel creates the source table and then applies `customise_table()`. Copy or download that code rather than relying on an unrecorded series of clicks. Example mappings are: ```text Overall = All participants age = Maternal age (years) Yes = Present No = Absent ``` Column hiding is presentational only. Hiding a p-value column does not remove the test from the result object or change the analysis. # Compare groups tab
Screenshot 6 — Compare groups Show outcome/group selection, Auto versus explicit test control, paired options, effect size, publication table, and Audit panel.
Suggested file: vignettes/images/app-06-compare.png
Use **Compare groups** for one focused inferential question—not to replace a descriptive Table 1. 1. Choose the **Variable to compare** (the outcome). 2. Choose the categorical **Compare across groups** variable. 3. Leave **Test** as Auto or explicitly select a planned test. 4. Optionally request an effect size. 5. Click **Compare groups**. Variable and group must be different. The app starts with a sensible pair in the birth-weight data (`age` by `low`). ## Test control **Auto** is the recommended starting point when there is no prespecified test. Its policy is visible in the package documentation and result notes: | Data structure | Automatic method | |---|---| | Continuous, two independent groups | Welch t-test by default; Student's t-test with `var_equal = TRUE`; Wilcoxon only if marked skewness is flagged | | Continuous, 3+ independent groups | Welch ANOVA by default; classical ANOVA with `var_equal = TRUE`; Kruskal-Wallis only if marked skewness is flagged | | Continuous, paired | Paired t-test/Wilcoxon signed-rank for two occasions; repeated-measures ANOVA/Friedman for 3+ occasions | | Ordinal | Chi-square/Fisher for independent level distributions; Wilcoxon signed-rank for two paired occasions or Friedman for 3+ paired occasions. Specify Wilcoxon/Kruskal explicitly for an independent rank-based ordinal question. | | Binary/nominal categorical | Chi-square when no expected count is below 1 and no more than 20% are below 5; Fisher exact when sparse | | Binary, paired | McNemar for two occasions; Cochran's Q for 3+ occasions | Marked skewness uses absolute sample skewness at least 1. Shapiro-Wilk and lesser asymmetry remain supporting information; neither changes Auto alone. For categorical and independent ordinal outcomes, Fisher is selected when an expected count is below 1 or more than 20% are below 5; otherwise chi-square is used. The app also exposes the paired methods: McNemar (two binary occasions), Cochran's Q (three or more binary occasions), repeated-measures ANOVA, and Friedman. Turn on **Repeated measurements from the same participant** and select the participant ID before running any paired comparison. Use an explicit choice only when it is justified by the study design or an analysis plan. For **Auto**, the app also offers **equal variances are justified**. This sets `var_equal = TRUE`: it switches only a non-skewed independent continuous auto comparison to Student's t-test or classical ANOVA. It does not perform a variance test and does not alter paired, categorical, ordinal, or rank-based comparisons. ## Result and Audit panels The **Result** panel gives the publication-ready comparison table and explains what auto selected. The **Audit** panels are important: | Audit tab | What it shows | What you should do | |---|---|---| | Diagnostics | Calculated details such as expected counts or distribution context | Check for sparse data and unexpected patterns | | Assumptions | Automatic checks and design checks | Confirm user-check items from the study design | | Denominators | Observations used by the calculation | Confirm the analytical population is appropriate | Use the **Code** panel to retain the exact comparison in your analysis script. # Correlation tab
Screenshot 7 — Correlation and matrix visualisation Show the pair/matrix switch, method choice, correlation table, heatmap, plot appearance controls, and generated code.
Suggested file: vignettes/images/app-07-correlation.png
Use **Correlation** for relationships between continuous variables. Choose **One pair** for a conventional coefficient and scatterplot, or **Correlation matrix** for several variables. For one pair: 1. Choose two different continuous variables. 2. Select Auto, Pearson, or Spearman. 3. Choose the plotted trend and whether its confidence band is shown. 4. Click **Create correlation output**. Under **Advanced plot appearance**, pair plots can customise point and trend colours, axis labels, caption, confidence level, and base font size. Matrix heatmaps can customise negative, zero, and positive correlation colours. For a matrix: 1. Tick at least two continuous variables. 2. Choose lower, upper, or full layout. Lower triangle is the publication default; upper triangle places the longest row at the top. 3. Preserve the selected order, sort labels alphabetically, or cluster similar absolute correlation patterns. Input order is best for a prespecified publication; clustering is exploratory. 4. Choose whether cells contain the coefficient alone, adjusted p-value, pairwise n, both p and n, or a confidence interval. 5. Optionally hide the diagonal and shade the publication table. The **Plot** panel shows the matching scatterplot or heatmap and can be downloaded as PNG or PDF. The publication table and all three Audit tables can be downloaded as DOCX, HTML, PDF, or RTF. The **Code** panel reproduces both the `correlation()` and `plot_correlation()` calls. The app reports how many continuous variables are selected. At more than 12 it warns that the matrix may be suitable for exploration but too wide for a publication. **Tidy CSV** downloads the underlying pair-level estimates, p-values, adjusted p-values, confidence intervals, and denominators. When pairwise sample sizes differ, a visible warning directs you to the Denominators tab. Less frequently used ordering, adjustment, diagonal, and shading controls are kept under **Advanced matrix options**. **Reset options** restores the safe defaults without running an analysis. # Comparison plots The **Compare groups** tab can create the figure that accompanies its inferential result. Leave **Create comparison plot** selected for the beginner route. Auto chooses an appropriate visual for the variable; experienced users can request a boxplot or bar chart, switch categorical plots between counts and proportions, show or hide observations and the p-value, edit labels and caption, choose a colour palette, and change the base font size. The figure is downloadable as PNG or PDF, and the Code panel includes the matching `plot_compare()` call so the GUI figure can be reproduced in a script. Auto uses Pearson throughout a matrix only when every selected variable has absolute sample skewness below 1; otherwise it uses Spearman throughout. This does not establish linearity or monotonicity. Review the plot, pairwise denominators, influential observations, subject-matter meaning, and the fact that correlation does not imply causation. # Crosstabs tab
Screenshot 8 — Crosstabs and epidemiological measures Show row/column selectors, percentage choices, totals, association test, and a 2x2 result containing OR, RR, and risk difference.
Suggested file: vignettes/images/app-08-crosstabs.png
Use **Crosstabs** for two categorical variables. 1. Choose **Rows (exposure)**. 2. Choose **Columns (outcome)**. 3. Choose column, row, and/or total percentages. 4. Choose Auto, chi-square, Fisher exact, or no association test. 5. Click **Create crosstab**. For a 2×2 table, the result includes RR, OR, and RD by default, in addition to the association test and Cramer's V. For larger R×C tables, it gives the cross-tab and association statistics, but not 2×2 risk measures. If both row and column percentages are selected, cells are labelled so their denominator is clear. The generated code contains `percent = c("row", "column")`, which can be reused directly. # History tab The **History** tab records actions run during the current app session: - Describe data - Assess distribution - Create summary table - Compare groups - Create a correlation table and plot - Create crosstab The **Complete R script** panel can be copied or downloaded and contains the data source, applied preparation steps, and analyses run so far. The history is a session log, not a permanent audit database. It clears when the app closes, or when you click **Clear history**. Use it to orient yourself while exploring; use copied/downloaded code for the permanent analysis record. # Help tab The **Help** tab repeats the safe beginner order: 1. Inspect the data. 2. Check selected continuous variables before interpreting comparisons. 3. Build a summary table using one consistent presentation per variable. 4. Use Compare groups for a focused inferential question. 5. Review the output and generated code before reporting. # Saving outputs
Screenshot 9 — Download and reproduce Show the DOCX/HTML/PDF/RTF controls together with Copy code and Download .R. This should be the final image in the app tour.
Suggested file: vignettes/images/app-09-export-code.png
Every result tab offers table downloads. Use them as follows: | Format | Good for | Notes | |---|---|---| | DOCX | A Word manuscript | Best general choice for reporting | | HTML | Viewing or sharing in a browser | Preserves the table appearance | | RTF | Basic word-processing interchange | Useful when DOCX is not required | | PDF | A fixed-layout copy | Requires a local browser/webshot setup | | `.R` code | Reproducible analysis | Recommended for every final analysis | The copy buttons use your browser clipboard. If a browser blocks clipboard access, use **Download .R** instead. # Troubleshooting ## The app does not open ```r install.packages("shiny") gtstats_app() ``` If it opens in an external browser and you prefer RStudio, run it from an interactive RStudio session. You can also choose explicitly: ```r gtstats_app(launch.browser = rstudioapi::viewer) ``` ## Excel upload gives an error Install `rio`, restart the app, and try again: ```r install.packages("rio") ``` ## A table or comparison is blank Select the variables required by that tab and click its blue action button. The app intentionally does not calculate Table 1, comparisons, or crosstabs on startup. ## A variable seems to have the wrong type Return to **Data** and check the preview and Data dictionary. In your permanent script, explicitly convert categories to factors and ordered scales to `ordered()` factors. Numeric clinical codes should not be interpreted as continuous without checking their meaning. ## I see `(blank)` in a result The uploaded data contain an observed empty string. This is not an app error: gtstats displays it safely as `(blank)`. Decide whether it means “unknown”, “not recorded”, or a true category, then recode it in your analysis script before final reporting. ## Chrome or a browser crashes Run the app in the RStudio Viewer where possible. A browser is only needed for the local interface and, on some systems, PDF export. HTML and DOCX downloads do not require a browser screenshot engine. # Best practice Use the app to learn, explore, and produce a first publication-ready output. Use the generated R code as the durable record of the analysis. Before final reporting, ensure that the data preparation, category meanings, missing-data policy, statistical choices, and exports are reproducible outside the app.