79701787

Date: 2025-07-15 08:50:24
Score: 1
Natty:
Report link

The initial answer from @Daniel put me on the right track. However, the new level must be given a name, and editing its label afterwards is a good idea.

Here's the code in full. The new lines are the two that use the forcats function-

# Define the data:-
df <- data.frame(pat = c(1:90))
df$by <- ifelse(df$pat < 30, "A", "B")
df$lvl <- ifelse(df$pat < 30, NA, ifelse(df$pat < 60, "Red", "Blue"))

# Convert the NA level to something that will predictably appear at the
# bottom of an alphabetical list, then edit its label to something 'legible' 
df$lvl_f <- forcats::fct_na_value_to_level(df$lvl, level = 'zz_Missing')
df$lvl_f <- forcats::fct_recode(df$lvl_f, Missing = "zz_Missing")

# Output in GTSummary
df |> select(by, lvl_f) |>
  tbl_summary(by = by,
              percent = "column",
              type = list(all_continuous() ~ "continuous2"),
              missing = "ifany",
              missing_text = "Missing",
              missing_stat = "{N_miss} ({p_miss})"
  ) |>
  modify_post_fmt_fun(
    fmt_fun = ~ifelse(. == "0 (NA%)", "0", .),
    columns = all_categorical()
  ) |> 
  add_overall(last = TRUE)

And here's the updated output, with corrected percentage. Thanks @Daniel (for the answer, and a great package in GTSummary!).
enter image description here

Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Daniel
  • User mentioned (0): @Daniel
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: rambles