R for data science chap19——使用purrr和broom处理多个模型

19.2 列表列

dataframe

  • data.frame()默认将列表作为列的列表处理
> data.frame(x=list(1:3,3:5))
  x.1.3 x.3.5
1     1     3
2     2     4
3     3     5

解决:使用I()

> data.frame(
+   x=I(list(1:3,3:5)),
+   y=c("1,2","3,4,5")
+ )
        x     y
1 1, 2, 3   1,2
2 3, 4, 5 3,4,5

tibble

  • 不需要修改输入
> tibble(
+   x=list(1:3,3:5),
+   y=c("1,2","3,4,5")
+ )
# A tibble: 2 x 2
  x         y    
  <list>    <chr>
1 <int [3]> 1,2  
2 <int [3]> 3,4,5
> tb <-  tibble(
+   x=list(1:3,3:5),
+   y=c("1,2","3,4,5")
+ )
> tb$x
[[1]]
[1] 1 2 3

[[2]]
[1] 3 4 5

> tb$y
[1] "1,2"   "3,4,5"

tribble()

  • tribble()比tibble()更容易,可以自动识别想要的列表
> trb <-  tribble(
+   ~x,~y,
+   1:3,"1,2",
+   3:5,"3,4,5"
+ )
> trb
# A tibble: 2 x 2
  x         y    
  <list>    <chr>
1 <int [3]> 1,2  
2 <int [3]> 3,4,5

19.3 创建列表列

19.3.1 使用嵌套; nest()

  • 嵌套数据框
元观测
列 (列表列) 组成元观测的具体观测
列(其他) 定义观测的变量
  • nest() 的使用
    • 用于分组数据框:保留用于分组的列,而将其他所有数据归并到列表列中(其他所有数据归并到列表列)
    • 用于未分组数据框: 需要指定嵌套哪些列

19.3.2 使用向量化函数

> df <-  tribble(
+   ~x1,
+   "a,b,c",
+   "d,e,f,g"
+ )

> str_split(df$x1,",")
[[1]]
[1] "a" "b" "c"

[[2]]
[1] "d" "e" "f" "g"
#嵌套:mutate(function()) [function()生成一个list]
> df %>% 
+   mutate(x2= str_split(x1,","))
# A tibble: 2 x 2
  x1      x2       
  <chr>   <list>   
1 a,b,c   <chr [3]>
2 d,e,f,g <chr [4]>
# 还原嵌套:unnest()
> df %>% 
+   mutate(x2= str_split(x1,",")) %>% 
+   unnest()
# A tibble: 7 x 2
  x1      x2   
  <chr>   <chr>
1 a,b,c   a    
2 a,b,c   b    
3 a,b,c   c    
4 d,e,f,g d    
5 d,e,f,g e    
6 d,e,f,g f    
7 d,e,f,g g  
# 调用不同函数
> 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))
# A tibble: 3 x 3
  f     params           sims      
  <chr> <list>           <list>    
1 runif <named list [2]> <dbl [10]>
2 rnorm <named list [1]> <dbl [10]>
3 rpois <named list [1]> <int [10]>

19.3.3 使用多值摘要

summarize()只能返回单一值的摘要函数,对于返回更长向量的函数,可以将结果包装在一个list中

> mtcars %>% 
+   group_by(cyl) %>% 
+   summarize(q = quantile(mpg))
`summarise()` regrouping output by 'cyl' (override with `.groups` argument)
# A tibble: 15 x 2
# Groups:   cyl [3]
     cyl     q
   <dbl> <dbl>
 1     4  21.4
 2     4  22.8
 3     4  26  
 4     4  30.4
 5     4  33.9
 6     6  17.8
 7     6  18.6
 8     6  19.7
 9     6  21  
10     6  21.4
11     8  10.4
12     8  14.4
13     8  15.2
14     8  16.2
15     8  19.2

我也不知道为啥这里没有报错/(ㄒoㄒ)/~~

* 修改代码: 将结果包装为list

> mtcars %>% 
+   group_by(cyl) %>% 
+   summarize(q = list(quantile(mpg)))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 3 x 2
    cyl q        
  <dbl> <list>   
1     4 <dbl [5]>
2     6 <dbl [5]>
3     8 <dbl [5]>

酱紫就对啦O(∩_∩)O

By the way, group_by 在不搭配其他函数使用就没什么用

> mtcars %>% group_by(cyl)
# A tibble: 32 x 11
# Groups:   cyl [3]
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
 2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
 3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
 4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
 5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
 6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
 7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
 8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
 9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4

看起来啥也没变,但没有毛病就是酱紫

直接unnes()显示结果

> mtcars %>% 
+   group_by(cyl) %>% 
+   summarize(q = list(quantile(mpg))) %>% 
+   unnest()
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 15 x 2
     cyl     q
   <dbl> <dbl>
 1     4  21.4
 2     4  22.8
 3     4  26  
 4     4  30.4
 5     4  33.9
 6     6  17.8
 7     6  18.6
 8     6  19.7
 9     6  21  
10     6  21.4
11     8  10.4
12     8  14.4
13     8  15.2
14     8  16.2
15     8  19.2
Warning message:
`cols` is now required when using unnest().
Please use `cols = c(q)` 

为了让结果和比率值一同显示

