从保存为列表列的模型中提取模型信息

extract model info from model saved as list column in r

我正在尝试从列表列中的模型中提取模型信息。 用mtcars来说明我的问题:

mtcars %>%  
    nest(-cyl) %>% 
    mutate(model= map(data, ~lm(mpg~wt, data=.))) %>% 
    mutate(aic=AIC(model))

我得到的是错误信息:

Error in mutate_impl(.data, dots) : 
  Evaluation error: no applicable method for 'logLik' applied to an object of class "list".

但是当我这样做时,它起作用了。

mtcars %>%  
    group_by(cyl) %>% 
    do(model= lm(mpg~wt, data=.)) %>% 
    mutate(aic=AIC(model))

谁能解释一下为什么?为什么第二种方式有效?我想不通。在这两种情况下,列表列 'model' 都包含模型信息。但可能会有一些差异......非常感谢。

让我们比较一下这两种方法的区别。我们可以 运行 除了最后一个 AIC 调用之外的整个代码,并将结果保存到 ab.

a <- mtcars %>%  
  nest(-cyl) %>% 
  mutate(model= map(data, ~lm(mpg~wt, data=.))) 

b <- mtcars %>%  
  group_by(cyl) %>% 
  do(model= lm(mpg~wt, data=.)) 

现在我们可以在控制台打印结果了。

a
# A tibble: 3 x 3
    cyl               data    model
  <dbl>             <list>   <list>
1     6  <tibble [7 x 10]> <S3: lm>
2     4 <tibble [11 x 10]> <S3: lm>
3     8 <tibble [14 x 10]> <S3: lm>

b
Source: local data frame [3 x 2]
Groups: <by row>

# A tibble: 3 x 2
    cyl    model
* <dbl>   <list>
1     4 <S3: lm>
2     6 <S3: lm>
3     8 <S3: lm>

现在我们可以看到数据帧 b 按行分组,而数据帧 a 不是。这是关键。

要在数据帧 a 中提取 AIC,我们可以使用 rowwise 函数按每一行对数据帧进行分组。

mtcars %>%  
  nest(-cyl) %>% 
  mutate(model= map(data, ~lm(mpg~wt, data=.))) %>%
  rowwise() %>%
  mutate(aic=AIC(model))

Source: local data frame [3 x 4]
Groups: <by row>

# A tibble: 3 x 4
    cyl               data    model      aic
  <dbl>             <list>   <list>    <dbl>
1     6  <tibble [7 x 10]> <S3: lm> 25.65036
2     4 <tibble [11 x 10]> <S3: lm> 61.48974
3     8 <tibble [14 x 10]> <S3: lm> 63.31555

或者我们可以使用 map_dbl 函数,因为我们知道每个 AIC 都是数字。

mtcars %>%  
  nest(-cyl) %>% 
  mutate(model= map(data, ~lm(mpg~wt, data=.))) %>%
  mutate(aic = map_dbl(model, AIC))

# A tibble: 3 x 4
    cyl               data    model      aic
  <dbl>             <list>   <list>    <dbl>
1     6  <tibble [7 x 10]> <S3: lm> 25.65036
2     4 <tibble [11 x 10]> <S3: lm> 61.48974
3     8 <tibble [14 x 10]> <S3: lm> 63.31555