map(映射)与reduce(规约)操作在数据处理中非常常见,R语言的核心是向量化操作,自带的apply系列函数完成了数据框的向量化计算,而purrr包中的map与reduce系列函数很好的拓展了向量化计算,使R语言处理数据更加优雅流畅。
purrr 包是tidyverse 系列中的包,开发者是大名鼎鼎的Hadley Wickham。purrr 包中的函数很多,使用最多的是map 与reduce 系列函数。
安装包
install.packages('purrr')
map
map 表示映射,可以在一个或多个列表/向量的每个位置上应用相同函数进行计算。map 函数的映射对象只有一个。

map(.x, .f, …)
.x : 列表或向量;
.f : 映射函数;
... : 映射函数的其他参数
# 加载包
library(purrr)
# 单个向量map
1:4 %>%
map(rnorm)
## [[1]]
## [1] 0.1892454
##
## [[2]]
## [1] -1.149757 1.782667
##
## [[3]]
## [1] 0.9311241 0.5962078 0.8575180
##
## [[4]]
## [1] 1.2708588 0.7957794 -0.0106283 0.5393979
从map 函数的结果来看,其返回与输入向量等长的结果,类型为列表。
其他参数
可以指定映射函数的其他参数:
# 单个向量map,指定函数参数
1:4 %>%
map(rnorm,mean=1,sd=2)
## [[1]]
## [1] 1.610763
##
## [[2]]
## [1] -0.4034499 1.5814313
##
## [[3]]
## [1] 2.806429 1.719962 2.005490
##
## [[4]]
## [1] 2.170663 2.849836 1.085069 4.130320
匿名函数
传入的函数可以是匿名函数:
# 单个向量map,使用匿名函数
1:4 %>%
map(function(x) rnorm(x))
## [[1]]
## [1] 0.01422782
##
## [[2]]
## [1] 1.7895586 0.7135593
##
## [[3]]
## [1] 0.0603224 1.0498781 -1.0028828
##
## [[4]]
## [1] 0.2673761 -1.1297717 0.7769814 1.5304043
公式函数
还可以把函数当成一个公式传入,这是purrr 提供的高级功能,能够简化代码量。
- 当函数只有一个参数时,公式函数中用
.x 代替参数;
- 当函数有两个参数时,公式函数中用
.x ,.y 代替参数;
- 当函数有多个参数时,公式函数中用
..1 ,..2 ,..3 代替参数。
# 单个向量map,使用公式函数
1:4 %>%
map(~rnorm(.x))
## [[1]]
## [1] -1.471681
##
## [[2]]
## [1] -0.04243286 -0.68348293
##
## [[3]]
## [1] 1.613470 -0.750001 -1.278718
##
## [[4]]
## [1] 0.9369563 -0.5285622 0.8601058 1.8868754
map2
map2 函数是map 函数的变形,映射对象有两个,需要注意两个列表/向量的长度必须相同。

map2(.x,.y, .f, …)
.x : 列表或向量;
.y : 列表或向量,与.x 等长;
.f : 映射函数;
... : 映射函数的其他参数
# 两个向量map
map2(1:3,2:4,sum)
## [[1]]
## [1] 3
##
## [[2]]
## [1] 5
##
## [[3]]
## [1] 7
用公式函数的方式:
# 两个向量map,使用公式函数
map2(1:3,2:4,~sum(.x,.y))
## [[1]]
## [1] 3
##
## [[2]]
## [1] 5
##
## [[3]]
## [1] 7
# 两个向量map,使用公式函数
map2(1:3,2:4,~sum(..1,..2))
## [[1]]
## [1] 3
##
## [[2]]
## [1] 5
##
## [[3]]
## [1] 7
pmap
pmap 函数是map 函数的变形,映射对象为多个,需要注意多个列表/向量的长度必须相同。

pmap(.l, .f, …)
.l : 列表向量/列表;
.f : 映射函数;
... : 映射函数的其他参数
# 多个向量map
pmap(list(1:3,2:4,3:5),sum)
## [[1]]
## [1] 6
##
## [[2]]
## [1] 9
##
## [[3]]
## [1] 12
用公式函数的方式:
# 多个向量map,使用公式函数
pmap(list(1:3,2:4,3:5),~sum(..1,..2,..3))
## [[1]]
## [1] 6
##
## [[2]]
## [1] 9
##
## [[3]]
## [1] 12
map变形
map ,map2 和pmap 返回的数据格式都是列表,有时候需要对返回的结果进行数据格式转换,这时候可以直接使用map系列的变形函数,直接一步完成。
## $mpg
## [1] 20.09062
##
## $cyl
## [1] 6.1875
##
## $disp
## [1] 230.7219
##
## $hp
## [1] 146.6875
##
## $drat
## [1] 3.596563
##
## $wt
## [1] 3.21725
##
## $qsec
## [1] 17.84875
##
## $vs
## [1] 0.4375
##
## $am
## [1] 0.40625
##
## $gear
## [1] 3.6875
##
## $carb
## [1] 2.8125
使用map_df 函数,直接返回数据框格式。
# 返回数据框
map_df(mtcars,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
# 返回字符向量
map_chr(mtcars,mean)
## mpg cyl disp hp drat wt
## "20.090625" "6.187500" "230.721875" "146.687500" "3.596563" "3.217250"
## qsec vs am gear carb
## "17.848750" "0.437500" "0.406250" "3.687500" "2.812500"
其他的有:
map_lgl /map2_lgl /pmap_lgl :返回逻辑向量;
map_int /map2_int /pmap_int :返回整数向量;
map_dbl /map2_dbl /pmap_dbl :返回浮点数向量;
map_chr /map2_chr /pmap_chr :返回字符串向量。
reduce
reduce 函数表示规约,计算向量中相邻的两个元素,结果再与第三个元素计算,…,最后计算出一个值。

reduce(.x, .f, …)
.x : 列表向量/列表;
.f : 规约函数;
... : 函数的其他参数
# 单个向量reduce
reduce(1:5,paste)
## [1] "1 2 3 4 5"
reduce2
reduce2 函数可以同时对两个向量进行规约计算,注意第二个向量长度需要比第一个向量小1。
reduce2(.x, .y,.f, …)
.x : 列表向量/列表;
.y : 列表向量/列表,长度比.x 小1;
.f : 规约函数;
... : 函数的其他参数
# 多个向量reduce
reduce2(1:4,c(1,1,1),function(x,y,z) x+y-z)
## [1] 7
计算逻辑为第一次:1+2-1=2,第二次2+3-1=4,第三次4+4-1=7。
更多的purrr包中函数用法,可以参考:cheatsheet
以上就是浅析R语言中map与reduce的详细内容,更多关于R语言map与reduce的资料请关注社区其它相关文章! |