---
title: "lt vs gt — gsDesign2 examples"
---

This document re-runs a few of the `as_gt()` examples from
[gsDesign2](https://github.com/Merck/gsDesign2)'s documentation, but builds
the tables with `lt` instead of `gt`. The first goal of `lt` is to be a
drop-in lightweight replacement for `gt` in gsDesign2 outputs.

Because `lt()` is an S3 generic, we define methods for gsDesign2's summary
classes. In practice these methods would live in gsDesign2 (or a bridge
package); here they're defined inline for demonstration.

```{r setup, message=FALSE}
library(lt)
library(gsDesign2)

enroll_rate = define_enroll_rate(duration = 18, rate = 20)
fail_rate = define_fail_rate(
  duration = c(4, 100), fail_rate = log(2) / 12,
  dropout_rate = .001, hr = c(1, .6)
)
study_duration = 36
alpha = 0.025
beta = 0.1

lt.fixed_design_summary = function(data, ...) {
  x = lt(as.data.frame(data), ...)
  if (!is.null(attr(data, "title")))
    x = lt_header(x, title = attr(data, "title"))
  if (!is.null(attr(data, "footnote")))
    x = lt_footnote(x, attr(data, "footnote"), "title")
  x
}

lt.gs_design_summary = function(data, ...) {
  x = lt(as.data.frame(data), ...) |>
    lt_group(~ Analysis, sep = TRUE) |>
    lt_spanner(
      label = "Cumulative boundary crossing probability",
      columns = c("Alternate hypothesis", "Null hypothesis")
    ) |>
    lt_format(
      c("Z", "~HR at bound", "Nominal p",
        "Alternate hypothesis", "Null hypothesis"),
      decimals = 4
    )
  x
}

registerS3method("lt", "fixed_design_summary", lt.fixed_design_summary, asNamespace("lt"))
registerS3method("lt", "gs_design_summary", lt.gs_design_summary, asNamespace("lt"))
```

## Fixed design — AHR method

Equivalent of `fixed_design_ahr() |> summary() |> as_gt()`.

```{r fixed-ahr}
fixed_design_ahr(
  alpha = alpha, power = 1 - beta,
  enroll_rate = enroll_rate, fail_rate = fail_rate,
  study_duration = study_duration, ratio = 1
) |> summary() |> lt()
```

## Fixed design — Fleming-Harrington

Equivalent of `fixed_design_fh() |> summary() |> as_gt()`.

```{r fixed-fh}
fixed_design_fh(
  alpha = alpha, power = 1 - beta,
  enroll_rate = enroll_rate, fail_rate = fail_rate,
  study_duration = study_duration, ratio = 1
) |> summary() |> lt()
```

## Group sequential — `gs_power_ahr`

Equivalent of `gs_power_ahr(lpar = ...) |> summary() |> as_gt()`. The long
"Analysis: N Time: ... AHR: ..." label is a natural row-group header.
The `lt.gs_design_summary` method handles grouping, spanner, and
formatting automatically.

```{r gs-power-ahr}
gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |>
  summary() |>
  lt() |>
  lt_header(
    title = "Bound summary for AHR design",
    subtitle = "AHR approximations of ~HR at bound"
  ) |>
  lt_footnote(
    "Approximate hazard ratio to cross bound.",
    "column", "~HR at bound"
  ) |>
  lt_footnote(
    "One-sided p-value for experimental vs control treatment.",
    "column", "Nominal p"
  )
```

## Group sequential — `gs_design_ahr`

Equivalent of `gs_design_ahr() |> summary() |> as_gt()`.

```{r gs-design-ahr}
gs_design_ahr() |>
  summary() |>
  lt() |>
  lt_header(
    title = "Bound summary for AHR design",
    subtitle = "AHR approximations of ~HR at bound"
  )
```

## What's missing vs `as_gt()`

With `lt()` as an S3 generic, gsDesign2 can ship its own `lt.gs_design_summary`
and `lt.fixed_design_summary` methods (similar to the ones defined above),
making `summary() |> lt()` work out of the box. The mapping from gt to lt is:

| gt                                | lt                                  |
|-----------------------------------|-------------------------------------|
| `gt::gt(groupname_col=, rowname_col=)` | `lt_group(~ col)` (first column auto-becomes stub) |
| `gt::tab_header(title=, subtitle=)`    | `lt_header(title=, subtitle=)` |
| `gt::tab_spanner(label=, columns=)`    | `lt_spanner(label=, columns=)` |
| `gt::tab_footnote(footnote=, locations=cells_*())` | `lt_footnote(text, where, columns)` |
| `gt::tab_source_note(source_note=)`    | `lt_note(text)`                |
| `gt::fmt_number(columns=, decimals=)`  | `lt_format(columns, decimals)`    |
