其他
purrr 包之 map 系列函数
purrr 包是 Hadley Wickham 大神编写的高级函数编程语言包,相对于 apply 家族的函数操作,具有更快更好的使用效果,能够更好的提高写代码的效率。里面包含了很多函数,今天来介绍一下 map 的系列函数,** map ** 函数能够对向量或列表使用函数进行迭代操作。
map()函数
map 函数对 .x(向量或列表)的每个元素执行 .f(函数)操作,并返回一个 list,...为执行函数的其它参数。。以下是不同类型的 map 函数返回不同类型的结果:
function | returns | 返回类型 |
---|---|---|
map | list | 列表 |
map_chr | character vector | 字符型 |
map_dbl | double (numeric) vector | 双精度 |
map_df | data frame | 按合并成表格 |
map_dfc | data frame (column bind) | 按列合并成表格 |
map_dfr | data frame (row bind) | 按行合并成表格 |
map_int | integer vector | 整数型 |
map_lgl | logical vector | 逻辑型 |
使用:
# 加载R包
library(dplyr)
library(purrr)
library(datasets)
# 加载测试数据
data("mtcars")
# 查看数据
head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
...
对每列求和:
mtcars %>% map(.,mean)
$mpg
[1] 20.09062
$cyl
[1] 6.1875
$disp
[1] 230.7219
...
返回结果为字符型:
mtcars %>% map_chr(.,mean)
mpg cyl disp hp drat wt qsec
"20.090625" "6.187500" "230.721875" "146.687500" "3.596563" "3.217250" "17.848750"
vs am gear carb
"0.437500" "0.406250" "3.687500" "2.812500"
返回结果为双精度型:
mtcars %>% map_dbl(.,mean)
mpg cyl disp hp drat wt qsec vs am
20.090625 6.187500 230.721875 146.687500 3.596563 3.217250 17.848750 0.437500 0.406250
gear carb
3.687500 2.812500
返回结果为表格按列合并:
mtcars %>% map_dfc(.,mean)
# A tibble: 1 x 11
mpg cyl disp hp drat wt qsec vs am gear carb
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 20.1 6.19 231. 147. 3.60 3.22 17.8 0.438 0.406 3.69 2.81
加入自定义函数使用:
lst <- list(a = c(1:5),b = c(2:6))
# 定义加1函数
myfun <- function(x){x + 1}
# 对每个list元素加1,结果合并成表格
map_df(lst,myfun)
# A tibble: 5 x 2
a b
<dbl> <dbl>
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
多参数,对每个元素取log以2为底数:
lst <- list(a = c(1:5),b = c(2:6))
map(lst,log,base = 2)
$a
[1] 0.000000 1.000000 1.584963 2.000000 2.321928
$b
[1] 1.000000 1.584963 2.000000 2.321928 2.584963
map2()函数
map2 函数对两个向量或列表配对的元素进行 .f(函数)操作,元素长度必须一样,...为执行函数的其它参数。
使用:
对 mpg 和 disp 两列每个对应元素求和:
map2_dbl(mtcars$mpg,mtcars$disp,sum)
[1] 181.0 181.0 130.8 279.4 378.7 243.1 374.3 171.1 163.6 186.8 185.4 292.2 293.1 291.0 482.4 470.4
[17] 454.7 111.1 106.1 105.0 141.6 333.5 319.2 363.3 419.2 106.3 146.3 125.5 366.8 164.7 316.0 142.4
使用自定义函数:
x = c(1:4) ; x
[1] 1 2 3 4
y = c(2:5) ; y
[1] 2 3 4 5
# 定义函数
myfun <- function(x,y){x*x + y}
# 计算,返回双精度
map2_dbl(x,y,myfun)
[1] 3 7 13 21
假如两个向量或列表长度不等:
x = c(1:3) ; x
[1] 1 2 3
y = c(2:5) ; y
[1] 2 3 4 5
myfun <- function(x,y){x*x + y}
map2_dbl(x,y,myfun)
错误: Mapped vectors must have consistent lengths:
* `.x` has length 3
* `.y` has length 4
对两个列表操作:
# lst1
x = c(1:4)
y = c(2:5)
lst1 <- list(x,y) ; lst1
[[1]]
[1] 1 2 3 4
[[2]]
[1] 2 3 4 5
# lst2
a = c(-1:-4) ; a
[1] -1 -2 -3 -4
b = c(-2:-5) ; b
[1] -2 -3 -4 -5
lst2 <- list(a,b) ; lst2
[[1]]
[1] -1 -2 -3 -4
[[2]]
[1] -2 -3 -4 -5
# 定义两个列表每个对应元素相加函数
myfun <- function(x,y){x + y}
# 计算
map2(lst1,lst2,myfun)
[[1]]
[1] 0 0 0 0
[[2]]
[1] 0 0 0 0
多参数,自定义多参数:
myfun <- function(x,y,n = 0){x + y + n}
map2(lst1,lst2,myfun,n=1)
[[1]]
[1] 1 1 1 1
[[2]]
[1] 1 1 1 1
对于 map2 函数,返回结果的类型和 map 相似,只需要 map2_* 跟上相应类型即可:
pmap()函数
pmap 函数可对多个向量或列表对应的元素进行 .f(函数)操作,...为执行函数的其它参数。
使用:
x <- list(1, 1, 1)
y <- list(10, 20, 30)
z <- list(100, 200, 300)
pmap_dbl(list(x, y, z), sum)
[1] 111 221 331
计算x和y的和,再与z的乘积,按位置迭代:
pmap_dbl(list(x, y, z), function(first, second, third) {(first + third) * second})
[1] 1010 4020 9030
计算x和z的和,再与y的乘积,按名字迭代:
l <- list(a = x, b = y, c = z) ; l
$a
$a[[1]]
[1] 1
$a[[2]]
[1] 1
$a[[3]]
[1] 1
...
pmap_dbl(l, function(c, b, a) {(a + c) * b})
[1] 1010 4020 9030
计算mtcars前两列和与后两列和的乘积:
lst <- list(mtcars[,1],mtcars[,2],mtcars[,3],mtcars[,4])
pmap_dbl(lst,function(a,b,c,d){(a + b)*(c + d)})
[1] 7290.00 7290.00 5386.80 10083.20 14284.50 7953.00 13491.50 5927.08 6319.44
[10] 7323.12 6916.28 11121.52 11531.74 10574.56 12456.80 12420.00 15209.00 5267.08
[19] 4392.88 5158.19 5536.05 10998.00 10532.80 12673.50 15640.00 4538.50 6339.00
[28] 7158.64 14637.00 8224.00 14628.00 5842.00
invoke_map()函数
invoke_map函数可以对每个list的元素执行多个不同的函数,...为执行函数的其它参数。
使用:
对x使用两个函数,一个加1,一个减1
lst <- list(fun1 <- function(x){x+1},fun2 <- function(x){x-1})
invoke_map(lst,x = 1:5)
[[1]]
[1] 2 3 4 5 6
[[2]]
[1] 0 1 2 3 4
- END -欢迎小伙伴留言评论!
今天的分享就到这里了,敬请期待下一篇!
最后欢迎大家分享转发,您的点赞是对我的鼓励和肯定!
如果觉得对您帮助很大,打赏一下吧!