R: t-тест между рядами внутри каждого уровня фактора
Это фрейм данных, над которым я пытаюсь работать:
m <- matrix(rnorm(108, mean = 5000, sd = 1000), nrow = 36)
colnames(m) <- paste('V', 1:3, sep = '')
df <- data.frame(type = factor(rep(c('T1', 'T2', 'T3', 'T4', 'T5',
'T6', 'T7', 'T8', 'T9'), each = 4)),
treatment = factor(rep(rep(c('C','P', 'N', 'S'), each = 1),
9)),
as.data.frame(m))
Я хочу знать, как я могу выполнить t-тест между строками внутри каждого "типа". Вот пример t-тестов для типа T1, который я хочу:
t.test(df[1,3:5], df[2, 3:5])
t.test(df[1,3:5], df[3, 3:5])
t.test(df[1,3:5], df[4, 3:5])
t.test(df[1,3:5], df[3, 3:5])
t.test(df[1,3:5], df[4, 3:5])
Я пытаюсь понять, как я могу перебирать все строки и получать все p-значения из t-теста (вместе с типом и обработкой для идентификации), вместо того, чтобы вычислять каждую строку вручную. Любая помощь или предложение будут высоко оценены.
1 ответ:
Что-то вроде этого:
library(dplyr) t_tests = df %>% split(.$type) %>% lapply(function(x){ t(x[3:5]) %>% data.frame %>% setNames(x$treatment) %>% combn(2, simplify = FALSE) %>% lapply(function(x){ data.frame(treatment = paste0(names(x), collapse = ", "), p_value = t.test(x[,1], x[,2])$p.value) }) %>% do.call(rbind, .) }) %>% do.call(rbind, .) %>% mutate(type = sub("[.].+", "", row.names(.)))
Результат:
> head(t_tests, 10) treatment p_value type 1 C, P 0.6112274 T1 2 C, N 0.6630060 T1 3 C, S 0.5945135 T1 4 P, N 0.9388568 T1 5 P, S 0.8349370 T1 6 N, S 0.9049995 T1 7 C, P 0.3274583 T2 8 C, N 0.9755364 T2 9 C, S 0.7391661 T2 10 P, N 0.3177871 T2
Правки (добавлен дополнительный уровень "файл" в набор данных):
library(dplyr) t_tests = df %>% split(.$file) %>% lapply(function(y){ split(y, y$type) %>% lapply(function(x){ t(x[4:6]) %>% data.frame %>% setNames(x$treatment) %>% combn(2, simplify = FALSE) %>% lapply(function(x){ data.frame(treatment = paste0(names(x), collapse = ", "), p_value = t.test(x[,1], x[,2])$p.value) }) %>% do.call(rbind, .) }) %>% do.call(rbind, .) %>% mutate(type = sub("[.].+", "", row.names(.))) }) %>% do.call(rbind, .) %>% mutate(file = sub("[.].+", "", row.names(.)))
Результат:
treatment p_value type file 1 C, P 0.3903450 T1 file1 2 C, N 0.3288727 T1 file1 3 C, S 0.0638599 T1 file1 4 P, N 0.6927599 T1 file1 5 P, S 0.1159615 T1 file1 6 N, S 0.2184015 T1 file1 7 C, P 0.1147805 T2 file1 8 C, N 0.4961888 T2 file1 9 C, S 0.9048607 T2 file1 10 P, N 0.4203666 T2 file1 11 P, S 0.3425908 T2 file1 12 N, S 0.7262478 T2 file1 13 C, P 0.6300293 T3 file1 14 C, N 0.8255837 T3 file1 15 C, S 0.7140522 T3 file1 16 P, N 0.4768694 T3 file1 17 P, S 0.3992130 T3 file1 18 N, S 0.8740219 T3 file1 19 C, P 0.2434270 T4 file1 20 C, N 0.2713622 T4 file1
Примечание о правке:
ОП хотел, чтобы к данным был добавлен дополнительный верхний уровень
file
, можно просто добавить другойsplit
+lapply
иdo.call
в конце.Новые Данные:
m <- matrix(rnorm(324, mean = 5000, sd = 1000), nrow = 108) colnames(m) <- paste('V', 1:3, sep = '') df <- data.frame(type = factor(rep(c('T1', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'T9'), each = 4)), treatment = factor(rep(rep(c('C','P', 'N', 'S'), each = 1), 9)), file = factor(rep(c("file1", "file2", "file3"), each = 36)), as.data.frame(m))