|
# 使用purrr和broom处理多个模型
# 准备工作
[AppleScript] 纯文本查看 复制代码 library(modelr)
library(tidyverse)
# 列表列——隐式定义在数据框中的:数据框是由相同长度的向量组成的命名列表
[AppleScript] 纯文本查看 复制代码 data.frame(x = list(1:3, 3:5))
# 可以使用I()函数,但是输出结果却难以理解
[AppleScript] 纯文本查看 复制代码 data.frame(
x = I(list(1:3, 3:5)),
y = c("1, 2", "3, 4, 5")
)
# tibble()更易创建列表列,输出结果更加易理解
[AppleScript] 纯文本查看 复制代码 tibble(
x = list(1:3, 3:5),
y = c("1, 2", "3, 4, 5")
)
# tribble()更易理解,它可以自动识别出想要的列表
[AppleScript] 纯文本查看 复制代码 tribble(
~x,~y,
1:3,"1, 2",
3:5, "3, 4, 5"
)
#2 要想有效地使用列表列,需要3个步骤
#2.1 nest()、summarize() + list()以及 mutate() + 映射函数
#2.2 使用map()、map2()和pmap()转换现有列表列,创建中间列表列
#2.3 将列表列简化还原成数据框或原子向量
#3 创建列表列
#3.1 使用tidyr::nest()函数将分组数据框转换为嵌套数据框,嵌套数据框中会包含数据框列表列
# nest()有两种使用方式,当用于分组数据框时,
# nest()函数会保留用于分组的列,而将其他所有数据归并到列表列
#3.2 使用mutate()函数以及能够返回列表的向量化函数
[AppleScript] 纯文本查看 复制代码 df <- tribble(
~x1,
"a, b, c",
"d, e, f, g"
)
df %>%
mutate(x2 = stringr::str_split(x1, ","))
# unnest()函数指导如何处理这些向量列表
[AppleScript] 纯文本查看 复制代码 df %>%
mutate(x2 = stringr::str_split(x1, ",")) %>%
unnest()
sim <- tribble(
~f, ~params,
"runif", list(min = -1, max = -1),
"rnorm", list(sd = 5),
"rpois", list(lambda = 10)
)
sim %>%
mutate(sims = invoke_map(f, params, n = 10))
#3.3 使用summarize()以及能够返回多个结果的摘要函数
# summarize()函数的一个局限性是只能使用返回单一值的摘要函数,
# 像quantile()这样会返回任意长度的向量的函数不能使用
[AppleScript] 纯文本查看 复制代码 mtcars %>%
group_by(cyl) %>%
summarize(q = quantile(mpg))
mtcars %>%
group_by(cyl) %>%
summarize(q = list(quantile(mpg)))
probs <- c(.01, .25, .5, .75, .99)
mtcars %>%
group_by(cyl) %>%
summarize(p = list(probs), q = list(quantile(mpg, probs))) %>%
unnest()
#3.4 使用命名列表
[AppleScript] 纯文本查看 复制代码 x <- list(
a = 1:5,
b = 3:4,
c = 5:6
)
df <- enframe(x)
df
# 使用enframe快速创建数据框:一列包含元素名称,一列包含元素中的列表内容
# 如果要对名称和值进行迭代,可使用map2()函数
[AppleScript] 纯文本查看 复制代码 df %>%
mutate(
smry = map2_chr(
name,
value,
~ stringr::str_c(.x, ":", .y[1])
)
)
#4 简化列表列
#4.1 列表转换为向量
[AppleScript] 纯文本查看 复制代码 df <- tribble(
~x,
letters[1:5],
1:3,
runif(5)
)
df %>% mutate(
type = map_chr(x, typeof),
length = map_int(x, length)
)
df <- tribble(
~x,
list(a = 1, b = 2),
list(a = 2, c = 4)
)
df
df %>%mutate(
a = map_dbl(x, "a"),
b = map_dbl(x, "b", .null = NA_real_)
)
#4.2 嵌套还原
# unnest()函数对列表列的每个元素都重复一次普通列
[AppleScript] 纯文本查看 复制代码 x <- 1:2
x
y <- list(1:4, 1)
y
tibble(x = 1:2, y = list(1:4, 1)) %>%
unnest(y)
# 以上示例,第一行重复4次(y中第一的元素的长度为4),
# 意味着不能同时还原包含不同数量元素的两个列表列
[AppleScript] 纯文本查看 复制代码 df1 <- tribble(
~x,~y,~z,
1, c("a", "b"), 1:2,
2,"c", 3
)
df1
df1 %>% unnest(y, z)
# y和z中的元素数量都相同,所以以上代码可运行
# 以下代码不能运行——y和z每行中的元素数量不同
[AppleScript] 纯文本查看 复制代码 df2 <- tribble(
~x, ~y, ~z,
1, "a", 1:2,
2, c("b", "c"), 3
)
df2
df2 %>% unnest(y, z)
#5 使用broom生成整洁数据
# broom包提供了3种常用工具,将模型转换为整洁数据框
# broom::glance(model)为每个模型返回一行数据,其中每一列都是模型的一个摘要统计量,
# 要么是模型质量的度量方式,要么是模型复杂度,又或者是二者组合
# broom::tidy(model)为模型的每个系数返回一行数据,其中每一列都是系数的估计值或变异指标
# broom::augment(model, data)返回data中的每一行,但不会添加一些额外信息,
# 如残差以及其他一些有影响的统计量
|
-
-
|