Search code examples
gtsummary

How to do repeated measures Anova and Friedman test in gtsummary?


I have repeated measures data for fasting glucose of few patients which are measured in Day 0, 3 and 7 during a clinical trial. I want to do friedman.test (and repeated measures anova for another data). Is it possible in gtsummaryto do Friedman test and repeated measures Anova?

This is my code

library(gtsummary)
library(dplyr)
smpl %>% select(c(Participant.ID, value, Day)) %>% 
             tbl_summary(by = Day, include = -Participant.ID) %>% add_p()

By default gtsummary does Kruskal-Wallis rank sum test for the three groups in my data (Day 0, 3 and 7). As it is a repeated measures I wanted to do friedman.test on these groups. So I tried the following code

my_friedman <- function(data, variable, by, random, ...) {
     data <- data[c(variable, by)] %>% dplyr::filter(complete.cases(.))
     friedman.test(variable ~ data[[by]] | random, data = data)
     
}

smpl %>% select(c(Participant.ID, value, Day)) %>% 
          tbl_summary(by = Day) %>% 
           add_p(test = value ~ "my_friedman", random = Participant.ID)

But that gives an error..

enter image description here

this is the dput for my sample data smpl

structure(list(Participant.ID = c(1002, 1007, 1010, 1017, 1018, 
1022, 1044, 1050, 1051, 1052, 1002, 1007, 1010, 1017, 1018, 1022, 
1044, 1050, 1051, 1052, 1002, 1007, 1010, 1017, 1018, 1022, 1044, 
1050, 1051, 1052), Randomization = c("Pioglitazone", "Pioglitazone", 
"Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
"Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
"Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
"Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
"Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
"Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
"Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone"
), Day = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L), .Label = c("0", "3", "7"), class = "factor"), 
    value = c(31.92, 53.25, 34.69, 33.32, 25.94, 34.69, 22.65, 
    33.32, 24.33, 25.94, 31.92, 46.54, 44.74, 145.12, 37.34, 
    39.89, 22.65, 27.5, 25.94, 25.94, 37.34, 53.25, 29.02, 37.34, 
    25.94, 34.69, 22.65, 27.5, 29.02, 31.92)), row.names = c(NA, 
-30L), class = c("tbl_df", "tbl", "data.frame"))

Can someone kindly help?

Here is the direct call to friedman.test

> friedman.test(value ~ Day | Participant.ID, data = aa)

    Friedman rank sum test

data:  value and Day and Participant.ID
Friedman chi-squared = 1.2667, df = 2, p-value = 0.5308

Solution

  • Your code was close! I made some small adjustments. See below!

    library(gtsummary)
    #> #BlackLivesMatter
    
    smpl <-
      structure(list(Participant.ID = c(1002, 1007, 1010, 1017, 1018, 
                                        1022, 1044, 1050, 1051, 1052, 1002, 1007, 1010, 1017, 1018, 1022, 
                                        1044, 1050, 1051, 1052, 1002, 1007, 1010, 1017, 1018, 1022, 1044, 
                                        1050, 1051, 1052), Randomization = c("Pioglitazone", "Pioglitazone", 
                                                                             "Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
                                                                             "Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
                                                                             "Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
                                                                             "Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
                                                                             "Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
                                                                             "Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone", 
                                                                             "Pioglitazone", "Pioglitazone", "Pioglitazone", "Pioglitazone"
                                        ), Day = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                                             2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 
                                                             3L, 3L, 3L, 3L), .Label = c("0", "3", "7"), class = "factor"), 
                     value = c(31.92, 53.25, 34.69, 33.32, 25.94, 34.69, 22.65, 
                               33.32, 24.33, 25.94, 31.92, 46.54, 44.74, 145.12, 37.34, 
                               39.89, 22.65, 27.5, 25.94, 25.94, 37.34, 53.25, 29.02, 37.34, 
                               25.94, 34.69, 22.65, 27.5, 29.02, 31.92)), row.names = c(NA, 
                                                                                        -30L), class = c("tbl_df", "tbl", "data.frame"))
    
    my_friedman <- function(data, variable, by, group, ...) {
      # construct the formula
      formula <- stringr::str_glue("{variable} ~ {by} | {group}") |> as.formula()
      
      # perform Friedman test
      friedman.test(
        formula = formula, 
        data = data
      ) |> 
        broom::tidy()
    }
    
    my_friedman(data = smpl, variable = "value", by = "Day", group = "Participant.ID")
    #> # A tibble: 1 × 4
    #>   statistic p.value parameter method                
    #>       <dbl>   <dbl>     <dbl> <chr>                 
    #> 1      1.27   0.531         2 Friedman rank sum test
    
    tbl <-
      smpl %>% 
      select(Participant.ID, value, Day) %>% 
      tbl_summary(
        by = Day,
        include = -Participant.ID
      ) %>% 
      add_p(test = value ~ "my_friedman", group = Participant.ID)
    

    enter image description here Created on 2023-01-08 with reprex v2.0.2