map()函数系列只接受一个向量,也就意味着,如果应用的函数要使用多个参数,map()将不能满足要求。于是就有了map2()系列函数,该函数接受两个长度相等的向量;又有了pmap()系列函数,接受包含任意数量向量的list。
map2(.x, .y, .f, ...)
pmap(.l, .f, ...)
.x,.y:长度相等的两个向量。
.l:包含任意数量长度相等的向量
.f:函数
之所以强调长度相同,是因为对参数取值的时候是按照向量中元素的位置对应取的。
注意:
.l可以是数据框,因为数据框中每列元素长度是相同的,这时候数据框中每一行代表一个参数的集合。
.l中各元素最好有名字,在参数较多的时候不易混淆,如果没有,则按照元素的position与.f函数argument的position匹配对应。
很好理解,举个例子:
# map2的例子
> mean<-seq(2.5,by=0.5,length.out=5)
> sd<-seq(0.5,by=0.1,length.out=5)
> map2(mean,sd,rnorm,n=5)
[[1]]
[1] 2.707987 2.097706 2.629040 1.693120 2.182847
[[2]]
[1] 3.565576 4.158574 2.602185 3.712357 3.479760
[[3]]
[1] 2.387515 4.347132 3.849035 3.431501 3.322924
[[4]]
[1] 4.250193 4.017156 4.042094 3.766900 3.328678
[[5]]
[1] 3.499739 4.967311 4.808283 4.279979 3.564106
# pmap的例子
> n<-1:5
> pmap(list(n,mean,sd),rnorm)
[[1]]
[1] 2.623169
[[2]]
[1] 3.059194 3.650276
[[3]]
[1] 2.738240 3.976271 2.630571
[[4]]
[1] 3.966740 4.238888 4.011116 5.164612
[[5]]
[1] 4.446307 4.674053 4.736802 4.177793 5.726234
上述是.f的参数组合,那如果想每次调用不同的参数呢?那就用到了invoke_map()系列函数了。
invoke(.f, .x = NULL, ..., .env = NULL)
invoke_map(.f, .x = list(NULL), ..., .env = NULL)
对invoke(),.f是一个函数;
对invoke_map(),.f是一个函数向量。
对invoke(),.x是一个list,包含.f对应的参数;
对invoke_map(),.x也是一个list,但list中的每个元素是包含各个参数对应参数的list。
...是传递给每个函数的其他参数
举个例子:
> flist <- c("dnorm","pnorm","qnorm","rnorm")
> xlist <- list(list(mean=0,sd=1,log=T),list(mean=0,sd=4,lower.tail=F),list(mean=0,sd=3,log.p=T),list(mean=0,sd=1.5))
> invoke_map(flist,xlist,seq(0.1,by=0.05,length.out=10))
[[1]]
[1] -0.9239385 -0.9301885 -0.9389385 -0.9501885 -0.9639385 -0.9801885
[7] -0.9989385 -1.0201885 -1.0439385 -1.0701885
[[2]]
[1] 0.4900275 0.4850432 0.4800612 0.4750823 0.4701074 0.4651370 0.4601722
[8] 0.4552135 0.4502618 0.4453178
[[3]]
[1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
[[4]]
[1] -0.1492631 1.3761858 1.2094010 0.3567733 -1.2777846 3.5718251
[7] -1.2376648 1.5243120 1.6198988 3.9988839
walk()、walk2()、pwalk()与map()类似,但这个系列的函数只调用函数for its side-effect,返回.x或.l,也就是第一个参数。
walk(.x, .f, ...)
walk2(.x, .y, .f, ...)
pwalk(.l, .f, ...)
书中列出的一个pwalk()的应用很有趣:循环保存图片。
library(ggplot2)
plots <- mtcars %>%
split(.$cyl) %>%
map(~ggplot(., aes(mpg, wt)) + geom_point())
paths <- stringr::str_c(names(plots), ".pdf")
pwalk(list(paths, plots), ggsave, path = tempdir())
网友评论