R学习:R for Data Science 循环-迭代 purrr 函数代替 for 循环

R学习往期回顾:

R学习:R for Data Science 循环-迭代(for while))

R学习:R for Data Science 向量(1)

R学习:R for Data Science 向量(2)

R学习 从Tidyverse学起,入门R语言 dplyr合并数据

R学习 流程控制 if,else,ifelse

R学习 从Tidyverse学起,入门R语言(tidyr和stringr)

R学习 从Tidyverse学起,入门R语言(tibble,readr和dplyr)

R学习:字符串

R学习:环境和函数

R学习:数据框的基本操作

R学习:R for Data Science(五)

R学习:R for Data Science(四)

R学习:R for Data Science(三)

R学习:R for Data Science(二)

R学习:R for Data Science(一)

for循环与函数式编程

for 循环在 R 中不像在其他语言中那么重要,因为 R 是一门函数式编程语言。这意味着可以先将 for 循环包装在函数中,然后再调用这个函数,而不是直接使用 for 循环

library(tidyverse)df <- tibble( a = rnorm(10), b = rnorm(10), c = rnorm(10), d = rnorm(10))

假设想要计算每列的均值。你可以使用 for 循环来完成这个任务

output <- vector("double", length(df))for (i in seq_along(df)) { output[[i]] <- mean(df[[i]])}output

将这段代码提取出来,转换成一个函数:

col_mean <- function(df) { output <- vector("double", length(df)) for (i in seq_along(df)) { output[i] <- mean(df[[i]]) } output}

还可以算每列的中位数和标准差

col_median <- function(df) { output <- vector("double", length(df)) for (i in seq_along(df)) { output[i] <- median(df[[i]]) } output}col_sd <- function(df) { output <- vector("double", length(df)) for (i in seq_along(df)) { output[i] <- sd(df[[i]]) } output}

通过添加支持函数应用到每列的一个参数,我们可以使用同一个函数完成与 col_mean()、col_median() 和 col_sd() 函数相同的操作:

col_summary <- function(df, fun) { out <- vector("double", length(df)) for (i in seq_along(df)) { out[i] <- fun(df[[i]]) } out}col_summary(df, median)col_summary(df, mean)

将函数作为参数传入另一个函数的这种做法是一种非常强大的功能,它是促使 R 成为函数式编程语言的因素之一。
我们将学习和使用 purrr 包,它提供的函数可以替代很多常见的 for 循环应用。 R 基础包中的应用函数族(apply()、 lapply()、 tapply() 等)也可以完成类似的任务,但 purrr 包中的函数更一致,也更易于学习。

使用 purrr 函数代替 for 循环的目的是将常见的列表处理问题分解为独立的几个部分。
· 对于列表中的单个元素,你能找到解决问题的方法吗?如果找到了解决方法,那么你就可以使用 purrr 将这种方法扩展到列表中的所有元素。

· 如果你面临的是一个非常复杂的问题,那么如何将其分解为几个可行的子问题,然后循序渐进地解决,直至完成最终的解决方案?使用 purrr,你可以解决很多子问题,然后再通过管道操作将这些问题的结果组合起来。

映射函数

先对向量进行循环、然后对其每个元素进行一番处理,最后保存结果。这种模式太普遍了,因此 purrr 包提供了一个函数族来替你完成这种操作。每种类型的输出都有一个相应的函数:
· map() 用于输出列表;
· map_lgl() 用于输出逻辑型向量;
· map_int() 用于输出整型向量;
· map_dbl() 用于输出双精度型向量;
· map_chr() 用于输出字符型向量。

每个函数都使用一个向量作为输入,并对向量的每个元素应用一个函数,然后返回和输入向量同样长度(同样名称)的一个新向量。向量的类型由映射函数的后缀决定。

我们可以使用这些函数来执行与最后一个 for 循环相同的操作。因为那些摘要函数返回的是双精度数,所以我们需要使用 map_dbl() 函数:

map_dbl(df, median)map_dbl(df, mean)

map_*() 和 col_summary() 具有以下几点区别

· 所有 purrr 函数都是用 C 实现的。这使得它们的速度非常快,但牺牲了一些可读性

· 第二个参数(即 .f,要应用的函数)可以是一个公式、一个字符向量或一个整型向量
· map_*() 使用向 .f 传递一些附加参数,供其在每次调用时使用

· 映射函数还可以保留名称

快捷方式

对于参数 .f,你可以使用几种快捷方式来减少输入量。假设你想对某个数据集中的每个分组都拟合一个线性模型。以下这个简单示例将 mtcars 数据集拆分成 3 个部分(按照气缸的值分类),并对每个部分拟合一个线性模型:

models <- mtcars %>% split(.$cyl) %>% map(function(df) lm(mpg ~ wt, data = df))

因为 R 中创建匿名函数的语法比较繁琐,所以 purrr 提供了一种更方便的快捷方式——单侧公式:

models <- mtcars %>% split(.$cyl) %>% map(~lm(mpg ~ wt, data = .))

