Unnest fit glm型号

时间:2018-02-16 12:55:39

标签: r nested models

我有一个嵌套的glm模型。我在变量(region)上嵌套并运行适合模型的函数region_model

# toy data
test_data = data.frame(region = sample(letters[1:3], 1000, replace = TRUE),
              x = sample(0:1, 1000, replace = TRUE), 
                                   y = sample(1:100, 1000, replace = TRUE), 
                                   z = sample(0:1, 1000, replace = TRUE)) %>% arrange(region)

# nest
by_region = test_data %>%
              group_by(region) %>%
              nest()


# glm function 
region_model  <- function(df) {
 glm(x ~ y + z, data = df, family = "binomial")
}              

# run the model  
    by_region = by_region %>% mutate(mod_rat = data %>% map(region_model))

由此产生的结果如下:

> by_region
# A tibble: 3 x 3
  region               data   mod_rat
  <fctr>             <list>    <list>
1      a <tibble [352 x 3]> <S3: glm>
2      b <tibble [329 x 3]> <S3: glm>
3      c <tibble [319 x 3]> <S3: glm>  

我的目的是让模型无法计算边际效应。我试过了,我遇到了这个错误:

> unnest(by_region, mod_rat)
Error: Each column must either be a list of vectors or a list of data frames [mod_rat]

我想知道是否可以在这类对象(unnest)上使用<S3: glm>,如果没有,是否有替代方法可以获得这些估算值。

1 个答案:

答案 0 :(得分:1)

碰巧,margins软件包最近进行了一些更新,可以帮助您以整洁的方式进行此操作。特别是,添加了margins_summary()函数,该函数可以映射到嵌套模型对象上。

GitHub上的

This issue包含详细信息。

以下是适用于您的示例的代码

使用上方的数据

library(tidyverse)
library(magrittr)
library(margins)

# toy data
test_data <- data.frame(region = sample(letters[1:3], 1000, replace = TRUE),
                             x = sample(0:1, 1000, replace = TRUE), 
                             y = sample(1:100, 1000, replace = TRUE), 
                             z = sample(0:1, 1000, replace = TRUE)) %>% 
arrange(region)

# nest
by_region <- 
    test_data %>%
    group_by(region) %>%
    nest()

# glm function 
region_model  <- function(df) {
   glm(x ~ y + z, data = df, family = "binomial")
}              

# run the model  
by_region %<>% 
  mutate(mod_rat = map(data, region_model))

通过margins_summary()使用purrr:map2()函数来计算边际效应(如包装插图中所述,我已经包括了通过逻辑回归计算边际效应的两种方法)

by_region %<>% 
    mutate(marginals      = map2(mod_rat, data, ~margins_summary(.x, data = .y)),
           marginals_link = map2(mod_rat, data, ~margins_summary(.x, data = .y, type = "link")))

我们现在可以将边际效应数据嵌套到创建的列表列中的任何一个

by_region %>% 
   unnest(marginals) -> region_marginals
   region_marginals
# A tibble: 6 x 8
  region factor      AME      SE      z     p
    <fct>  <chr>     <dbl>   <dbl>  <dbl> <dbl>
  1 a      y      -9.38e-4 9.71e-4 -0.966 0.334
  2 a      z       3.59e-2 5.55e-2  0.647 0.517
  3 b      y       1.14e-3 9.19e-4  1.24  0.215
  4 b      z      -2.93e-2 5.38e-2 -0.545 0.586 
  5 c      y       4.67e-4 9.77e-4  0.478 0.633
  6 c      z      -3.32e-2 5.49e-2 -0.604 0.546
# ... with 2 more variables: lower <dbl>,
#   upper <dbl>

好好画图

region_marginals %>% 
  ggplot(aes(reorder(factor, AME), AME, ymin = lower, ymax = upper)) +
  geom_hline(yintercept = 0, colour = "#AAAAAA") +
  geom_pointrange() +
  facet_wrap(~region) +
  coord_flip()

enter image description here