Как получить процент столбца и строки при использовании tbl_summary в R?

Я пытаюсь создать описательную таблицу, используя tbl_summary в R, которая будет показывать как процент столбца, так и процент строки для каждой категории. Рассмотрим следующий пример кода, использующий набор данных iris R:

iris_table <- iris %>%
  mutate(Sepal.Length.Cat = if_else(Sepal.Length > 5, "Big","Small")) %>% 
  tbl_summary(by = Species,
              include = c(Sepal.Length.Cat, Sepal.Width),
              type = list(
                Sepal.Width ~ "continuous2"
              ),
              statistic = list(
                all_continuous2() ~ c("{mean} ({sd})","{min} - {max}"),
                all_categorical() ~ "{n} ({p}%)"
              ),
              missing_text = "Missing") %>% 
  add_overall(col_label = "**Overall** <br>N = {n}") %>% 
  modify_footnote(update = everything() ~ NA)
print(iris_table)

Используя приведенный выше код, я получаю вывод по умолчанию для аргумента {p}, который равен проценту = «столбец». Однако я также хотел бы включить процент строки. Например, n = 22 в ячейке для видов Setosa с «большой» длиной чашелистика. Прямо сейчас ячейка показывает 22 (44%), что в сумме составляет 22/50 Setosa. Я хотел бы, чтобы он показывал что-то вроде «n = 22 (44%; 19%)», где 19% — это процент дополнительной строки (т. е. 22/118 всего Big).

Я попытался использовать аргумент процент = «строка», встроенный в tbl_summary. Однако это не только избавляет от процентов столбца, но также изменяет проценты в столбце «Общее» на проценты строк. Я бы хотел, чтобы проценты столбца остались, а категория «Общее» осталась только процентами столбца.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Пакет не предназначен для отображения процентных значений как по строкам, так и по столбцам. Но в новой версии пакета появились более универсальные способы создания индивидуальных таблиц. В приведенном ниже примере мы сначала вычисляем всю статистику, которая появится в таблице, а затем передаем ее новой функции под названием tbl_ard_summary(). Это не самый простой для чтения код, но он принесет вам обоим процент.

library(cards)
library(gtsummary)
packageVersion("gtsummary")
#> [1] '2.0.1.9002'

iris2 <- iris |> 
  dplyr::mutate(Sepal.Length.Cat = ifelse(Sepal.Length > 5, "Big","Small"))

# create the primary ARD
ard <- iris2 |>
  ard_stack(
    .by = Species,
    ard_continuous(variables = Sepal.Width),
    ard_categorical(variables = Sepal.Length.Cat),
    .missing = TRUE,
    .attributes = TRUE
  ) |> 
  # create ARD for row percentages
  bind_ard(
    ard_categorical(iris2, by = Species, variables = Sepal.Length.Cat, statistic = ~"p", denominator = "row") |> 
      dplyr::mutate(stat_name = ifelse(stat_name == "p", "p_row", stat_name))
  )


# pass the ARD to gtsummary to create table
ard |> 
  tbl_ard_summary(
    by = Species,
    include = c(Sepal.Length.Cat, Sepal.Width),
    type = list(
      Sepal.Width ~ "continuous2"
    ),
    statistic = list(
      all_continuous2() ~ c("{mean} ({sd})","{min} - {max}"),
      all_categorical() ~ "{n} (Column {p}%; Row {p_row}%)"
    ),
    missing_text = "Missing"
  ) |> 
  modify_footnote(all_stat_cols() ~ NA) |> 
  as_kable() # convert to kable to display on SO
Характеристика сетоза лишай Вирджиния Чашелистик.Длина.Кот Большой 22 (столбец 44,0%; строка 18,6%) 47 (столбец 94,0%; строка 39,8%) 49 (столбец 98,0%; строка 41,5%) Маленький 28 (столбец 56,0%; строка 87,5%) 3 (столбец 6,0%; строка 9,4%) 1 (столбец 2,0%; строка 3,1%) Чашелистик.Ширина Среднее (СО) 3,4 (0,4) 2,8 (0,3) 3,0 (0,3) Мин-Макс 2,3 - 4,4 2,0 - 3,4 2,2 - 3,8

Created on 2024-08-27 with reprex v2.1.1

Спасибо за быстрый и подробный ответ! Я опробовал ваше решение, и оно сработало с моими данными. Оставшиеся вопросы: (1) В tbl_ard_summary возникла ошибка, когда я включил исходную строку add_overall(). Есть ли способ добавить общий столбец? (2) Добавление аргумента «label = list(...)» из исходного tbl_summary также привело к ошибке. Как я могу обойти это, чтобы добавить ярлыки? Примечание для других: я создал список из более чем 80 категориальных переменных (например, all_categorical |> c(var1, var2, var3 и т. д.)), затем заменил строку ard_categorical на ard_categorical(variables = all_of(all_categorical)).

Robyn Husa 28.08.2024 16:21

