提取模型摘要并将其存储为新列

时间:2016-12-02 10:42:14

标签: r dplyr lm summary purrr

我是purrr范例的新手,并且正在努力解决这个问题。

遵循一些资源我已经设法嵌套数据框,在嵌套数据上运行线性模型,从每个lm中提取一些系数,并为每个lm生成摘要。我要做的最后一件事是提取" r.squared"从摘要(我原本认为这将是我试图实现的最简单的部分),但无论出于何种原因,我都无法正确理解语法。

这是我的工作的MWE:

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

mtcars %>%
  nest(-cyl) %>%
  mutate(fit = map(data, ~lm(mpg ~ wt, data = .)),
         sum = map(fit, ~summary))

这是我尝试提取失败的r.squared:

mtcars %>%
  nest(-cyl) %>%
  mutate(fit = map(data, ~lm(mpg ~ wt, data = .)),
         sum = map(fit, ~summary),
         rsq = map_dbl(sum, "r.squared"))
Error in eval(substitute(expr), envir, enclos) : 
  `x` must be a vector (not a closure)

这表面上类似于RStudio网站上提供的示例:

mtcars %>%
  split(.$cyl) %>%
  map(~ lm(mpg ~ wt, data = .x)) %>%
  map(summary) %>%
  map_dbl("r.squared")

这有效但我希望r.squared值位于一个新列(因此是mutate语句)中,我想了解为什么我的代码不工作而不是解决方法问题

编辑:

这是我使用以下解决方案的工作解决方案:

mtcars %>%
      nest(-cyl) %>% 
      mutate(fit = map(data, ~lm(mpg ~ wt, data = .)),
             summary = map(fit, glance),
             r_sq = map_dbl(summary, "r.squared"))

编辑2:

因此,事实证明该错误来自于summary = map(fit,〜summary)行中包含波形符号键。我的猜测是,使对象成为嵌套的函数,而不是摘要本身返回的对象。如果有人想要加入,我会喜欢这方面的权威答案。

要明确的是,此版本的原始代码可以正常工作:

mtcars %>%
  nest(-cyl) %>%
  mutate(fit = map(data, ~lm(mpg ~ wt, data = .)),
         summary = map(fit, summary),
         r_sq = map_dbl(summary, "r.squared"))

3 个答案:

答案 0 :(得分:5)

要适应当前的管道,您需要使用.select2-selection__arrow { display: none } 以及unnest包中的mapglance

broom

你将获得的不仅仅是r平方,从那里你可以使用library(tidyr) library(dplyr) library(broom) mtcars %>% nest(-cyl) %>% mutate(fit = map(data, ~lm(mpg ~ wt, data = .))) %>% unnest(map(fit, glance)) 删除你不需要的东西。

如果要保持嵌套在列表列中的模型摘要:

select

如果您只想从嵌套框架中提取单个值,您只需要使用mtcars %>% nest(-cyl) %>% mutate(fit = map(data, ~lm(mpg ~ wt, data = .)), summary = map(fit, glance)) 到实际值(而不是我最初建议的map[[,很多谢谢你找到了。)

extract2

答案 1 :(得分:4)

我认为,对于您希望实现的目标,最好使用glance()包中的broom函数:

library(broom)
library(dplyr)
mtcars %>%
  group_by(cyl) %>%
  do(glance(lm(mpg ~ wt, data = .))) %>%
  select(cyl, r.squared)
#    cyl r.squared
#  <dbl>     <dbl>
#1     4 0.5086326
#2     6 0.4645102
#3     8 0.4229655

答案 2 :(得分:1)

必须有一个更好的方法,这是我的管道尝试:

mtcars %>%
  split(.$cyl) %>%
  map(~ lm(mpg ~ wt, data = .x)) %>%
  map(summary) %>%
  map_dbl("r.squared") %>% 
  list() %>% 
  as.data.frame(col.names = "r.squared") %>% 
  add_rownames(var = "cyl")

# # A tibble: 3 × 2
#     cyl r.squared
#   <chr>     <dbl>
# 1     4 0.5086326
# 2     6 0.4645102
# 3     8 0.4229655

注意:您可能会收到警告。

  

警告消息:已弃用,请改用tibble :: rownames_to_column()。