Я думаю, вы найдете это руководство полезным: Запуск модели в отдельных группах .
Давайте сгенерируем некоторые примеры данных, аналогичные вашим, со значениями для двух вариантов и среднего возраста.Нам также понадобится несколько пакетов:
library(dplyr)
library(tidyr)
library(purrr)
library(broom)
set.seed(1001)
data1 <- data.frame(mean_age = sample(40:80, 50, replace = TRUE),
snp01 = rnorm(50),
snp02 = rnorm(50))
Первый шаг - преобразование из "широкого" в "длинный" формат с использованием gather
, чтобы названия вариантов находились в одном столбце, а значения - в другом.Затем мы можем nest
по названию варианта.
data1 %>%
gather(snp, value, -mean_age) %>%
nest(-snp)
Это создает столбец (специальный фрейм данных), где второй столбец, data
, представляет собой «столбец списка» - он содержит средние числа изначения для варианта в этой строке:
# A tibble: 2 x 2
snp data
<chr> <list>
1 snp01 <tibble [50 x 2]>
2 snp02 <tibble [50 x 2]>
Теперь мы используем purrr::map
для создания третьего столбца с линейной моделью для каждой строки:
data1 %>%
gather(snp, value, -mean_age) %>%
nest(-snp) %>%
mutate(model = map(data, ~lm(mean_age ~ value, data = .)))
Результат:
# A tibble: 2 x 3
snp data model
<chr> <list> <list>
1 snp01 <tibble [50 x 2]> <lm>
2 snp02 <tibble [50 x 2]> <lm>
Последний шаг - суммирование моделей по желанию, затем unnest
структура данных.Я использую broom::glance()
.Полная процедура:
data1 %>%
gather(snp, value, -mean_age) %>%
nest(-snp) %>%
mutate(model = map(data, ~lm(mean_age ~ value, data = .)),
summary = map(model, glance)) %>%
select(-data, -model) %>%
unnest(summary)
Результат:
# A tibble: 2 x 12
snp r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance df.residual
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <dbl> <int>
1 snp01 0.00732 -0.0134 12.0 0.354 0.555 2 -194. 394. 400. 6901. 48
2 snp02 0.0108 -0.00981 12.0 0.524 0.473 2 -194. 394. 400. 6877. 48