【问题标题】:Unnest and bind nested tibble list-columns取消嵌套和绑定嵌套的 tibble 列表列
【发布时间】:2019-08-07 09:37:59
【问题描述】:

为了简化再现性,我使用来自ResourceSelection 包的goats 数据集,其中包含山羊的已使用(STATUS == 1) 和“可用”(STATUS == 0) GPS 位置的空间数据。 ID 代表个人 (n = 10),ELEVATION, ... , TASP 是点的属性。

library(tidyverse)
library(broom)
library(ResourceSelection)
head(goats)
  STATUS ID ELEVATION   SLOPE       ET   ASPECT       HLI      TASP
1      1  1       651 38.5216  35.3553 243.1131 0.9175926 0.9468804
2      1  1       660 39.6927  70.7107 270.0000 0.8840338 0.6986293
3      1  1       316 20.5477  50.0000 279.2110 0.7131423 0.5749115
4      1  1       334 34.0783  35.3553 266.1859 0.8643775 0.7447368
5      1  1       454 41.6187  25.0000 258.3106 0.9349181 0.8292587
6      1  1       343 28.4694 103.0776 237.0426 0.8254866 0.9756112

我正在为每个人拟合多个模型,并将每个模型的输出存储为单独的列表列,如下所示。

#Function for model one
Mod1 <- function(df) {
  glm(STATUS ~ SLOPE + I(SLOPE^2) + ASPECT + ET, data = df)
}

#Function for model two without ET
Mod2 <- function(df) {
  glm(STATUS ~ SLOPE + I(SLOPE^2) + ASPECT, data = df)
  }


#Fit the models
ModelFits <- goats %>%
  group_by(ID) %>% 
  nest() %>% 
  mutate(fits1 = map(data, Mod1),
         fits2 = map(data, Mod2),
         glanced1 = map(fits1, glance),
            #Create a dummy column to index model one
            glanced1 = map(glanced1, ~ .x %>% mutate(Mod = "One")),
         glanced2 = map(fits2, glance),
            #Create a dummy column to index model two
            glanced2 = map(glanced2, ~ .x %>% mutate(Mod = "Two")))

对于每个人,我想进行模型选择并根据AIC 确定哪个模型(Mod1 或 Mod2)排名更高。为此,我正在尝试unnest 使用glance 创建的两个列表列,并将它们绑定到单独的数据框中。我可以为glanced1glanced2 手动执行此操作,如下所示,它创建了在单个数据框中汇总所有单个模型的所需输出。

Mod1DF <- ModelFits %>% 
  unnest(glanced1) %>% 
  #Remove other list-columns
  select(-c(data,  fits1, fits2, glanced2)) %>% 
  as.data.frame()

Mod2DF <- ModelFits %>% 
  unnest(glanced2) %>% 
  #Remove other list-columns
  select(-c(data,  fits1, fits2, glanced1)) %>% 
  as.data.frame()  


Dat <- bind_rows(Mod1DF, Mod2DF)
#There is one model for each model type and individual in `Dat`
table(Dat$Mod)
One Two 
 10  10

但是,对于许多模型,这种方法很麻烦。我尝试过其他方法,但结果绑定的是列而不是行(即变宽而不是长),例如:

Dat <- ModelFits %>% 
  select(-c(data, fits1, fits2)) %>% 
  unnest(glanced1, glanced2) %>% 
  bind_rows() %>% 
  as.data.frame()

我怎样才能用一种不那么繁琐的方法达到预期的效果?

【问题讨论】:

    标签: r tidyr broom


    【解决方案1】:

    您可以使用gather 将宽数据帧转换为长格式:

    ModelFits %>%
      gather("model", "fit", glanced1:glanced2) %>%
      unnest(fit) %>%
      select(ID, null.deviance:Mod)
    

    但更直接的方法可能是遍历模型列表:

    map_df(list("One" = Mod1, "Two" = Mod2), function(mod) {
      goats %>%
        group_by(ID) %>%
        nest() %>%
        mutate(fits = map(data, mod), glanced = map(fits, glance)) %>%
        select(ID, glanced) %>%
        unnest()
    }, .id = "Mod")
    

    【讨论】:

      猜你喜欢
      • 2018-05-18
      • 2020-12-08
      • 2022-01-11
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 2012-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多