2017-01-05 120 views

回答

6

這裏有很多選項,其中包括modelr::add_residuals(請參閱@LmW的回答),broom::augment和普通的舊residuals。如果您正在使用分組模型,則在列表中嵌套模型非常方便,自然會導致遍歷模型列表以計算殘差等。


residuals

普通老式基礎R作品巧妙地與一些purrr(使用lapply如果您喜歡):

library(tidyverse) 

mtcars %>% 
    rownames_to_column('car') %>% 
    nest(-gear) %>% 
    mutate(model = map(data, ~lm(mpg ~ disp, data = .x)), 
      resid = map(model, residuals)) %>% 
    unnest(data, resid) 

#> # A tibble: 32 × 13 
#>  gear  resid   car mpg cyl disp hp drat wt 
#> <dbl>  <dbl>   <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
#> 1  4 0.98649891  Mazda RX4 21.0  6 160.0 110 3.90 2.620 
#> 2  4 0.98649891 Mazda RX4 Wag 21.0  6 160.0 110 3.90 2.875 
#> 3  4 -3.56856040  Datsun 710 22.8  4 108.0 93 3.85 2.320 
#> 4  4 2.76107028  Merc 240D 24.4  4 146.7 62 3.69 3.190 
#> 5  4 0.44001547  Merc 230 22.8  4 140.8 95 3.92 3.150 
#> 6  4 0.11531527  Merc 280 19.2  6 167.6 123 3.92 3.440 
#> 7  4 -1.28468473  Merc 280C 17.8  6 167.6 123 3.92 3.440 
#> 8  4 2.45060811  Fiat 128 32.4  4 78.7 66 4.08 2.200 
#> 9  4 0.08397007 Honda Civic 30.4  4 75.7 52 4.93 1.615 
#> 10  4 3.02179175 Toyota Corolla 33.9  4 71.1 65 4.22 1.835 
#> # ... with 22 more rows, and 4 more variables: qsec <dbl>, vs <dbl>, 
#> # am <dbl>, carb <dbl> 

你可以在residuals直接包住lm電話:

mtcars %>% 
    rownames_to_column('car') %>% 
    group_by(gear) %>% 
    mutate(resid = residuals(lm(mpg ~ disp))) 

獲得了相同的結果,但這種方法是不可取的,除非你確定你不打算對模型做其他任何事情。 (顯然unnesting失去型號爲好,但如果你能控制,當你這樣做,你是否被打破鏈早期保存副本。)


broom::augment

augment增加了許多有用的變量包括殘差,並且同樣可以使用:

mtcars %>% 
    rownames_to_column('car') %>% 
    nest(-gear) %>% 
    mutate(model = map(data, ~lm(mpg ~ disp, data = .x)), 
      model_data = map(model, broom::augment)) %>% 
    unnest(model_data) 

#> # A tibble: 32 × 10 
#>  gear mpg disp .fitted .se.fit  .resid  .hat .sigma 
#> <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl>  <dbl> <dbl> 
#> 1  4 21.0 160.0 20.01350 0.9758770 0.98649891 0.16546553 2.503083 
#> 2  4 21.0 160.0 20.01350 0.9758770 0.98649891 0.16546553 2.503083 
#> 3  4 22.8 108.0 26.36856 0.7466989 -3.56856040 0.09687426 2.197330 
#> 4  4 24.4 146.7 21.63893 0.8206560 2.76107028 0.11701449 2.331455 
#> 5  4 22.8 140.8 22.35998 0.7674126 0.44001547 0.10232345 2.524090 
#> 6  4 19.2 167.6 19.08468 1.0800836 0.11531527 0.20268993 2.528466 
#> 7  4 17.8 167.6 19.08468 1.0800836 -1.28468473 0.20268993 2.482941 
#> 8  4 32.4 78.7 29.94939 1.0762841 2.45060811 0.20126638 2.357875 
#> 9  4 30.4 75.7 30.31603 1.1195513 0.08397007 0.21777368 2.528634 
#> 10  4 33.9 71.1 30.87821 1.1879209 3.02179175 0.24518417 2.247410 
#> # ... with 22 more rows, and 2 more variables: .cooksd <dbl>, 
#> # .std.resid <dbl> 

如果你想從原始數據保存未使用的變量,改變model_datamodel_data = map2(model, data, broom::augment)),路過augment a data參數,而不是將其默認爲模型使用的數據。

+0

感謝您的不同選擇alistaire。這正是我需要的。 – Tony2016

3

modelr::add_residuals()應該做的正是你想要的:

require(tidyverse) 
require(modelr) 

models <- mtcars %>% 
    group_by(gear) %>% 
    nest() %>% 
    mutate(model = map(data, ~lm(mpg ~ disp, data = .)), 
      residuals = map2(data, model, add_residuals)) 

models %>% unnest(residuals) 

# A tibble: 32 × 12 
    gear mpg cyl disp hp drat wt qsec vs am carb 
    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  4 21.0  6 160.0 110 3.90 2.620 16.46  0  1  4 
2  4 21.0  6 160.0 110 3.90 2.875 17.02  0  1  4 
3  4 22.8  4 108.0 93 3.85 2.320 18.61  1  1  1 
4  4 24.4  4 146.7 62 3.69 3.190 20.00  1  0  2 
5  4 22.8  4 140.8 95 3.92 3.150 22.90  1  0  2 
6  4 19.2  6 167.6 123 3.92 3.440 18.30  1  0  4 
7  4 17.8  6 167.6 123 3.92 3.440 18.90  1  0  4 
8  4 32.4  4 78.7 66 4.08 2.200 19.47  1  1  1 
9  4 30.4  4 75.7 52 4.93 1.615 18.52  1  1  2 
10  4 33.9  4 71.1 65 4.22 1.835 19.90  1  1  1 
# ... with 22 more rows, and 1 more variables: resid <dbl> 

檢查出modelr的文件;我發現它非常方便。

相關問題