ITPub博客

首页 > > > 【R语言】tidyverse之零:管道操作

【R语言】tidyverse之零:管道操作

作者:浪花小雨滴 时间:2020-06-17 10:48:30 0 删除 编辑

前言

Hadley 大神的 tidyverse 包,将数据处理和建模整个流程所涉及到的:读入、清洗、重塑、汇总、可视化、探索、建模、结果展示的整个流程,都以一种“优雅”的方式整合到了一起。

我之前学了一遍 Hadley 的配套书《R for Data Science》,虽然比较系统全面,但重点部分有点过于基础,实用性欠缺了点。最近偶然看到一个非常好且精炼的进阶资料《Working in the Tidyverse》,主要以它为主,翻译并学习记录下来。

强烈建议大家,抛弃流传甚广的陈旧的数据操作方面的 R 语法,全面改用 tidyverse。

——————————————————————————————

下面先从第零篇,管道操作,开始。

一. 简介

magrittr 包引入了管道操作,能够通过管道将数据从一个函数传给另一个函数,从而用若干函数构成的管线依次变换你的数据。

先看一个例子,对数据集 warpbreaks,按分类变量 wool 和 tension 分组,对连续变量 breaks 做分组汇总,分别计算均值、中位数、标准差:

warpbreaks %>%
  group_by(wool, tension) %>%
  summarise_at(vars(breaks), list(~mean(.), ~median(.), ~sd(.)))

管道运算符%>%的意思是:将左边的运算结果,以输入的方式传给右边函数。若干个函数通过管道链接起来,叫做管线(pipeline)。

"ATMOSPHERE" %>% str_replace("SPHERE", "SQUARE") %>% str_to_lower() %>% print()

管线,也支持 Base R 函数:

month.abb %>%     # 内置月份名缩写的字符串
  sample(6) %>% 
  tolower() %>% 
  paste0(collapse = "|")

使用管道的好处是:

(1)避免使用过多的中间变量;

(2)程序可读性大大增强:

管道操作的过程,读起来就是对原数据集依次进行一系列操作的过程。而非管道操作,读起来与操作的过程是相反的,比如同样实现上例:

paste0(tolower(sample(month.abb, 6)), collapse="|")

二. 使用管道操作

  1. 管道默认将输出传给下一个函数的第1个参数
. <- c(1, 3, 4, 5, NA)
mean(., na.rm=TRUE)
c(1, 3, 4, 5, NA) %>% mean(., na.rm=TRUE)
c(1, 3, 4, 5, NA) %>% mean(na.rm = TRUE)   # "."可以省略


2. 输出可以在右边使用多次

在右边的函数调用中需要借助".":

c(1, 3, 4, 5) %>% plot(., main=paste(., collapse=", "))
# 第1个"."可以省略, 其余的"."不能省略
c(1, 3, 4, 5) %>% plot(main=paste(., collapse=", "))


3. 输出传给不是第1个参数

若函数的第1个参数不是接受数据,需要手动放置"."

# 错误做法
# iris %>% plot(Sepal.Width~Petal.Width)  # 相当于
# plot(x=iris, y=Sepal.Width~Petal.Width)
# 正确做法
iris %>% plot(Sepal.Width~Petal.Width, data = .)


4. 管道中使用函数

(1) 有时候想在管道中使用匿名函数

month.abb %>%   # 选择子集
  {.[1:3]}
# 等同于
month.abb %>%
  (function(.) {.[1:3]})

(2) 也可以将整个管线定义为一个函数,需要将"."作为管线的第1个值,将整个管线赋值给一个名字(函数名)

random_sepal_data <-    # 函数名
  . %>%                 # 用"."作为管线的开始
  select(Species, starts_with("Sepal")) %>% 
  sample_n(5) %>% 
  arrange(desc(Sepal.Length)) 

iris %>%
  random_sepal_data()

注意:管线函数总是一元的,只能接受一个参数,而且在管线中参数为一个".";若要在管线内传递多个参数,需要用通常的方式 function() 定义函数。

5. 通常操作的管道函数

你可能想要用[ 或 [[ 或 $访问"."的内容,例如选择数据框的子集,查看直方图中某个条形的值。可以用这些函数的前缀形式实现,但可读性不好:

iris %>%
  filter(Petal.Length>2, Petal.Width>2) %>%
  `[[`("Sepal.Length") %>%
  hist(main="Histogram of 'Sepal.Length' after subsetting")

magrittr 包提供了一些函数来实现这样的操作,更多函数可用 ?extract 查阅。

iris %>%
  head() %>%
  extract(c("Sepal.Length","Sepal.Width"))       # 提取列, 返回数据框
iris %>%
  head() %>%
  extract2("Sepal.Length")        # 提取1列, 返回向量

注意:不同包中同名的函数,默认是选最近加载的包中的。建议用加前缀的方式“magrittr::”为这样的函数指定包。


参考文献:

  1. Desi Quintans, Jeff Powell. Working in the Tidyverse. hiercourse.com/
  2. Garrett Grolemund, Hadley Wickham. R for Data Science. r4ds.had.co.nz/

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3120509/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 初识SQL Server 2017
请登录后发表评论 登录
全部评论

注册时间:2018-05-16

  • 博文量
    4259
  • 访问量
    39804