2016-12-02 52 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''不是一個函數,那麼這個提取究竟是如何完成或應用的呢?你能澄清嗎? :) –

相關問題