10.8 其他函数介绍
10.8.1 flatten 系列
flatten()
系列函数可以将列表输出为稳定类型,通过flatten_
函数后缀表明输出类型。
<- rerun(2, sample(4)) # rerun purrr 中的函数
x
x%>% flatten()
x %>% flatten_int()
x
# 提取列表的第一个元素
%>% map(1L) %>% flatten_int()
x # 下面的方式效率更高
%>% map_int(1L) x
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, ...)
<- list(0:10, 5.5)
y %>% every(is.numeric)
y #> [1] TRUE
%>% every(is.integer)
y #> [1] FALSE
%>% some(is.integer)
y #> [1] TRUE
%>% none(is.character)
y #> [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()
实现一种通用形式的元素提取。
<- list("a", list(1, elt = "foo"))
obj1 <- list("b", list(2, elt = "bar"))
obj2 <- list(obj1, obj2) x
pluck(x, 1)
#> [[1]]
#> [1] "a"
#>
#> [[2]]
#> [[2]][[1]]
#> [1] 1
#>
#> [[2]]$elt
#> [1] "foo"
1]]
x[[#> [[1]]
#> [1] "a"
#>
#> [[2]]
#> [[2]][[1]]
#> [1] 1
#>
#> [[2]]$elt
#> [1] "foo"
pluck(x, 1, 2)
#> [[1]]
#> [1] 1
#>
#> $elt
#> [1] "foo"
1]][[2]]
x[[#> [[1]]
#> [1] 1
#>
#> $elt
#> [1] "foo"
pluck(x, 1, 2, "elt")
#> [1] "foo"
1]][[2]][["elt"]]
x[[#> [1] "foo"
10.8.6 筛选函数
keep()
和discard()
函数筛选元素,keep()
保留计算后为 TRUE 的结果,discard()
保留计算后为 FALSE 的结果。
keep(.x, .p, ...)
discard(.x, .p, ...)
compact(.x, .p = identity)
.p 参数是一个谓词函数(predicate function),谓词函数返回单个的TRUE
或FALSE
。
筛选从 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 的记录。
<- rerun(5, a = rbernoulli(1), b = sample(10))
x %>% keep("a")
x #> [[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
%>% discard("a")
x #> [[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