Каркас tbl_ard_*() совершенно новый, и я все еще его дорабатываю. На данный момент он поддерживает не все функции, которые поддерживает функция tbl_summary(). Чтобы получить общие столбцы (на данный момент), вам нужно будет повторить приведенный выше код без переменной by, а затем вы можете использовать tbl_merge() для объединения двух таблиц. Аргумента метки сейчас нет, но если вы установите версию пакета gtsummary для разработчиков, аргумент label будет присутствовать.

Daniel D. Sjoberg 28.08.2024 21:53

Вместо использования версии pkg для разработчиков для получения аргумента label вы также можете назначить метки столбцов перед передачей фрейма данных в ard_stack(). Самый простой способ назначить метки столбцов — использовать функцию labelled::set_variable_labels() IMO.

Daniel D. Sjoberg 28.08.2024 21:54

Мне еще предстоит найти метод, встроенный в gtsummary. Мне удалось создать обходной путь. К сожалению, это не очень динамично и универсально; это сильно зависит от расположения в таблице, которую вы использовали в своем вопросе. Вероятно, для повторного использования потребуется модификация.

Я создал функцию, которая изменяет таблицу по вашему запросу.

fixer <- function(tbl) {   # add row percentages to table with column percentages
  tabIn <- tbl$inputs
  nms <- names(tabIn$type[tabIn$type %in% "categorical"]) # which columns?
                           # calculate the row %, arrange/format as per table
  rp <- table(tabIn$data[, nms], tabIn$data[, tabIn[["by"]]]) %>% 
    prop.table(1) %>% t() %>% as.vector() %>% style_percent()
                           # add percentages to the table
  map(2:3, \(j) {                                # for each row in the table
    imap(paste0("stat_", 1:3), \(k, i) {         # for the stat in each row
      val <- tbl$table_body[[j, k]]              # collect content
      val2 <- str_replace(val, "\\)", paste0("/", rp[(j - 1) * i], "%\\)")) # fix
      tbl$table_body[[j, k]] <<- val2            # add update back to table
      })
    })
  tbl          # return updated table
  }

Когда вы создаете свою таблицу или после ее вызова, вы вызываете эту функцию. Например:

iris_table %>% fixer()   # call table and update

Или со столом в том виде, в каком он сделан...

library(gtsummary)

iris_table <- iris %>%
  mutate(Sepal.Length.Cat = if_else(Sepal.Length > 5, "Big","Small")) %>% 
  tbl_summary(by = Species,
              include = c(Sepal.Length.Cat, Sepal.Width),
              type = list(
                Sepal.Width ~ "continuous2"
              ),
              statistic = list(
                all_continuous2() ~ c("{mean} ({sd})","{min} - {max}"),
                all_categorical() ~ "{n} ({p}%)"
              ),
              percent = "column",
              missing_text = "Missing") %>% 
  add_overall(col_label = "**Overall** <br>N = {n}") %>% 
  modify_footnote(update = everything() ~ NA) %>% fixer()   # <---- I'm new

Проверьте это

Эта функция действительно классная, спасибо за вашу тяжелую работу! Я пытаюсь изменить таблицу моих фактических данных, чтобы посмотреть, будет ли она работать. Мой главный камень преткновения — попытка выяснить, как внести изменения, чтобы включить все более 80 категориальных переменных, каждая из которых имеет разные уровни. Я предполагаю, что это где-то на карте (2:3...) часть функции (извиняюсь, я новичок в функциях)?

Robyn Husa 28.08.2024 21:29

Без проблем. В приведенной выше таблице есть три переменные и две строки переменных. Вы видите 2:3 в первом вызове map, это затронутые строки (строка 1 — это строка, содержащая только слова Sepal. Length Cat). Во вложенном вызове imap вы видите stat_...., поскольку каждый столбец со статистикой имеет имя stat_1, stat_2...and so on (where the overall` всегда и только stat_0. Если вы посмотрите на iris_table$itable_body, вы увидите эту таблицу как фрейм данных. (Это может помочь.) Если у вас есть еще вопросы, дайте мне знать. Вызов, который создает rp — он должен быть отдельным для ea. вар

Kat 28.08.2024 21:38

Другие вопросы по теме

Таблица с горячим кодированием в tbl_summary
Округление до ближайшего 0 или 5 в gtsummary outputbale
В R при представлении данных (RCT) в таблице (желательно gtsummary) как включить тесты значимости как внутри группы, так и между группами? [картинка]
Описательная таблица в R с более чем одной группирующей переменной
R gtsummary tbl_summary со слоями и двумя независимыми группирующими переменными
Измените аргумент статистики так, чтобы дихотомические переменные показывали количество обоих проявлений, разделенных косой чертой (/)
Ошибка Gtsummary при использовании tbl_merge: «Невозможно преобразовать из `y$modify_stat_N` <double> в `x$modify_stat_N` <integer> из-за потери точности»
Удалить метку переменной при использовании tbl_strata() и tbl_summary() из пакета gtsummary
Gtsummary: можно ли добавить «n» для каждого столбца таблицы, если tbl_summary разделена на две группы?
Добавление значений p в сводку таблицы