использование lm в столбце списка для прогнозирования новых значений с помощью purrr

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

Я сделал здесь игрушечный пример:

library(dplyr)
library(purrr)
library(tidyr)
library(broom)

set.seed(1234)

exampleTable <- data.frame(
  ind = c(rep(1:5, 5)),
  dep = rnorm(25),
  groups = rep(LETTERS[1:5], each = 5)
) %>%
group_by(groups) %>%
nest(.key=the_data) %>%
mutate(model = the_data %>% map(~lm(dep ~ ind, data = .))) %>%
mutate(Pred = map2(model, the_data, predict))

exampleTable <- exampleTable %>%
  mutate(ind=row_number())

это дает мне кусок, который выглядит так:

# A tibble: 5 × 6
  groups         the_data    model      Pred   ind 
  <fctr>           <list>   <list>    <list> <int> 
1      A <tibble [5 × 2]> <S3: lm> <dbl [5]>     1 
2      B <tibble [5 × 2]> <S3: lm> <dbl [5]>     2 
3      C <tibble [5 × 2]> <S3: lm> <dbl [5]>     3 
4      D <tibble [5 × 2]> <S3: lm> <dbl [5]>     4 
5      E <tibble [5 × 2]> <S3: lm> <dbl [5]>     5 

чтобы получить прогнозируемое значение с использованием модели lm для конкретной группы, я могу использовать это:

predict(exampleTable[1,]$model[[1]], slice(exampleTable, 1) %>% select(ind))

что дает такой результат:

> predict(exampleTable[1,]$model[[1]], slice(exampleTable, 1) %>% select(ind))
         1 
-0.4822045

Я хотел бы иметь по одному новому прогнозу для каждой группы. Я пробовал использовать purrr, чтобы получить то, что хотел:

exampleTable %>%
  mutate(Prediction = map2(model, ind, predict))

но это дает следующую ошибку:

Error in mutate_impl(.data, dots) : object 'ind' not found

Я смог получить желаемый результат со следующей чудовищностью:

exampleTable$Prediction <- NA

for(loop in seq_along(exampleTable$groups)){
  lmod <- exampleTable[loop, ]$model[[1]]
  obs <- filter(exampleTable, row_number()==loop) %>%
    select(ind)
  exampleTable[loop, ] $Prediction <- as.numeric(predict(lmod, obs))
}

это дает мне кусок, который выглядит так:

# A tibble: 5 × 6
  groups         the_data    model      Pred   ind Prediction
  <fctr>           <list>   <list>    <list> <int>      <dbl>
1      A <tibble [5 × 2]> <S3: lm> <dbl [5]>     1 -0.4822045
2      B <tibble [5 × 2]> <S3: lm> <dbl [5]>     2 -0.1357712
3      C <tibble [5 × 2]> <S3: lm> <dbl [5]>     3 -0.2455760
4      D <tibble [5 × 2]> <S3: lm> <dbl [5]>     4  0.4818425
5      E <tibble [5 × 2]> <S3: lm> <dbl [5]>     5 -0.3473236

Должен быть способ сделать это аккуратно, но я просто не могу его взломать.


person jkgrain    schedule 22.06.2017    source источник
comment
Как насчет mutate(Pred = map2_dbl(model, 1:5, ~predict(.x, newdata = data.frame(ind = .y))))?   -  person aosmith    schedule 23.06.2017
comment
Вот и все! Если вы измените это на ответ, я отмечу его как таковой. Огромное спасибо.   -  person jkgrain    schedule 23.06.2017


Ответы (1)


Вы можете воспользоваться аргументом newdata для predict.

Я использую map2_dbl, поэтому он возвращает только одно значение, а не список.

mutate(Pred = map2_dbl(model, 1:5, ~predict(.x, newdata = data.frame(ind = .y))))

# A tibble: 5 x 4
  groups         the_data    model       Pred
  <fctr>           <list>   <list>      <dbl>
1      A <tibble [5 x 2]> <S3: lm> -0.4822045
2      B <tibble [5 x 2]> <S3: lm> -0.1357712
3      C <tibble [5 x 2]> <S3: lm> -0.2455760
4      D <tibble [5 x 2]> <S3: lm>  0.4818425
5      E <tibble [5 x 2]> <S3: lm> -0.3473236

Если вы добавите ind в набор данных перед прогнозированием, вы можете использовать этот столбец вместо 1:5.

mutate(ind = 1:5) %>%
    mutate(Pred = map2_dbl(model, ind, ~predict(.x, newdata = data.frame(ind = .y) )))

# A tibble: 5 x 5
  groups         the_data    model   ind       Pred
  <fctr>           <list>   <list> <int>      <dbl>
1      A <tibble [5 x 2]> <S3: lm>     1 -0.4822045
2      B <tibble [5 x 2]> <S3: lm>     2 -0.1357712
3      C <tibble [5 x 2]> <S3: lm>     3 -0.2455760
4      D <tibble [5 x 2]> <S3: lm>     4  0.4818425
5      E <tibble [5 x 2]> <S3: lm>     5 -0.3473236
person aosmith    schedule 23.06.2017