我们模拟6个学生10次考试成绩。

scores <- list(  s1 = round(runif(10, 50, 100)),  s2 = round(runif(10, 50, 100)),  s3 = round(runif(10, 50, 100)),  s4 = round(runif(10, 50, 100)),  s5 = round(runif(10, 50, 100)),  s6 = round(runif(10, 50, 100)))scores

我们用列表记录这些学生的成绩。

请问:如何计算每个学生的平均分数?

方案一:base-R的写法

list(  s1 = mean(scores$s1),  s2 = mean(scores$s2),  s3 = mean(scores$s3),  s4 = mean(scores$s4),  s5 = mean(scores$s5),  s6 = mean(scores$s6))

输出结果

函数map是什么意思_map函数_函数map()的语法格式

方案一,不足之处,对scores列表的每个元素重写了mean函数,若是有更多的学生计算平均分数,这种方法费时费力,不精简,还容易出错。

方案二:使用apply的家族函数 lapply函数

lapply(scores, mean)

输出结果同上。

这个写法很简洁,也适合列表含有多个元素的场景

方案三:使用函数式编程,也就是把一个函数作用于列表的每个元素,成功处理完后,重组为一个新的列表。这个逻辑,我们可以使用purrr包的map函数族。可以理解为它们是base-R的apply函数族的升级版本

library(magrittr)library(purrr)map(scores, mean)# 或者# 管道操作和表示scores %>% map(mean)

输出结果同上

为了准确地使用purrr包map函数做函数式编程和应用,我们先深入了解下这个函数的用法。

学习任何函数,三步曲。

第一步:函数输入

第二步:函数体做什么事情

第三步:函数输出

map函数,也不例外

map函数的理解,如下图所示:

函数map()的语法格式_函数map是什么意思_map函数

map函数解读

1)输入部分,第一个参数是列表或者向量,第二个参数是函数(R自带或者自定义的)

2)函数体部分,函数会作用于列表或者向量中的每个元素,进行对应的函数处理

3)输出部分,函数作用于每个元素都会有个输出,所有输出组合成一个新的list。

map函数家族

map函数家族,可以让map返回我们需要的数据格式。如下图所示:

map函数_函数map是什么意思_函数map()的语法格式

例如:

1)6个学生的平均分记为一个向量

scores %>% map_dbl(mean)

输出结果

2)6个学生的平均分保存在数据框里

scores %>% map_df(mean)

输出结果

map函数_函数map是什么意思_函数map()的语法格式

map函数的使用拓展

1 支持添加额外参数

说明,这个额外参数,来自于map函数的第二个参数—函数f的参数。

例如:我们需要对6个学生的分数做降序排列

scores %>% map(sort, decreasing = FALSE)

输出结果

2支持自定义函数

有时候,根据需求,我们需要自定义函数来对列表的每个元素做处理。

例如:对每个学生的成绩做标准化处理

# 第一步:自定义函数my_fun <- function(x){  (x - mean(x))/sd(x)}# 第二步:自定义函数作用于列表的每个元素std_scores % map(my_fun)std_scores# 第三步:检验是否标准化成功std_scores %>% map(mean)std_scores %>% map(var)

3 支持匿名函数

匿名函数就是没有函数名的函数

第一种写法

scores %>% map(function(x) {(x-mean(x))/sd(x)})

第二种写法

scores %>% map(~ {(.x-mean(.x))/sd(.x)})

第三种写法

scores %>% map(~ {(.-mean(.))/sd(.)})

三种写法,输出结果都一样,你可以根据自己的喜好选择一种写法,同时,知道其它写法效果等同就好了。

4 与dplyr包结合使用

dplyr包方便数据处理,purrr包的map函数家族方便做函数式编程,两者结合,可以做更多有趣的事情。

例如,我们想知道列表中每个元素的长度

library(tidyverse)df <- tibble(  x = list(1, 2:3, 4:6)) %>%   mutate(l = purrr::map_int(x, length))df

输出结果

函数map()的语法格式_函数map是什么意思_map函数

例如,用于建模操作

mtcars %>%  group_by(cyl) %>%  nest() %>%  mutate(model = purrr::map(data, ~ lm(mpg ~ wt, data = .))) %>%  mutate(result = purrr::map(model, ~ broom::tidy(.))) %>%  unnest(result)

输出结果

函数map是什么意思_函数map()的语法格式_map函数

总结

purrr包map函数家族,可以实现函数式编程,apply函数家族的升级版本,通过简介代码,实现迭代操作,提升工作效率。

进一步阅读

可以阅读《R数据科学》书籍的第三部分:编程

需要R数据科学书籍的朋友,可以加我微信,备注:R数据科学书籍

需要加入R语言群的朋友,可以加我微信,备注:R群

我的微信luqin360。

限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: lzxmw777

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注