Делаем t-тесты или u-тесты в R сразу для многих колонок с помощью `tidyverse`-подхода



Бывают ситуации, когда измерили много количественных переменных для двух групп, например контрольной и с заболеванием, я встречала такие данные у медиков или как результаты масс-спектрометрии. Планируется сравнить все эти количественные переменные тестом Стьюдента или Манна-Уитни, но вручную прописывать 3 или больше раз t-тест кажется не очень хорошей идеей. Что можно сделать? Будем использовать следующий подход: сначала развернем таблицу в длинный формат, соберем в списки значения по каждой группе и количественной переменной, затем таблицу снова превратим в широкий формат, но уже в виде

переменная1 [список значений контрольной группы] [список значений экспериментальной группы]



И уже к этой таблице применим нужный тест один раз и получим список p-value для каждой количественной переменной! Прикрепляю пример кода, постаралась прокомментировать основные моменты, данные сгенерированы из стандартного нормального распределения с заданием seed, так что этот код должен воспроизвестись:



 r

library(dplyr)

library(tidyr)

set.seed(2)

df <- data.frame(lapply(rep(100,15), rnorm),

group = rep(c('control', 'treatment'), each = 50)) # генерируем данные

colnames(df)[1:15] <- paste0('marker', 1:15) # меняем имена колонок на более понятные

df %>%

select(where(is.numeric), group) %>% # это на случай, если в исходном датафрейме не только числовые переменные

pivot_longer(cols = -group, names_to = 'variable') %>% # преобразуем датафрейм в long-формат

group_by(group, variable) %>% # группируем по типу обработки и типу переменных

summarise(value = list(value)) %>% # собираем в списки

pivot_wider(id_cols = c(variable), names_from = group) %>% # разворачиваем обратно

group_by(variable) %>% # группируем для проведения стат теста

# запускаем тест Манна-Уитни, сохраняем u-значение и p-value

mutate(p_value = wilcox.test(unlist(control), unlist(treatment))$p.value,

u_value = wilcox.test(unlist(control), unlist(treatment))$statistic)

#> `summarise()` has grouped output by 'group'. You can override using the

#> `.groups` argument.

#> # A tibble: 15 × 5

#> # Groups: variable [15]

#> variable control treatment p_value u_value

#> <chr> <list> <list> <dbl> <dbl>

#> 1 marker1 <dbl [50]> <dbl [50]> 0.293 1403

#> 2 marker10 <dbl [50]> <dbl [50]> 0.0403 1548

#> 3 marker11 <dbl [50]> <dbl [50]> 0.269 1411

#> 4 marker12 <dbl [50]> <dbl [50]> 0.997 1249

#> 5 marker13 <dbl [50]> <dbl [50]> 0.323 1106

#> 6 marker14 <dbl [50]> <dbl [50]> 0.560 1335

#> 7 marker15 <dbl [50]> <dbl [50]> 0.667 1313

#> 8 marker2 <dbl [50]> <dbl [50]> 0.117 1478

#> 9 marker3 <dbl [50]> <dbl [50]> 0.931 1263

#> 10 marker4 <dbl [50]> <dbl [50]> 0.866 1225

#> 11 marker5 <dbl [50]> <dbl [50]> 0.791 1211

#> 12 marker6 <dbl [50]> <dbl [50]> 0.986 1247

#> 13 marker7 <dbl [50]> <dbl [50]> 0.920 1235

#> 14 marker8 <dbl [50]> <dbl [50]> 0.0169 1597

#> 15 marker9 <dbl [50]> <dbl [50]> 0.707 1195



Если понадобится сделать не тест Манна-Уитни, как в примере, а t-test, то надо просто поменять в последней команде wilcox.test() на t.test().