我们在以上示例中使用了 . 作为一个代词:它表示当前列表元素(与 for 循环中用 i 表示当前索引是一样的)

需要提取出  R平方 这样的摘要统计量

需要先运行 summary() 函数,然后提取出结果中的 r.squared。我们可以使用匿名函数的快捷方式来完成这个操作:

models %>% map(summary) %>% map_dbl(~.$r.squared)

因为提取命名成分的这种操作非常普遍,所以 purrr 提供了一种更为简洁的快捷方式:使用字符串

models %>% map(summary) %>% map_dbl("r.squared")

后面需要有apply()家族函数的基础知识,为了循序渐进,后面我们将会介绍apply家族,下回见。

(0)

相关推荐

  • R语言学习笔记

    R语言学习笔记

  • R语言简单for循环

    欢迎来到医科研,这里是白介素2的读书笔记,跟我一起聊临床与科研的故事, 生物医学数据挖掘,R语言,TCGA.GEO数据挖掘. 简单for循环  创建一个简单数据框 1Sys.setlocale('LC ...

  • R包基础实操—tidyverse包

    核心软件包是ggplot2.dplyr.tidyr.readr.purrr.tibble.stringr和forcats,它们提供了建模.转换和可视化数据的功能. 其中,readr包用于读取数据,ti ...

  • 《R数据科学》--千变万化的数据只需一个readr便可

    [toc] 写在前面 数据导入是使用R语言分析数据的第一步,但是这部分的细节确实非常多,尤其是对于咱们微生物组数据来说,经常会遇到制表符和逗号作为分隔符的文件,其次,物种注释文件的七级注释往往使用分号 ...

  • 《R语言实战》- 牛国庆

    [toc] 第一章 1.3.2 R中帮助函数 R中用于管理R工作空间的函数 函数setwd()不会自动创建一个不存在的目录.如果必要的话,可以使用函数dir.create()来创建新目录,然后使用se ...

  • R语言 | 向量化操作purrr包

    Python网络爬虫与文本数据分析 在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句. 问题 比如有一个序列ns,现在想得到res,让ns中每一个数字变为平方数,代码如下 ...

  • tidyr总结篇-续

    欢迎来到医科研,这里是白介素2的读书笔记,跟我一起聊临床与科研的故事, 生物医学数据挖掘,R语言,TCGA.GEO数据挖掘. tidyr总结篇  gather(data,key="" ...

  • dplyr总结篇

    欢迎来到医科研,这里是白介素2的读书笔记,跟我一起聊临床与科研的故事, 生物医学数据挖掘,R语言,TCGA.GEO数据挖掘. dplyr-总结  有必要对dplyr进行一个总结 对行处理 数据处理对于 ...

  • R学习:R for Data Science(七)函数

    R学习往期回顾: R学习:R for Data Science(六)使用forcats处理因子 R学习 从Tidyverse学起,入门R语言 dplyr合并数据 R学习 流程控制 if,else,if ...

  • 【R分享|实战】一次有趣的尝试~函数定义与循环

    " 敢于尝试,快乐无穷."   --科白君 "R分享实战"专刊·第8篇   编辑 | 科白维尼   1000字 | 5分钟阅读 本期推送内容 一次有趣的尝试.主 ...

  • R学习:R for Data Science 循环-迭代(for while))

    R学习往期回顾: R学习:R for Data Science 向量(1) R学习:R for Data Science 向量(2) R学习 从Tidyverse学起,入门R语言 dplyr合并数据 ...

  • R学习:R for Data Science(一)

    R语言学习系列 今天我们来开始一起学习一本书:R for Data Science 数据科学是一个极其广阔的领域,仅靠一本书是不可能登堂入室的.本书的目标是教会你使用最重要的数据科学工具.在一个典型的 ...

  • R学习:R for Data Science(二)

    R语言学习系列 昨天我们开始了R for Data Science这本书的学习,今天我们来继续学习 R学习:R for Data Science(一) 分面 添加额外变量的一种方法是使用图形属性.另一 ...

  • R学习:R for Data Science(三)

    R语言学习系列 今天我们来继续学习R for Data Science R学习:R for Data Science(一) R学习:R for Data Science(二) 统计变换 接下来我们看一 ...

  • R学习:R for Data Science(四)

    前面我们学了该书得第一章节,使用ggplot2进行数据可视化,现在我们开始学习第二章节,本章节内容丰富,值得收藏! R学习:R for Data Science(一) R学习:R for Data S ...

  • R学习:R for Data Science(五)

    R学习:R for Data Science(一) R学习:R for Data Science(二) R学习:R for Data Science(三) R学习:R for Data Science ...

  • R学习:R for Data Science(六) 使用forcats处理因子

    R学习往期回顾: R学习 从Tidyverse学起,入门R语言 dplyr合并数据 R学习 流程控制 if,else,ifelse R学习 从Tidyverse学起,入门R语言(tidyr和strin ...