作者:黄天元,复旦大学博士在读,目前研究涉及文本挖掘、社交网络分析和机器学习等。希望与大家分享学习经验,推广并加深R语言在业界的应用。
邮箱:huang.tian-yuan@qq.com
前言
上篇介绍了什么是ETL,什么是SQL,为什么用R做ETL。本篇讲一下R语言的基础设置。
1.安装R
如果你的计算机还没有安装R语言的话,需要先安装R语言,官网网址为:https://www.r-project.org/
尽管裸R也是非常好用的,如果新手上路的话,一个全裸的R软件加一个记事本,就可以满足你很多的需求。不过如果你经常需要做一些数据项目的话,为了便于管理,推荐大家使用Rstudio
它是一个非常优秀的集成开发环境(IDE, Integrated Development Environment),官网是:https://www.rstudio.com/
网上有很多安装教程,这里不用图文赘述了,但是安装R是学习本系列内容的最低要求。
2.安装package
R语言之强大,就在于它可以安装加载不同的包(package)。很多前沿的科研工作者会把他们最新的工具写成包上传到github或者CRAN上,这样所有R的用户都可以下载使用。本系列要用到的包很少,只要把下面的代码运行一遍,往后都不需要再考虑安装包的事情了:
install.packages("pacman") library(pacman) p_load(tidyverse,nycflights13)
pacman是一个管理R包的工具,加载之后,采用p_load函数对包进行安装和加载。
一般情况下,包需要先用install.packages来安装,然后用library来加载到R的环境中。上面我们对pacman包就是这样处理的。有了pacman之后,我们再要安装加载其他的包,就可以直接用p_load函数,我们注意到install.package里面的包名称需要用双引号括起来,在p_load中就不需要,省了很多事情。p_load会判断环境中是否有这个包,如果没有,先安装再加载;如果有,那么直接加载。p_load就是把install.package和library集成在一起的方便工具。
3.规约说明
如果没有特殊声明,这里的代码块都是R代码,而部分R代码提供对应的SQL代码,SQL代码前都会用提前声明。本系列只需要tidyverse和nycflights13两个包,初次安装tidyverse可能需要较长时间,请耐心等待。代码上一节已经给出,在最开始运行一次即可,不需要每次运行。
本系列所有章节都具有独立性,既可以从头开始阅读,也可以分开浏览。它既是一本快速入门的教程,又是数据科学日常的工具字典,目录即包含索引功能。
4.会SQL还要学R吗?
如果你还没有用过SQL或者很少用,可以以后再了解本节的内容。但是我们的结论很简单,就是,如果你工作中还是需要大量用SQL的话,R依旧是你强大的伴侣。这里要传授给大家一个小小的秘笈,就是如何利用R的工具,从而高效把dplyr包的一些操作翻译成SQL。R做ETL有多么简单,如果大家稍微看一下后面的章节,就会知道。如果你在日常的SQL操作中,对层层嵌套的操作搞得头昏脑胀,那么可以尝试先写R代码,然后把R代码翻译成SQL,再在SQL的集成环境中进行数据查询。具体方法如下:
•1.把SQL中需要的数据取一个小的子集,导入R
•2.把子集放入虚拟的R数据库中,然后用dplyr写相应的代码
•3.利用sql_render函数或explain函数,把R代码转化为SQL代码
•4.参考这个SQL代码,在数据库中进行实际操作
下面我就具体用代码演示一下,供大家参考。
1.环境准备
这个方法需要用到DBI,dbplyr和RSQLite包,我们先安装并加载。另外,我们要用到nycflights13的数据,也要一并加载进来,此外还需要用到我们主要介绍的tidyverse包。
pacman::p_load(DBI,dbplyr,nycflights13,tidyverse,RSQLite)
2.创建虚拟数据库
下面我们要创建一个名为con的虚拟数据库。
con <- dbConnect(RSQLite::SQLite(), ":memory:")3.把数据对象导入虚拟数据库
这个步骤中,我们把flights数据库导入到con数据库中。注意,我只导入了第一行,因为我们完全没必要把所有内容都导入进去,我们需要的只是翻译功能,不是直接求具体的结果。
copy_to(con,flights[1,]) -> fl_tbl
现在con数据库中,已经有了我们的数据,我们可以查看一下:
dbListTables(con) ## [1] "flights[1, ]" "sqlite_stat1" "sqlite_stat4"
上面名为flights[1,]的就是我们导入的数据,我们可以通过对fl_tbl进行操作,从而对这个对象进行数据库的基本操作。
4.按照需求写R的查询代码,并转为SQL
我会用一个非常复杂的代码告诉大家,R语言做数据操纵是多么强大:
fl_tbl %>% group_by(tailnum) %>% #根据tailnum分组 summarise( delay = mean(arr_delay), #汇总arr_delay的平均值 n = n() #求每个组里面一共有多少条记录 ) %>% arrange(desc(delay)) %>% #在组内进行排序 filter(n > 100) %>% #筛选出分组中记录大于100的结果 sql_render() #把上面写的所有代码转化为SQL代码 ## Warning: Missing values are always removed in SQL. ## Use `AVG(x, na.rm = TRUE)` to silence this warning ## <SQL> SELECT * ## FROM (SELECT * ## FROM (SELECT `tailnum`, AVG(`arr_delay`) AS `delay`, COUNT() AS `n` ## FROM `flights[1, ]` ## GROUP BY `tailnum`) ## ORDER BY `delay` DESC) ## WHERE (`n` > 100.0)
我们已经看到,我们用R写出来的代码,最后能够转化为非常复杂的SQL代码。这些代码在R里面是层层递进,简洁高效的,但是如果要写成SQL,可能会包含多重嵌套。我认为SQL其实需要一个更加简洁的语法结构,但是dplyr包目前已经完成了这一步,给大家带来极大的便利。
5.有始有终,关闭连接
如果后面不再使用虚拟数据库了,可以把连接关掉。
dbDisconnect(con)
5.编程风格
每个程序员都会有自己的编程风格,尽管有很多协定想要统一程序员的编码风格,但是完全统一是不可能也没必要的。但是我们需要保证代码具有很高的可读性,因此虽然不指定一定要有某个风格,但是每个人应该有自己的风格,也就是遇到相同的情况应该用统一的方式解决问题,这里提一下本系列的编程风格。
我的编程风格很大程度师法tidy门派,因此依赖于管道操作符“%>%”。这个符号的意思极其简单,就是把符号左边的部分作为第一个参数传递到符号右边的函数中。也就是说,f(x)如果让我来表达,就是x %>% f();如果是f(x,y,z),我就会表达为:x %>% f(y,z);如果是g(f(x)),我的表达为x %>% f() %>% g().
这样做的好处是,不需要每一步都进行赋值,这节省了存储空间;语法结构清晰,一步完成一个操作,层层递进;从左到右,符合人类思考习惯,因此我经常会用“->”进行赋值操作,可以形象想象为一个箭头,把左边的东西赋值给右边。我认为这种编程风格有利于简化我们的代码,因此本系列基本用了这种风格。
6.小结
本章讲了R语言的基本环境设置,你可以在官网中下载R软件,如果感兴趣,可以使用Rstudio作为集成开发环境。我们讲了本系列的基本规约,并引导大家安装需要的安装包,并加载这些包。最后,我们还演示了如何利用R的一些工具,把R的ETL工程代码转化为传统的SQL代码。