10.8 其他函数介绍

10.8.1 flatten 系列

flatten()系列函数可以将列表输出为稳定类型,通过flatten_函数后缀表明输出类型。

x <- rerun(2, sample(4)) # rerun purrr 中的函数
x
x %>% flatten()
x %>% flatten_int()

# 提取列表的第一个元素
x %>% map(1L) %>% flatten_int()
# 下面的方式效率更高
x %>% map_int(1L)

10.8.2 imap 函数

imap()系列函数官方描述:

imap_xxx(x, …), an indexed map, is short hand for map2(x, names(x), …) if x has names, or map2(x, seq_along(x), …) if it does not. This is useful if you need to compute on both the value and the position of an element.

imap,当x有names(x)或者seq_along(x)属性,imap是map2的另一种表达方式。

详情请查看:?imap

案例:

imap_chr(sample(10), ~ paste0(.y, ": ", .x))
#>  [1] "1: 6"  "2: 2"  "3: 7"  "4: 9"  "5: 10" "6: 8"  "7: 5"  "8: 4"  "9: 3" 
#> [10] "10: 1"

sample(10),没有names(),只有长度信息。转化成map2表达如下:

map2_chr(sample(10),1:10,~paste0(.y,": ",.x)) # 第二个list 为位置信息.
#>  [1] "1: 3"   "2: 4"   "3: 6"   "4: 8"   "5: 2"   "6: 5"   "7: 1"   "8: 7"  
#>  [9] "9: 9"   "10: 10"

10.8.3 walk 系列

对于不关心过程或结果的操作可以采用该系列函数,比如打印,做图,批量输出数据,上传数据库等。

iwalk(mtcars, ~ cat(.y, ": ", median(.x), "\n", sep = ""))
#> mpg: 19.2
#> cyl: 6
#> disp: 196
#> hp: 123
#> drat: 3.7
#> wt: 3.33
#> qsec: 17.7
#> vs: 0
#> am: 0
#> gear: 4
#> carb: 2

个人觉得iwalk()和前文数据导入导出章节中提到的批量输出group_walk()函数功能有相似之处。

dt %>% 
  group_by(name) %>% 
  group_walk(~ write.csv(.x,file = file.path('data/read-write',paste0(.y$name,'.csv'))))

同上,iwalk()函数家族还有walk2()pwalk()`函数,函数间区别与 map 族函数间区别类似。

10.8.4 逻辑判断函数

判断序列中是否存在任意/存在元素满足条件

every(.x, .p, ...)

some(.x, .p, ...)

none(.x, .p, ...)
y <- list(0:10, 5.5)
y %>% every(is.numeric)
#> [1] TRUE
y %>% every(is.integer)
#> [1] FALSE
y %>% some(is.integer)
#> [1] TRUE
y %>% none(is.character)
#> [1] TRUE

应用在dplyr动词中:

mpg %>%
  group_by(manufacturer) %>% 
  mutate(a = every(cty, ~ .x > 10) )
#> # A tibble: 234 x 12
#> # Groups:   manufacturer [15]
#>   manufacturer model displ  year   cyl trans drv     cty   hwy fl    class a    
#>   <chr>        <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr> <lgl>
#> 1 audi         a4      1.8  1999     4 auto~ f        18    29 p     comp~ TRUE 
#> 2 audi         a4      1.8  1999     4 manu~ f        21    29 p     comp~ TRUE 
#> 3 audi         a4      2    2008     4 manu~ f        20    31 p     comp~ TRUE 
#> 4 audi         a4      2    2008     4 auto~ f        21    30 p     comp~ TRUE 
#> 5 audi         a4      2.8  1999     6 auto~ f        16    26 p     comp~ TRUE 
#> 6 audi         a4      2.8  1999     6 manu~ f        18    26 p     comp~ TRUE 
#> # ... with 228 more rows

10.8.5 提取函数

pluck()chuck()实现一种通用形式的元素提取。

obj1 <- list("a", list(1, elt = "foo"))
obj2 <- list("b", list(2, elt = "bar"))
x <- list(obj1, obj2)
pluck(x, 1)
#> [[1]]
#> [1] "a"
#> 
#> [[2]]
#> [[2]][[1]]
#> [1] 1
#> 
#> [[2]]$elt
#> [1] "foo"
x[[1]]
#> [[1]]
#> [1] "a"
#> 
#> [[2]]
#> [[2]][[1]]
#> [1] 1
#> 
#> [[2]]$elt
#> [1] "foo"

pluck(x, 1, 2)
#> [[1]]
#> [1] 1
#> 
#> $elt
#> [1] "foo"
x[[1]][[2]]
#> [[1]]
#> [1] 1
#> 
#> $elt
#> [1] "foo"

pluck(x, 1, 2, "elt")
#> [1] "foo"
x[[1]][[2]][["elt"]]
#> [1] "foo"

10.8.6 筛选函数

keep()discard()函数筛选元素,keep()保留计算后为 TRUE 的结果,discard()保留计算后为 FALSE 的结果。

keep(.x, .p, ...)
discard(.x, .p, ...)
compact(.x, .p = identity)

.p 参数是一个谓词函数(predicate function),谓词函数返回单个的TRUEFALSE

筛选从 1:10 中随机生成的 5 个数字,保留均值大于的记录。

rep(10, 10) %>%
  map(sample, 5) %>%
  keep(~ mean(.x) > 6)
#> [[1]]
#> [1]  8 10  6  9  7
#> 
#> [[2]]
#> [1]  8  7  2  5 10
#> 
#> [[3]]
#> [1] 7 4 9 8 3

筛选列表(list) x 中“a”元素为 TRUE 或 FALSE 的记录。

x <- rerun(5, a = rbernoulli(1), b = sample(10))
x %>% keep("a")
#> [[1]]
#> [[1]]$a
#> [1] TRUE
#> 
#> [[1]]$b
#>  [1]  4  9  6  5  8  2  7  1 10  3
#> 
#> 
#> [[2]]
#> [[2]]$a
#> [1] TRUE
#> 
#> [[2]]$b
#>  [1]  2  8 10  6  7  1  5  3  4  9
x %>% discard("a")
#> [[1]]
#> [[1]]$a
#> [1] FALSE
#> 
#> [[1]]$b
#>  [1]  6  9  5  7  4  1  8 10  2  3
#> 
#> 
#> [[2]]
#> [[2]]$a
#> [1] FALSE
#> 
#> [[2]]$b
#>  [1]  8  7  6  9  3  2 10  5  1  4
#> 
#> 
#> [[3]]
#> [[3]]$a
#> [1] FALSE
#> 
#> [[3]]$b
#>  [1]  6  8 10  7  3  4  2  5  9  1

compact() 舍弃 NULL 元素和长度为 0 的元素。

list(a = "a", b = NULL, c = integer(0), d = NA, e = list()) %>%
  compact()
#> $a
#> [1] "a"
#> 
#> $d
#> [1] NA