Использование tbl_regression для многомерной регрессии во вложенных фреймах данных

Я делаю многомерную регрессию по списку переменных результата с последовательным набором независимых переменных. Для одномерной регрессии я следовал этому примеру использовать tl_uvregression из gtsummary во вложенном фрейме данных, но я пытаюсь обобщить это на многомерную регрессию, используя tbl_regression во вложенном фрейме данных, и когда я пытаюсь unnest таблицы, я получаю сообщение об ошибке, что вход должен быть списком векторов. Ниже показано, что я пробовал — я предполагаю, что мне не хватает небольшого, но важного шага, но я не могу понять, что это такое. Мой желаемый результат — это таблица выходных данных многомерной регрессии, где каждая модель является столбцом, а все ковариаты — строками (аналогично выполнению tbl_merge в списке каждой из этих многомерных моделей, выполняемых отдельно в tbl_regression).

library(tidyverse)
library(magrittr)
library(gtsummary)
library(broom)

id <- 1:2000
gender <- sample(0:1, 2000, replace = T)
age <- sample(17:64, 2000, replace = T)
race <- sample(0:1, 2000, replace = T)
health_score <- sample(0:25, 2000, replace = T)
cond_a <- sample(0:1, 2000, replace = T)
cond_b <- sample(0:1, 2000, replace = T)
cond_c <- sample(0:1, 2000, replace = T)
cond_d <- sample(0:1, 2000, replace = T)
df <- data.frame(id, gender, age, race, health_score, cond_a, cond_b, cond_c, cond_d)

regression_tables <- df %>% select(-id) %>% 
  gather(c(cond_a, cond_b, cond_c, cond_d), key = "condition", value = "case") %>% 
  group_by(condition) %>% nest() %>% 
  mutate(model = map(data, ~glm(case ~ gender + age + race + health_score, family = "binomial", data = .)),
         table = map(model, ~tbl_regression, exponentiate = T, conf.level = 0.99)) %>% 
  select(table) %>% unnest(table)

Так почему бы не остановиться на шаге select и изучить структуру результата?   —  person Kellan Baker    schedule 20.02.2021

@IRTFM Я сделал. И я не знаю, что делать с тем фактом, что table — это список функций.   —  person Kellan Baker    schedule 20.02.2021

См. также:  Как использовать dplyr для фильтрации NA в нескольких столбцах

Попробуйте заменить последний select / nest на pull(table) %>% tbl_stack(). Используйте аргумент заголовка группы в функции стека, чтобы получить заголовки над каждой многомерной моделью.   —  person Kellan Baker    schedule 20.02.2021

@ DanielD.Sjoberg большое вам спасибо! Я пробовал pull, но с переменной модели. Кроме того, @akrun заметил лишний ~ в вызове map(model, ~tbl_regression), который превращал вывод в непригодную для использования таблицу функций.   —  person Kellan Baker    schedule 21.02.2021

Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 1
  1. Kellan Baker

    Проблема, похоже, заключается в использовании лямбда-выражения (~) и без его использования, т.е. с указанием аргументов. Кроме того, отсутствуют tidy доступные методы (начиная с broom) для извлечения в формат Tibble из tbl_regression

    library(dplyr)
    library(tidyr)
    library(broom)
    library(gtsummary)
    
    out <-  df %>% 
       select(-id) %>% 
     gather(c(cond_a, cond_b, cond_c, cond_d), key = "condition", 
        value = "case") %>% 
     group_by(condition) %>% 
     nest() %>% 
      mutate(model = map(data,  
        ~glm(case ~ gender + age + race + health_score, 
            family = "binomial", data = .)),
      table = map(model, tbl_regression, exponentiate = T, conf.level = 0.99)) %>%
      select(table)
    
    out$table[[1]]
    

    введите описание изображения здесь


    Фактически, помимо метода OP, использующего map для перебора цикла, мы могли бы просто применить модель tbl_regression после nest_by (заменили gather на pivot_longer, поскольку gather устареет, pivot_longer — это обобщенная версия)

    out <-  df %>%
        select(-id) %>% 
        pivot_longer(cols = starts_with('cond'), 
           names_to = 'condition', values_to = 'case') %>% 
        nest_by(condition) %>% 
        mutate(model = list(glm(case ~ gender + age + 
          race + health_score, 
            family = "binomial", data = data)), 
    table_out = list(tbl_regression(model, exponentiate = TRUE, conf.level = 0.99)))
    
    out
    # A tibble: 4 x 4
    # Rowwise:  condition
    #  condition               data model  table_out 
    #  <chr>     <list<tbl_df[,5]>> <list> <list>    
    #1 cond_a           [2,000 × 5] <glm>  <tbl_rgrs>
    #2 cond_b           [2,000 × 5] <glm>  <tbl_rgrs>
    #3 cond_c           [2,000 × 5] <glm>  <tbl_rgrs>
    #4 cond_d           [2,000 × 5] <glm>  <tbl_rgrs>
    

    Если нам нужна объединенная таблица, примените tbl_merge к list из tbl_regression

    tbl_merge(out$table_out)
    

    -выход

    введите описание изображения здесь

    Спасибо тебе за это! Я должен признаться, что меня сбил с толку второй метод, просто использующий list для просмотра различных моделей, но я понимаю, что он приближает меня к решению. Есть ли способ превратить полученный тиббл в объединенную таблицу, используя, например, gt_summary::tbl_merge, без ручного извлечения каждой отдельной таблицы из out $ table_out? Я пытался lapply безуспешно. person Kellan Baker; 20.02.2021

    @KellanBaker, ты можешь просто сделать tbl_merge(out$table_out) person Kellan Baker; 20.02.2021

    @KellanBaker Не могли бы вы проверить обновление. Причина, по которой это не сработало, заключалась в том, что tbl_merge ожидает list в качестве ввода person Kellan Baker; 20.02.2021

    Извините за задержку, сервер в моей безопасной среде не работает, что не позволяет мне снова войти в систему. Как только я смогу войти, я проверю это. Я очень ценю вашу помощь! person Kellan Baker; 21.02.2021

    Это сработало, спасибо! Я наконец понимаю, что вы имеете в виду, говоря о неиспользованном ~, который превратил вывод в функцию. Можете ли вы указать мне на ресурс, который объясняет, как / почему я могу просто использовать list для циклического просмотра моделей во вложенном фрейме данных? Я искал объяснение этому, но не понимаю, что list здесь делает вместо map. person Kellan Baker; 21.02.2021

    @KellanBaker, я использовал list, потому что мы создаем новый столбец в mutate, а результат model представляет собой сложную структуру данных в формате списка. Итак, я обернул list, чтобы контейнер выводить как единое целое, поскольку mutate по умолчанию будет искать простой векторный столбец без каких-либо изысков. Используя map, вы, по сути, перебираете каждый элемент или строку, а затем структура вывода по умолчанию — это список. Кроме того, поскольку мы используем nest_by, группировка выполняется по строкам и, таким образом, можно строить модель непосредственно для каждой строки. person Kellan Baker; 21.02.2021

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: