Search code examples
rgtsummary

Is it possible to add p-value from a linear model to tbl_summary


I have data on C-Reactive Protein (CRP) values for non-diabetic, pre-diabetic, and diabetic patients. I am using tbl_summary to obtain the median values for these three groups and perform a statistical test for differences. However, I also want to add another p-value to this table from a linear regression adjusted for Age and Sex. Can someone please help me? Here is my code

oxid <- c('ALT','AST', 'CRP')

sampled_df %>%  
tbl_summary(by = DiabetesStatus, 
include = oxid, 
type = all_continuous() ~ "continuous2", 
statistic = all_continuous() ~ c("{mean} ({sd})"), 
missing_text = "missing") %>% 
add_p()

This is my linear regression model adjusting for Age, Sex and BMI.

lm(ALT ~ DiabetesStatus + Age + Sex + BMI, sampled_df) |> broom::tidy() 
lm(AST ~ DiabetesStatus + Age + Sex + BMI, sampled_df) |> broom::tidy() 
lm(CRP ~ DiabetesStatus + Age + Sex + BMI, sampled_df) |> broom::tidy() 

I want to add the p.value of DiabetesStatus to the above tbl_summary. Following is the sample from my data.

structure(list(ALT = c(46, 49, 47, NA, 68, 66, 40, 42, 52, 30, 
47, 35, 32, 37, 42, 28, 33, 46, 17.4, 33, NA, 45, 64, 64, 32, 
NA, 33.7, 17, 32, 67, 31, 13, 35, 30, 28, 44.2, 48, 37, 33, 33, 
48, 44, 58, 18.4, 48, 28, 74, 50), AST = c(27, 24, NA, NA, 34, 
34, 17, 22, 33, 16, 19, 26, 15, 19, 19, 17, 19, 21, 19.7, 13, 
NA, 24, 31, 46, 23, NA, 19.3, 19, 19, 29, 43, 14, 22, 14, 23, 
26.5, 31, 24, 16, 17, 30, 25, 28, 17.7, 31, 18, 35, 34), CRP = c(3, 
5, 3, NA, 3, 2, 2, NA, 0.9, 2.9, 1, 1, 2, 1, 4, 1, NA, 5, 3, 
1, NA, 1, 4, 1, 8, NA, 3, 3, 2.7, 3, 3, NA, 7, 1, 2, 2, 1, 2, 
4, 3, 1, 1, 3, 3, 1, 1, 3, 3), DiabetesStatus = structure(c(1L, 
3L, 1L, 1L, 1L, 2L, 2L, 3L, 2L, 2L, 3L, 2L, 1L, 1L, 1L, 2L, 1L, 
2L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 3L, 2L, 2L, 1L, 3L, 2L, 2L, 
3L, 1L, 3L, 1L, 2L, 3L, 3L, 2L, 3L, 1L, 1L, 1L, 1L, 3L, 1L), levels = c("Non-diabetic", 
"Pre-diabetic", "Diabetic"), class = "factor"), Age = c(51, 55, 
32, 52, 40, 48, 40, 57, 34, 48, 64, 46, 30, 37, 37, 48, 54, 45, 
48, 48, 62, 36, 49, 52, 49, 60, 54, 35, 53, 50, 55, 42, 66, 49, 
25, 52, 26, 48, 47, 59, 34, 71, 45, 41, 29, 37, 42, 51), BMI = c(24.7, 
28.8, 35.8, 26.9, 33.6, 29.7, 31, 39, 23, 23.5, 31.9, 25.6, 24.6, 
27.4, 30.6, 25.6, 28.3, 34.3, 32.6, 21.3, 25.1, 26.4, 43, 25.7, 
30.4, 25.2, 26.1, 26, 34.8, 34.4, 40.6, 40.1, 36.8, 26, 18.6, 
26.6, 22.8, 22.7, 31.7, 32.5, 28.6, 22.9, 24.7, 25.9, 22.8, 32.4, 
30.9, 21.4), Sex = structure(c(1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 
2L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 
2L, 2L, 1L, 2L, 2L, 1L, 2L, 2L), levels = c("Female", "Male"), class = "factor")), row.names = c(NA, 
-48L), class = c("tbl_df", "tbl", "data.frame"))

Solution

  • You can define a custom p-value method, and pass it in add_p(). Details on writing the method are here: https://www.danieldsjoberg.com/gtsummary/reference/tests.html#custom-functions-1

    library(gtsummary)
    packageVersion("gtsummary")
    #> [1] '1.7.2'
    
    sampled_df <-
      structure(list(ALT = c(46, 49, 47, NA, 68, 66, 40, 42, 52, 30, 
                             47, 35, 32, 37, 42, 28, 33, 46, 17.4, 33, NA, 45, 64, 64, 32, 
                             NA, 33.7, 17, 32, 67, 31, 13, 35, 30, 28, 44.2, 48, 37, 33, 33, 
                             48, 44, 58, 18.4, 48, 28, 74, 50), AST = c(27, 24, NA, NA, 34, 
                                                                        34, 17, 22, 33, 16, 19, 26, 15, 19, 19, 17, 19, 21, 19.7, 13, 
                                                                        NA, 24, 31, 46, 23, NA, 19.3, 19, 19, 29, 43, 14, 22, 14, 23, 
                                                                        26.5, 31, 24, 16, 17, 30, 25, 28, 17.7, 31, 18, 35, 34), CRP = c(3, 
                                                                                                                                         5, 3, NA, 3, 2, 2, NA, 0.9, 2.9, 1, 1, 2, 1, 4, 1, NA, 5, 3, 
                                                                                                                                         1, NA, 1, 4, 1, 8, NA, 3, 3, 2.7, 3, 3, NA, 7, 1, 2, 2, 1, 2, 
                                                                                                                                         4, 3, 1, 1, 3, 3, 1, 1, 3, 3), DiabetesStatus = structure(c(1L, 
                                                                                                                                                                                                     3L, 1L, 1L, 1L, 2L, 2L, 3L, 2L, 2L, 3L, 2L, 1L, 1L, 1L, 2L, 1L, 
                                                                                                                                                                                                     2L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 3L, 2L, 2L, 1L, 3L, 2L, 2L, 
                                                                                                                                                                                                     3L, 1L, 3L, 1L, 2L, 3L, 3L, 2L, 3L, 1L, 1L, 1L, 1L, 3L, 1L), levels = c("Non-diabetic", 
                                                                                                                                                                                                                                                                             "Pre-diabetic", "Diabetic"), class = "factor"), Age = c(51, 55, 
                                                                                                                                                                                                                                                                                                                                     32, 52, 40, 48, 40, 57, 34, 48, 64, 46, 30, 37, 37, 48, 54, 45, 
                                                                                                                                                                                                                                                                                                                                     48, 48, 62, 36, 49, 52, 49, 60, 54, 35, 53, 50, 55, 42, 66, 49, 
                                                                                                                                                                                                                                                                                                                                     25, 52, 26, 48, 47, 59, 34, 71, 45, 41, 29, 37, 42, 51), BMI = c(24.7, 
                                                                                                                                                                                                                                                                                                                                                                                                      28.8, 35.8, 26.9, 33.6, 29.7, 31, 39, 23, 23.5, 31.9, 25.6, 24.6, 
                                                                                                                                                                                                                                                                                                                                                                                                      27.4, 30.6, 25.6, 28.3, 34.3, 32.6, 21.3, 25.1, 26.4, 43, 25.7, 
                                                                                                                                                                                                                                                                                                                                                                                                      30.4, 25.2, 26.1, 26, 34.8, 34.4, 40.6, 40.1, 36.8, 26, 18.6, 
                                                                                                                                                                                                                                                                                                                                                                                                      26.6, 22.8, 22.7, 31.7, 32.5, 28.6, 22.9, 24.7, 25.9, 22.8, 32.4, 
                                                                                                                                                                                                                                                                                                                                                                                                      30.9, 21.4), Sex = structure(c(1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 
                                                                                                                                                                                                                                                                                                                                                                                                                                     2L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
                                                                                                                                                                                                                                                                                                                                                                                                                                     1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 
                                                                                                                                                                                                                                                                                                                                                                                                                                     2L, 2L, 1L, 2L, 2L, 1L, 2L, 2L), levels = c("Female", "Male"), class = "factor")), row.names = c(NA, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      -48L), class = c("tbl_df", "tbl", "data.frame"))
    
    oxid <- c('ALT','AST', 'CRP')
    
    adjusted_p <- function(data, variable, by, ...) {
      reformulate(c(by, c("Age", "BMI", "Sex")), response = variable) |> 
        lm(data = data) |> 
        broom::tidy() |> 
        head(1) |> 
        dplyr::mutate(method = "ANCOVA: Adjusted for Age, BMI, and Sex")
    }
    
    tbl <- sampled_df |> 
      tbl_summary(
        by = DiabetesStatus, 
        include = all_of(oxid), 
        type = all_continuous() ~ "continuous2", 
        statistic = all_continuous() ~ c("{mean} ({sd})"), 
        missing_text = "missing"
      ) |> 
      add_p(test = ~adjusted_p)
    

    enter image description here Created on 2024-02-12 with reprex v2.1.0