Как сопоставить вложенный фрейм данных и сохранить несколько столбцов в качестве вывода - PullRequest
2 голосов
/ 25 мая 2020

У меня есть следующая структура данных:

test <- data.frame(
   id= rep(1:3, each=20),
   count  = rnorm(60, mean=5, sd=1),
   covar1 = rnorm(60, mean=10, sd=3),
   covar2 = rnorm(60, mean=95, sd=5),
   covar3 = rnorm(60, mean=30, sd=5)
   )

Затем я вкладываю ее в id:

test <- test %>% nest(-id)

Я хочу применить модель к каждому из данных covar столбец для данного идентификатора. Затем я хочу сохранить результат в отдельной колонке. Я могу сделать это следующим образом:

test <- test %>% mutate(covar1_lm = map(data, ~lm(count ~ covar1, data=.x)),
                        covar2_lm = map(data, ~lm(count ~ covar2, data=.x)),
                        covar3_lm = map(data, ~lm(count ~ covar3, data=.x)))

Что дает результат, который я хочу:

> test
# A tibble: 3 x 5
     id data              covar1_lm covar2_lm covar3_lm
  <int> <list>            <list>    <list>    <list>   
1     1 <tibble [20 × 4]> <lm>      <lm>      <lm>     
2     2 <tibble [20 × 4]> <lm>      <lm>      <lm>     
3     3 <tibble [20 × 4]> <lm>      <lm>      <lm>   

Проблема в том, что мои реальные данные имеют большое количество covar столбцов, и поэтому Я хотел бы сократить шаблонный код. Итак, я предполагаю, что мне нужна какая-то концепция динамических c имен переменных, но я не могу понять, как сопоставить динамический c набор имен столбцов ??

1 Ответ

2 голосов
/ 25 мая 2020

Сначала вы можете pivot_longer() набор данных, чтобы было одно наблюдение (строка) для каждой ковариаты для каждого набора данных. Затем вы выполняете модель для каждой ковариаты.

test %>%
  pivot_longer(starts_with("covar"),
               names_to = "covariate") %>%
  group_by(id, covariate) %>%
  summarize(model = list(lm(count ~ value)))

Теперь у вас есть одно наблюдение для каждой комбинации идентификатора и ковариаты.

# A tibble: 9 x 3
# Groups:   id [3]
     id covariate model 
  <int> <chr>     <list>
1     1 covar1    <lm>  
2     1 covar2    <lm>  
3     1 covar3    <lm>  
4     2 covar1    <lm>  
5     2 covar2    <lm>  
6     2 covar3    <lm>  
7     3 covar1    <lm>  
8     3 covar2    <lm>  
9     3 covar3    <lm>  

Если вы хотите превратить это в тот же вид результата, вы можете передать это по каналу pivot_wider(names_from = covariate, values_from = model). (Но обратите внимание, что наличие одной строки для каждой модели может упростить исследование и визуализацию моделей, особенно если вы уберете каждую с помощью broom::tidy() и удалите их из вложений).


Альтернатива group_by()/summarize() выше было бы вложить их:

test %>%
  pivot_longer(starts_with("covar"),
               names_to = "covariate") %>%
  group_by(id, covariate) %>%
  nest() %>%
  mutate(model = map(data, ~ lm(count ~ value, data = .x)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...