library(tidyverse)
rm(list = ls())

本系列主要是又来挖坑想对tidyverse(Wickham 2023)这个整合包的各个包的使用说明做一个完整的中文介绍。本章主要介绍purrr(Wickham and Henry 2023)purrr包通常被称为“优雅的循环迭代包”,它比for循环的速度快,代码更容读。
# map()函数

0.1 一个列表

  1. map(.x, .f, ...)map系列函数会将一个函数应用到输入的列表或向量的每个元素上面,然后返回一个list。比如:
x <- list(1:10, 11:20, 21:30)

l1 <- list(x = c("a", "b"), y = c("c", "d"))

map(l1, sort, decreasing = T )
# $x
# [1] "b" "a"
# 
# $y
# [1] "d" "c"
  1. map_dbl(.x, .f, ...)返回双精度向量
# map_dbl(x, ~ mean(.x, na.rm = T))
map_dbl(x, mean)
# [1]  5.5 15.5 25.5
  1. map_int返回整数向量,注意对于计算结果不是整数的函数,使用map_int程序会报错。
map_int(x, length)
# [1] 10 10 10
  1. map_chr, 返回字符向量。
map_chr(l1, paste, collapse = ",")
#     x     y 
# "a,b" "c,d"
  1. map_lgl返回逻辑向量

  2. map_dfc返回一个按列合并的数据框,注意对于每一个元素运行候返回的值要长度

map_dfc(l1, rep, 3)
# # A tibble: 6 × 2
#   x     y    
#   <chr> <chr>
# 1 a     c    
# 2 b     d    
# 3 a     c    
# 4 b     d    
# 5 a     c    
# 6 b     d

对于这个结果感到疑惑的,我们可以单独l1中的元素运行rep看看结果,就更好理解了。

rep(l1$x,3)
# [1] "a" "b" "a" "b" "a" "b"
rep(l1$y, 3)
# [1] "c" "d" "c" "d" "c" "d"

对于map_dfc运行的结果,看作是做了以下操作

df <- as.data.frame(matrix(nrow = length(l1[[1]]) * 3, ncol = 0))

for (i in 1:length(l1)) {
  df <- bind_cols(df, data.frame(rep(l1[[i]], 3)))
  colnames(df)[[i]] <- names(l1)[[i]]
}
df
#   x y
# 1 a c
# 2 b d
# 3 a c
# 4 b d
# 5 a c
# 6 b d
  1. map_dfr,返回按行合并的数据框。
map_dfr(x, summary)
# # A tibble: 3 × 6
#   Min.        `1st Qu.`   Median      Mean        `3rd Qu.`   Max.       
#   <table[1d]> <table[1d]> <table[1d]> <table[1d]> <table[1d]> <table[1d]>
# 1  1           3.25        5.5         5.5         7.75       10         
# 2 11          13.25       15.5        15.5        17.75       20         
# 3 21          23.25       25.5        25.5        27.75       30
  1. walkwalk 函数并不会返回任何结果,有时仅需要遍历一个数据结构调用函数进行一些显示、绘图, 这称为函数的side effect, 不需要返回结果。比如用cat查看并输出数据框中的变量类别
walk(x, print)
#  [1]  1  2  3  4  5  6  7  8  9 10
#  [1] 11 12 13 14 15 16 17 18 19 20
#  [1] 21 22 23 24 25 26 27 28 29 30

0.2 两个列表使用map2系列

  1. map2(.x, .f, ...)map函数会将一个函数应用到输入的一对列表或向量的一对元素上面,然后返回一个list。比如:
# x <- list(1:10, 11:20, 21:30)
y <- list(1, 2, 3)
z <- list(4, 5, 6)
l2 <- list(x = "a", y = "z")
map2(x, y, ~ .x * .y)
# [[1]]
#  [1]  1  2  3  4  5  6  7  8  9 10
# 
# [[2]]
#  [1] 22 24 26 28 30 32 34 36 38 40
# 
# [[3]]
#  [1] 63 66 69 72 75 78 81 84 87 90
# list(x[[i]] * y[[i]])
  1. map2_dbl
map2_dbl(y, z, ~ .x / .y)
# [1] 0.25 0.40 0.50
  1. map2_int
map2_int(y, z, ~ (length(c(.x) + length(.y))))
# [1] 1 1 1
Wickham, Hadley. 2023. Tidyverse: Easily Install and Load the Tidyverse. https://CRAN.R-project.org/package=tidyverse.
Wickham, Hadley, and Lionel Henry. 2023. Purrr: Functional Programming Tools. https://CRAN.R-project.org/package=purrr.