取消嵌套并绑定嵌套的 tibble 列表列
Unnest and bind nested tibble list-columns
为了简化重现性,我使用 ResourceSelection
包中的 goats
数据集,其中包含空间数据供使用 (STATUS == 1
) 和 'available' (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
创建的两个列表列并将它们绑定到一个单独的数据框中。我可以为 glanced1
和 glanced2
手动执行此操作,如下所示,它创建了所需的输出,在单个数据框中汇总了所有单个模型。
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()
我怎样才能用不那么繁琐的方法达到预期的效果?
您可以使用 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")
为了简化重现性,我使用 ResourceSelection
包中的 goats
数据集,其中包含空间数据供使用 (STATUS == 1
) 和 'available' (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
创建的两个列表列并将它们绑定到一个单独的数据框中。我可以为 glanced1
和 glanced2
手动执行此操作,如下所示,它创建了所需的输出,在单个数据框中汇总了所有单个模型。
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()
我怎样才能用不那么繁琐的方法达到预期的效果?
您可以使用 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")