【问题标题】:Applying multiple model formulas to groups of data将多个模型公式应用于数据组
【发布时间】:2017-07-21 20:43:00
【问题描述】:

我想将 3 个线性模型应用于我的数据,并为每个模型提取残差。我想知道是否有一种方法可以结合使用 dplyr 和 purrr 对每个模型应用相同的步骤:

我想保留:

  1. 每个模型的 lm 对象
  2. 每个模型的 augment 输出
  3. 每个模型的残差

这是一个分析mpg 数据集的工作示例:

library(dplyr)
library(tidyr)
library(purrr)
library(broom)
library(ggplot2)

这是我想为我的 lm 使用的三个不同的公式

f1 = hwy ~ cyl
f2 = hwy ~ displ
f3 = hwy ~ cyl + displ

lin_mod = function(formula) {
  function(data) {
    lm(formula, data = data)
  }
}

这是我为单个公式提取残差的方法:

mpg %>% 
group_by(manufacturer) %>% 
nest() %>% 
mutate(model = map(data, lin_mod(f1)), 
       aug = map(model, augment), 
       res = map(aug, ".resid"))

但是,这种技术对于所有公式来说似乎都是一种糟糕的方法,因为我重写了很多代码:

mpg %>% 
group_by(manufacturer) %>% 
nest() %>% 
mutate(model1 = map(data, lin_mod(f1)), 
       aug1 = map(model1, augment), 
       res1 = map(aug1, ".resid"),
       model2 = map(data, lin_mod(f2)), 
       aug2 = map(model2, augment), 
       res2 = map(aug2, ".resid"),
       model3 = map(data, lin_mod(f3)), 
       aug3 = map(model3, augment), 
       res3 = map(aug3, ".resid"))

如何以优雅的方式将此函数应用于每个公式?我在想 mutate_all,或将公式放入列表中可能会有所帮助,但可惜我被卡住了。

【问题讨论】:

    标签: r dplyr purrr


    【解决方案1】:

    您可以使用mutate_at(或mutate_if)就地改变列表列。这样可以节省多次迭代,并使代码可管道化且更紧凑。

    library(dplyr)
    library(tidyr)
    library(purrr)
    library(broom)
    
    lin_mod = function(formula) {
      function(data,...){
      map(data,~lm(formula, data = .x))
      }
    }
    
    list_model <- list(cyl_model= hwy ~ cyl,
                       displ_model= hwy ~ displ,
                       full_model= hwy ~ cyl + displ) %>% 
                  lapply(lin_mod)
    
    ggplot2::mpg %>% 
      group_by(manufacturer) %>% nest() %>% 
        mutate_at(.vars=("data"),.funs=list_model) %>% 
        mutate_at(.vars=vars(ends_with("model")), .funs=~map(.x, augment)) %>% 
        mutate_at(.vars=vars(ends_with("model")), .funs=~map(.x, ".resid")) %>% unnest()
    

    【讨论】:

      【解决方案2】:

      按照here的例子,这是我能想到的最接近的方法

      library(dplyr)
      library(tidyr)
      library(purrr)
      library(broom)
      library(ggplot2)
      
      # Here are the three different formulas I want to use for my lm
      
      f1 = hwy ~ cyl
      f2 = hwy ~ displ
      f3 = hwy ~ cyl + displ
      
      formulas = c(f1,f2,f3)
      
      lin_mod = function(formula) {
        function(data) {
          lm(formula, data = data)
        }
      }
      
      list_model = lapply(formulas, lin_mod)
      names(list_model) = c('cyl_model', 'displ_model', 'full_model')
      
      
      fn_model <- function(.model, df){
        df$model <- map(df$data, possibly(.model, NULL))
        df
      }
      
      mpg_nested = mpg %>% 
      group_by(manufacturer) %>% 
      nest()
      
      mpg_nested_new = list_model %>% 
                       map_df(fn_model, mpg_nested, .id = 'id_model') %>% 
                       arrange(manufacturer) %>% 
                       mutate(aug = map(model, augment), 
                       res = map(aug, ".resid"))
      
      
      output = mpg_nested_new %>% 
      gather(Var, val, c('model', 'aug', 'res')) %>% 
      unite(desc, id_model, Var)%>% 
      spread(desc, val)
      

      【讨论】:

        猜你喜欢
        • 2020-03-05
        • 1970-01-01
        • 2020-01-22
        • 2013-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-02
        • 2021-12-02
        相关资源
        最近更新 更多