2016-12-02 22 views
3

我是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

,以适应当前的管道,你会想要使用mapglance沿着unnestbroom包。

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

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

你得到的不仅仅是R平方以上,并从那里你可以使用select砸你不需要的东西。

如果你想保持嵌套在列表列模型摘要:

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

如果你想只提取你只需要使用map实际值嵌套框架单个值(和不是[[extract2,正如我原先所建议的,非常感谢你的发现)。

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

好吧,这似乎是我想要做的,我只是困惑,为什么代码是这样构造的。我不明白你为什么解开数据?你能解释一下吗? 感谢您的回答! – niklz

+1

使用'unnest'将数据框从列表列中取出,并将所有可用的列扩展到父数据框。你可以让它嵌套,但是r平方的列不能直接访问。我会更新答案,让代码没有“unnest”。 –

+0

因此,对于map(fit,〜glance)声明的结果是不公平的,我认为它是对嵌套的tibble(这是我感到困惑的地方)取消嵌套。 这种方法也规避了总结列与总结的要求,对吗?如果我明白了;第二个版本中的coeffs列将包含相同的信息(虽然格式不同)。 难道我没有办法从sum列中提取“r.squared”?只是我看到自己再次碰到这堵墙,在那里我有一个嵌套列表,我只想从中抓出一个元素。 – niklz

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 
+0

这确实得到了期望的输出,但是(抱歉挑剔)我真的很想找到一个在当前管道中工作的实现。我确信有一种方法,这只是获得正确语法的一个例子。 感谢您的回答 – niklz

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()。

+0

谢谢,确实有更好的办法;检查我的编辑在OP – niklz

+0

@ zx8754我有一个哈特时间来理解为什么'map_dbl(“r.squared”)'在这个例子中工作。我的意思是''r.squared''不是一个函数,那么这个提取究竟是如何完成或应用的呢?你能澄清吗? :) –

相关问题