> mtcars %>% 
+   group_by(cyl) %>% 
+   summarise(p=list(probs),q=list(quantile(mpg,probs))) %>% 
+   unnest()
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 15 x 3
     cyl     p     q
   <dbl> <dbl> <dbl>
 1     4  0.01  21.4
 2     4  0.25  22.8
 3     4  0.5   26  
 4     4  0.75  30.4
 5     4  0.99  33.8
 6     6  0.01  17.8
 7     6  0.25  18.6
 8     6  0.5   19.7
 9     6  0.75  21  
10     6  0.99  21.4
11     8  0.01  10.4
12     8  0.25  14.4
13     8  0.5   15.2
14     8  0.75  16.2
15     8  0.99  19.1

19.3.4 使用命名列表

> x <-  list(
+   a=1:5,
+   b=3:4,
+   c=5:6
+ )
> x
$a
[1] 1 2 3 4 5

$b
[1] 3 4

$c
[1] 5 6

> df <-  enframe(x)
> df
# A tibble: 3 x 2
  name  value    
  <chr> <list>   
1 a     <int [5]>
2 b     <int [2]>
3 c     <int [2]>
> library(stringr)
> ?str_c
> x <-  list(
+   a=1:5,
+   b=3:4,
+   c=5:6
+ )
> x
$a
[1] 1 2 3 4 5

$b
[1] 3 4

$c
[1] 5 6

> df <-  enframe(x)
> df
# A tibble: 3 x 2
  name  value    
  <chr> <list>   
1 a     <int [5]>
2 b     <int [2]>
3 c     <int [2]>
> library(stringr)
> df %>% 
+   mutate(
+     smry= map2_chr(
+       name,
+       value,
+       ~str_c(.x,":",y[1])
+     )
+   )
Error: Problem with `mutate()` input `smry`.
x object 'y' not found
i Input `smry` is `map2_chr(name, value, ~str_c(.x, ":", y[1]))`.
Run `rlang::last_error()` to see where the error occurred.
> df
# A tibble: 3 x 2
  name  value    
  <chr> <list>   
1 a     <int [5]>
2 b     <int [2]>
3 c     <int [2]>
> df %>% 
+   mutate(
+     smry= map2_chr(
+       name,
+       value,
+       ~str_c(.x,":",.y[1])
+     )
+   )
# A tibble: 3 x 3
  name  value     smry 
  <chr> <list>    <chr>
1 a     <int [5]> a:1  
2 b     <int [2]> b:3  
3 c     <int [2]> c:5  

注意,str_c(.x,":",.y) .漏掉会报错

异构列表筛选必备!!!(。^▽^)

  • 根据类型筛选
> df %>% 
+   mutate(
+     smry= map2_chr(
+       name,
+       value,
+       ~str_c(.x,":",y[1])
+     )
+   )
Error: Problem with `mutate()` input `smry`.
x object 'y' not found
i Input `smry` is `map2_chr(name, value, ~str_c(.x, ":", y[1]))`.

19.4 简化列表列

> df <-  tribble(
+   ~x,
+   letters[1:5],
+   1:3,
+   runif(5)
+ )
> df
# A tibble: 3 x 1
  x        
  <list>   
1 <chr [5]>
2 <int [3]>
3 <dbl [5]>

> df %>% 
+   mutate(
+     type= map_chr(x,typeof),
+     length= map_int(x,length)
+   )
# A tibble: 3 x 3
  x         type      length
  <list>    <chr>      <int>
1 <chr [5]> character      5
2 <int [3]> integer        3
3 <dbl [5]> double         5
  • 从list中x的所有元素中提取指定变量中的内容

.null=NA_real_ 可以提供一个缺失值的返回值

df <- tribble(
  ~x,
  list(a=1,b=2),
  list(a=2,c=4)
)
> df2 %>% 
+   mutate(
+   a= map_dbl(x,"a"),
+   b= map_dbl(x,"b",.null=NA_real_)
+ )
# A tibble: 2 x 3
  x                    a     b
  <list>           <dbl> <dbl>
1 <named list [2]>     1     2
2 <named list [2]>     2    NA

19.4.2 嵌套还原

> tibble(
+   x=1:2,
+   y=list(1:4,1)
+ )
# A tibble: 2 x 2
      x y        
  <int> <list>   
1     1 <int [4]>
2     2 <dbl [1]>


> tibble(
+   x=1:2,
+   y=list(1:4,1)
+ ) %>% 
+   unnest()
# A tibble: 5 x 2
      x     y
  <int> <dbl>
1     1     1
2     1     2
3     1     3
4     1     4
5     2     1
Warning message:
`cols` is now required when using unnest().
Please use `cols = c(y)` 

第二行之重复了一次,这意味着:

  • 不能同时还原包含不同数量元素的两个列表列
df1 <- tribble(
  ~x,~y,~z,
  1,c("a","b"),1:2,
  2,"c",3
)
df1
df1 %>% unnest()

y和z每行中元素数量相等,可以正常运行

> df1 <- tribble(
+   ~x,~y,~z,
+   1,c("a","b"),1:2,
+   2,c("b","c"),3
+ )
> df1
# A tibble: 2 x 3
      x y         z        
  <dbl> <list>    <list>   
1     1 <chr [2]> <int [2]>
2     2 <chr [2]> <dbl [1]>
> df1 %>% unnest()
# A tibble: 4 x 3
      x y         z
  <dbl> <chr> <dbl>
1     1 a         1
2     1 b         2
3     2 b         3
4     2 c         3
Warning message:
`cols` is now required when using unnest().
Please use `cols = c(y, z)` 

(lll¬ω¬)书上这里应该跑不出来……可能更新后level up 了,应该x、y、z元素数量相同就可以

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350