第1章 R语言数据可视化简介
本章主要介绍R语言数据可视化的一些基本内容,包括什么是R、什么是Rstudio、什么是R包等,另外还会介绍R语言基本语法的相关内容。由于本书的**在于数据可视化,因此不会深入讲解R语言的语法。本章旨在帮助读者了解R语言的一些核心内容,以尽可能简单的方式帮助读者了解如何使用R语言,*后介绍一些常见的统计图形。
1.1 R语言介绍
R是一种编程语言和自由软件,常用于统计计算和图形绘制。R语言广泛应用于统计学领域和数据科学领域,用于开发统计软件和进行数据分析。R是世界上*强大的统计计算、机器学习和图形编程语言,拥有蓬勃发展的全球用户、开发人员和贡献者社区。
R语言是罗斯•伊哈卡(Ross Ihaka)和罗伯特•杰特曼(Robert Gentleman)在新西兰的奥克兰大学所创建的,以两个作者名字的**个字母命名。R项目于1992年构思,1995年发布初始版本,2000年发布稳定版本。R可从CRAN网页进行下载,链接为http:// cran.r-project.org/。
R及其库实现了各种统计和图形方法,包括线性和非线性建模、经典统计测试、时间序列分析、分类、聚类等。一般而言,*新的统计方法都有对应的R包,R用户可以非常方便地学习、应用*新的统计方法。
R可以通过函数和扩展包轻松扩展其功能,R社区因在软件包方面的积极贡献而闻名。任何人都可以在R社区贡献出自己的包。到目前为止,R中有超过10 000个包可供下载。R开发人员社区非常活跃。R在统计计算、数据科学及数据可视化方面有着****的优势,几乎你面临的所有问题或者你关心的问题都有人实现了R包。
R是数据科学领域*流行的语言,并且R语言是完全面向数据的,更加注重从数据的角度去思考问题,在这一点上与其他的编程语言有很大的区别。
另外,R是用于统计研究的主要工具。因此当新的方法被开发的时候,它不仅仅被作为论文发表,而且往往会被开发成为一个R包。这让R永远成为新算法的前沿,而R用户可以非常方便地使用这些新的算法。
CRAN本身是一个非常有效的共享R扩展平台,具有用于包创作、构建、测试和分发的成熟系统。R核心团队,特别是CRAN维护者,为R包创建了这样一个充满活力的生态系统。图1.1所示为R包数量在不同年份的变化。
图1.1 R包数量的变化
从图1.1中可以看到,R包的开发速度越来越快。但是过多的包导致人们在寻找自己所需要的包时困难重重,可能需要借助一些搜索工具来完成。目前有很多包的搜索与汇总工具,例如:
? CRAN提供包任务视图(https://cran.r-project.org/web/views/),按主题区域(例如财务或临床试验)提供包目录。
? MRAN(Microsoft R应用程序网络)为CRAN上的R软件包提供搜索工具。MRAN的链接为https://mran.microsoft.com/taskview。
? 为了找到*受欢迎的软件包,Rdocumentation.org按下载次数提供了软件包的排行榜,并提供了新发布和*近更新的包的列表。RDocumentation.org(https://www. rdocumentation.org/taskviews#Bayesian)还提供了基于CRAN任务视图的可搜索版本。
通过上面的几个方法可以很方便地找到自己所需要的包。
R有许多标准函数,使用这些函数可以解决非常多的统计机器学习的任务。对于计算密集型任务,可以在运行时连接和调用C、C 和Fortran代码。**用户可以编写C、C 、Java、.NET或Python代码直接操作R对象,还可以通过使用用户提交的包来执行特定功能或特定研究领域的任务。软件包使R具有高度可扩展性。
R的语法非常简单,介绍R的语法首先需要从数据的角度入手,在使用任何编程语言进行编程时,需要使用各种变量来存储各种信息。与其他编程语言(如C和Java)不同,在R中使用变量不需要声明类型,并且R中的数据由R语言的对象存储。这些对象包括向量、列表、矩阵、数组、因子、数据框。
数据是数据科学的基础,也是数据可视化的基础。下面开始介绍R的基本数据结构。
1.1.1 向量
这里所说的向量并不是物理学中有方向的一个量,而是一组数据。例如,1~10,这10个数字就可以表示为一个向量。或者26个字母,也可以表示为一个向量。向量是R中的一个基本数据结构。当你想用多个元素创建向量时,应该使用c函数,这意味着将元素组合成一个向量。下面的代码则是创建向量的一个例子。 # 创建一个向量
letter <- c('a','b',"c")
letter
## [1] "a" "b" "c"
# 查看数据类型
class(letter)
## [1] "character" 上面的代码使用c函数创建了一个向量,包含3个元素,分别为a、b、c这3个字母。然后class函数可以用于查看数据的类型。从代码的输出结果中可以看出,这个向量中元素的数据类型是字符类型(character)。上面创建的向量有3个元素,如果希望提取向量中的某个元素,则可以通过[]进行提取,代码如下: letter[1]
## a 上面的代码选取了向量中的**个元素,希望提取第几个元素只需要传入对应数字即可。
1.1.2 列表
列表(list)这个数据类型常用于存储不同数据类型的数据。列表里面可以存储向量、列表、矩阵、数组、因子、数据框等所有数据类型。另外,列表还可以嵌套多层列表,下面的代码创建了一个列表,列表中分别包含了向量、列表、数组、矩阵、数据框这几种R语言中的数据结构。 l <- list(c(1,2,3),list(1),array(c(1,2,3,3,1,2),dim = c(1,2,3)),matrix
(c(1,2,3,4),nrow = 2),factor(c(1,2,3)),data.frame(nu = c(1:3),id =c("a",
"b","c")))
l
## [[1]]
## [1] 1 2 3
##
## [[2]]
## [[2]][[1]]
## [1] 1
##
##
## [[3]]
## , , 1
##
## [,1] [,2]
## [1,] 1 2
##
## , , 2
##
## [,1] [,2]
## [1,] 3 3
##
## , , 3
##
## [,1] [,2]
## [1,] 1 2
##
##
## [[4]]
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
##
## [[5]]
## [1] 1 2 3
## Levels: 1 2 3
##
## [[6]]
## nu id
## 1 1 a
## 2 2 b
## 3 3 c
class(l)
## [1] "list" 上面的代码创建了6种类型的数据,然后将它们全部放到一个list里面。如果希望提取列表中的元素,则需要使用[[]]这个符号。l[[1]]表示提取列表的**个元素,也就是整个向量。如果希望进一步提取向量中的元素,提取方式与普通向量的提取方式相同。例如,代码l[[1]][1]提取了列表中向量的**个元素。
1.1.3 矩阵
矩阵可以理解为二维数组,它可以使用矩阵函数(matrix)来创建。执行下面的代码,将创建一个矩阵。 # Create a matrix.
M = matrix( c('a','a','b','c','b','a'), nrow = 2, ncol = 3, byrow = TRUE)
print(M)
## [,1] [,2] [,3]
## [1,] "a" "a" "b"
## [2,] "c" "b" "a"
上面的代码创建了一个矩阵,创建矩阵的时候需要指定几个参数,nrow表示这个矩阵有多少行,ncol用于表示这个矩阵有多少列。这两个参数*少只需要设置一个。byrow=TRUE表示将向量通过行的方式排列成矩阵。拿上面的例子来说,c的位置为(2,1),如果设置的是byrow=F,则c的位置是(2,2)。对于矩阵,数据框的元素提取同样使用的是[]。例如上面所创建的例子,想要提取矩阵中的**个元素,代码则是M[1,1],提取数据框的元素原理相同。
1.1.4 数组
虽然矩阵被限制为二维,但数组可以具有任何数量的维度。创建数组所使用的函数是array,数组函数使用dim属性指定数组的维度。在下面的例子中,我们创建了一个三维数组。该数组包含两个元素,每个元素为3×3的矩阵。 # 创建一个数组
a <- array(c('green','yellow'),dim = c(3,3,2))
print(a)
## , , 1
##
## [,1] [,2] [,3]
## [1,] "green" "yellow" "green"
## [2,] "yellow" "green" "yellow"
## [3,] "green" "yellow" "green"
##
## , , 2
##
## [,1] [,2] [,3]
## [1,] "yellow" "green" "yellow"
## [2,] "green" "yellow" "green"
## [3,] "yellow" "green" "yellow" 上面的代码创建了一个3×3×2的数组,dim参数表示有两个3×3的矩阵。通过指定dim参数,可以创建任意维度的数组。
1.1.5 因子
因子是使用向量创建的R对象,它将向量中元素的不同值一起存储为标签,不管原始向量中的元素是什么类型的。例如数值类型,如果被设定成为因子,元素都会变成类似于字符类型的分类变量。因子类别的数据与字符类别的数据差别在于,因子类型的数据是有顺序的。例如,男和女是性别这个变量的两个值,二者之间没有大小关系;春、夏、秋、冬是季节的4个值,但是这4个值是有先后顺序的(即春、夏、秋、冬)。所以,性别变量可以直接使用字符类型进行存储,季节则可以使用因子类型进行存储。
因子在统计建模中非常有用。在R中使用factor函数创建因子,函数中的levels参数用于指定因子中分类变量的顺序,因子常常用于创建有顺序的分类变量。下面的代码创建了一个因子类型的数据。 # 创建一个颜色向量
apple_colors <- c('green','green','yellow','red','red','red','green') # 创建一个因子向量
factor_apple <- factor(apple_colors) # 输出结果
print(factor_apple)
## [1] green green yellow red red red green
## Levels: green red yellow
print(nlevels(factor_apple))
## [1] 3 上面的代码创建了由3个因子水平(level)组成的因子向量,分别表示为green、red、yellow。一般而言,字符数据不能进行比较。但是如果设置成因子,则表示字符是有顺序的。在这个例子中,yellow>red>green,因子可以通过判断语句进行判断。
1.1.6 数据框
数据框是表格数据对象,使用数据框可以非常方便地描绘现实世界。数据框与矩阵非常类似。但是数据框与矩阵不同的是,数据框每列可以包含不同的数据模式。**列可以是数字,第二列可以是字符,第三列可以是逻辑型的数据。它是等长度向量的组合,在R中使用data.frame函数来创建数据框。下面的代码使用data.frame函数创建了一个数据框,用来记录不同人的身高、体重等数据。 # 创建一个数据框
BMI <- data.frame(
gender = c("Male", "Male","Female"),
height = c(152, 171.5, 165),
weight = c(81,93, 78),
Age = c(42,38,26)
)
print(BMI)
## gender height weight Age
## 1 Male 152.0 81 42
## 2 Male 171.5 93 38
## 3 Female 165.0 78 26 上面的代码创建了一个数据框。数据框是数据科学中*常用的数据结构,它的数据结构非常符合人们对于现实世界的认识,是对现实世界的一个很好的映射。上面创建的数据框记录了不同人的性别、身高、体重、年龄。
用数据框的思维可以很好地将现实世界映射成为数据框。例如,想了解什么因素会影响学生成绩,比如父母的学历、平均学习时长、健康状况等,将这些数据收集起来成为一个数据框,就是一份整洁、可以用于分析的数据。
在数据科学中有一个概念是整洁数据(tidy data)。整洁数据格式有下面3个定义:
? 每一个变量都是一列(Each variable forms a column)。
? 每一个观测都是一行(Each observation forms a row)。
? 每一种类型的观察值一起构成一个表格(Each type of observational unit forms a table)。
数据框通常是整洁数据的一种表现形式。因此,数据框同样也是*常用的数据格式。
在介绍完R中的数据类型之后,需要简单介绍R的一些控制流。
1.1.7 for循环
for循环是一种程序控制结构,用于实现执行特定次数的循环。在R中创建一个for循环语句的基本格式如下: for (test_expression) {
statement
} R的for循环特别灵活,因为它的循环变量不限于整数,实际上任何向量都可以通过for循环进行遍历。我们可以传递字符向量、逻辑向量、列表或表达式。下面的代码创建了一个for循环,循环遍历一个由字符组成的向量,每遍历一个向量,都会通过print函数输出遍历的结果: # for 循环
v <- LETTERS[1:4]
for ( i in v) {
print(i)
}
## [1] "A"
## [1] "B"
## [1] "C"
## [1] "D" 上面的代码创建了一个循环,i in v表示使用i这个变量对v的所有元素进行遍历。需要注意的是,使用for循环的效率比较低,因此往往采用其他的替代方式,如使用apply函数族。例如,上面的代码可以改为: # apply 函数
a <- data.frame(v)
apply(a,1,print)
## v
## "A"
## v
## "B"
## v
## "C"
## v
## "D"
## [1] "A" "B" "C" "D" 上面的代码使用了apply函数来实现循环。apply函数的效率比for循环高很多。因此,在需要使用for循环来解决问题的时候,*好的选择是使用apply函数。另外,apply函数属于一个函数族,还包括lappy、sapply等其他函数,用于处理需要遍历一个向量或者列表的情况。
1.1.8 条件判断
条件判断是代码中非常重要的程序流程控制方法。在R中创建if…else语句的基本语法如下: if(boolean_expression) {
## statement(s) will execute if the boolean expression is true.
} else {
## statement(s) will execute if the boolean expression is false.
} 如果布尔表达式的计算结果为真,则将执行if代码块,否则将执行else代码块。 # 条件判断
x <- c("what","is","truth") if("Truth" %in% x) {
print("Truth is found")
} else {
print("Truth is not found")
}
## [1] "Truth is not found" 上面的代码用于判断一个字符串是否在一个向量中,这里用到了%in%这个符号,用于判断某一个元素是否在一个集合之中。这里的Truth和truth是两个不同的字符串,所以返回Truth is not found。
if语句后面可以跟一个可选的else if…else语句。使用if…else if…else语句时,有几点要注意。
? else语句一定要在if语句之后。
? 一个if语句可以有多个else if语句。
? if…else if…else语句中,一旦某一个分支的判断为真,则不会继续运行其他分支的语句。
在R中创建if…else if…else语句的基本语法格式如下: if(boolean_expression 1) {
## Executes when the boolean expression 1 is true.
} else if( boolean_expression 2) {
## Executes when the boolean expression 2 is true.
} else if( boolean_expression 3) {
## Executes when the boolean expression 3 is true.
} else {
## executes when none of the above condition is true.
}
需要注意的是,关于条件判断有一个比较特殊的格式,就是ifelse(条件判断,语句1,语句2),这是if…else语句的一个简写。在ifelse函数中,**个参数是逻辑表达式,如果逻辑表达式为真,则运行语句1,否则运行语句2。
下面的代码是关于ifelse函数的一个简单的例子。 a <- c(seq(1,10))
a
[1] 1 2 3 4 5 6 7 8 9 10
ifelse(a>mean(a),1,0)
[1] 0 0 0 0 0 1 1 1 1 1 上面的代码首先创建了一个向量,然后使用ifelse函数进行判断,如果向量a的元素值大于向量a的平均值,则返回1,否则返回0。
1.1.9 函数
R语言中构建函数的方法是使用function函数,其函数格式如下: function_name <- function(arg_1, arg_2, ...) {
Function body
} 关于函数可以讨论的内容其实有很多。函数主要由以下4部分组成。
? 函数名:函数的实际名称。
? 参数:当调用一个函数时,可以将一个值传递给参数。参数是可选的,换句话说,函数可以没有参数。参数也可以有默认值。
? 函数体:函数所执行的语句包含在函数体内。
? 返回值:函数运行完成时返回的结果。
R语言有许多内置函数,可以在程序中直接调用,而无须先定义它们,如mean、sum等函数。我们还可以创建和使用自���的函数,这类函数称为用户定义函数。下面的代码创建了一个简单的函数。 # 函数
frist <- function(){
return(1 1)
} frist()
## [1] 2 上面的代码构建了一个简单的函数,每次调用函数都会计算1 1的结果。在这个函数中,并没有使用任何参数。下面的代码用于构建一个稍微复杂的函数。 Fibonacci <- function(n)
{
if(n == 1|n == 2)
{
return(1)
}
else
{
return(Fibonacci(n-1) Fibonacci(n - 2))
}
}
Fibonacci(11)
## [1] 89 上面的代码使用递归的方式编写了计算斐波那契数列的函数。这个函数有一个参数n,并且使用了递归的函数思想。
*后,介绍一个比较有用的参数“…”,如果有很多未知的参数会输入,则会使用“…”这个参数。其实,R的很多基础函数都会用到这个参数。例如,R中基础的绘图函数plot。 plot
## function (x, y, ...)
## UseMethod("plot")
## <bytecode: 0x7ffd75a5e828>
## <environment: namespace:graphics> 上面的代码显示了plot函数的代码,可以看到,plot函数包含了“…”这个参数。下面的代码显示了一个简单的例子。 f <- function(...){sum(...)}
f(x = 1,y = 3,z =3)
## [1] 7 上面的代码在函数中只设置了“…”参数,于是在函数调用的时候,所有的参数都会被传递到sum函数中。
R的另一个优势是绘制静态图形,它可以生成包含数学符号的出版品质的图形。通过其他软件包还可以构建动态和交互式图形。R的基础绘图函数是plot函数,使用plot函数就可以快速绘制大多数的统计图形。下面的代码使用plot函数绘制了一幅散点图,如图1.2所示。 # 使用基础绘图系统绘图
plot(rnorm(100),rnorm(100),xlab = "a",ylab = "b")
图1.2 使用plot函数绘制散点图
上面的代码绘制了两个正态分布变量的散点图。使用plot函数可以非常快速地绘制。但是随着R的不断发展,出现了更多的绘图工具。例如ggplot、ggvis,这些工具可以绘制更加美观的图形。下面的代码使用ggplot2包绘制了一幅散点图,如图1.3所示。 # 使用ggplot2 绘图
require(ggplot2)
## Loading required package: ggplot2
qplot(rnorm(100),rnorm(100),geom = "point") xlab("a") ylab("b")
图1.3 使用ggplot2包绘制散点图
上面的代码使用了ggplot2包绘制了两个正太分布数据的散点图。下面的代码使用ggvis包绘制了一幅同样的散点图,如图1.4所示。 # 使用ggvis绘图
library(ggvis)
##
## Attaching package: 'ggvis'
## The following object is masked from 'package:ggplot2':
##
## resolution
ggvis(data = data.frame(a = rnorm(100),b = rnorm(100)),x = ~ a,y = ~b)
%>%layer_points() 上面使用ggvis包绘制了两个正太分布数据的散点图。需要注意的是,ggvis比ggplot2速度快得多,尤其是在更改数据时。每个ggplot2图都有一秒钟或几秒钟的延迟。使用ggvis绘图比较简单。但是,目前而言,ggplot2是使用*为广泛的绘图包,并且有非常多的扩展包。本书也主要使用ggplot2进行绘图。
图1.4 使用ggvis包绘制散点图
1.2 Rstudio介绍
Rstudio是为R语言设计的一种跨平台集成开发环境。通过Rstudio可以更加方便地使用R进行编程。当然,R的集成开发环境很多,包括下面几种。
? Emacs ESS:ESS是Emacs文本编辑器的一个统计分析插件,其官网地址是http://ess.r-project.org/。
? Sublime Text R-Box:一个在Sublime中使用R语言编程的插件。
? StatET:一个基于Eclipse的R语言IDE,其官网地址是http://www.walware.de/goto/ statet。
? R Commander:一个包括基本图形用户界面的R包,其官网地址为http://socserv. mcmaster.ca/jfox/Misc/Rcmdr/。
? IRkernel:Jupyter的R语言内核,其官网地址为https://github.com/IRkernel/IRkernel7。
? Radiant:一个使用R语言并基于浏览器接口的独立业务分析平台,基于Shiny,其官网地址为http://vnijs.github.io/radiant/。
? RTVS:Visual Studio中的R开发工具,其官网地址为http://microsoft.github.io/RTVS- docs/。
以上集成开发环境都可以用于R的使用与开发,任意一个工具都可以很好地使用。目前,Rstudio是应用*广泛的集成开发环境。
当下载好R之后,可以下载Rstudio。Rstudio的下载链接为http://www.rstudio.com/ products/RStudio/。
Rstudio的使用这里不做过多介绍。如果想详细了解Rstudio的使用,包括快捷键、详细设置,可以进入Rstudio的官网查看。另外,需要注意的是,在Rstudio的官网上可以找都很多关于R的备忘录。这些备忘录总结了关于R的各种内容,如图1.5所示。
图1.5 Rstudio备忘录
图1.5显示了Rstudio备忘录,查看这个备忘录可以了解关于Rstudio使用的精简介绍。
1.3 R包介绍
R包是R的一个资源库。R语言的特性之一是非常开放。R语言通过R包来扩展自己的功能。目前来看,R中有超过10 000个包可以使用,这些包用于解决数据访问、统计、可视化、机器学习、自然语言等各个方面的问题。这些包的***都是活跃在统计、数据处理和机器学习前沿的**学者或者教授。
现在R包的开发依然处于一个非常活跃的时期,R包的数量依然在不断地增加。下载R包一般有两个途径:CRAN和GitHub。*初只能从CRAN中下载,如果***开发了一个包,想要上传到CRAN上是比较烦琐的。CRAN有非常多的要求与审核,这样做的好处是保证了上传包的质量。想要从CRAN上下载包,使用的函数是install.packages。假设要下载ggplot2这个包,那么代码如下: # 下载包
install.packages("ggplot2") 上面的代码会将对应的包下载下来。后来,随着R的不断发展,为了更加方便***贡献自己的力量,出现了更多关于R包的下载方式。有些包***一开始会将自己的包上传到GitHub上,然后再慢慢地调整,上传到CRAN上。也就是说,有些包只有GitHub上有,如果想要下载GitHub上面的包,则需要使用install_github这个函数。这个函数来自于devtools包,这个包提供了很多与开发相关的工具。ggplot2同样上传到了GitHub上,因此从GitHub上下载ggplot2的代码如下: # 从GitHub下载包
devtools::install_github("tidyverse/ggplot2") 上面的代码用于从GitHub上下载包。其中,tidyverse表示GitHub中的用户名,ggplot2表示对应的项目名称。
下载好之后,想要调用所下载的包一般而言有两种方式:一种是使用library函数,另外一种是使用require函数。这两种加载包的方式有一些区别。使用library函数会加载所有的包,如果重复地使用这个函数,则会重复加载。我们在写代码的时候并不知道某一个包是否已经下载。如果一个包没有被下载,则使用library函数加载这个包的时候,R语言会报错,代码会中断。如果不希望代码中断,则可以使用require函数。使用require函数加载包,还会返回一个布尔值,TRUE或者FALSE。如果这个包没有下载,代码不会报错,并且require函数会返回FALSE。也就是说,可以使用这个函数判断一个包是否已经下载。
关于使用包的基本内容,以上的介绍已经足够了。本书的主要内容是介绍数据探索与可视化,不会过多涉及这些内容。但是,任何一个R使用者都有必要了解R包开发的相关知识。因此,在这里**一本R语言包开发的相关书籍,如果读者有兴趣或者需要了解R语言包开发的相关内容,可以参考R Packages这本书,电子书的链接为https://r-pkgs.org/。
1.4 R语言数据读取
数据读取是进行数据探索与数据可视化*基本的一个步骤。我们需要将各种各样数据源的数据加载到R环境中进行处理、分析和建模。数据源可能是R自带的数据格式RData,也有可能是csv文件和xlsx文件,或者是SPSS和SAS文件。有时候需要从关系数据库中获取数据,这时需要使用R操作关系数据库。本节会探讨各种读取数据的方法,并进行总结,帮助我们灵活地导入或导出数据。
RData是R中的文件对象,可以储存R中的各种数据结构,包括向量、数据框、列表等。在R中生成的各种结果都是R对象,都可以通过RData文件进行储存,储存的方法是使用save函数。如果需要加载RData数据,则可以使用load函数进行操作。
R发展到今天,得益于很多贡献者发挥了他们的才智,为R用户开发了很多**工具,极大地提高了R用户的工作效率。其中与数据输入、输出相关的包是readr包。这个包是哈德利•韦翰(Hadley Wickham)等人开发的,提供了以快速、友好的方式读取矩阵数据,也就是读取csv和tsv等数据格式的数据。
readr包中的主要函数如下:
? read_csv函数:读取以逗号为分隔符的文件,如csv文件和tsv文件。
? read_csv2函数:读取以分号为分隔符的csv文件。
? read_delim:与read_csv类似,可以读取以任意符号为分隔符的文件,通过delim参数指定分隔符号。
? read_tsv函数:读取以制表符为分隔符的文件。
? read_table函数:读取以空格为分隔符的文件。
上面就是readr包中主要的读取数据的函数。其中需要注意的是,只有read_delim 需要指定分隔符来读取对应分隔符的数据,其他函数只能读取指定分隔符的数据。总体来说,这些函数有相似的使用方式,也有一些共同的参数,具本如下:
? col_names:这个参数的值可以是FALSE、TRUE或者一个字符向量,默认是TRUE。当参数设置为TRUE的时候,表示读取**行为列名,如果是字符向量,那么会将字符向量作为数据集的列名。
? skip:一个数值,表示读取数据的时候,跳过前多少条数据。
? n_max:一个数值,表示*多读取多少条数据,这个参数在只需要读取一部分数据的时候才可以使用。
以上是readr包中函数*常用的一些参数。关于readr包的优点*重要的一点是,readr读取数据的速度比R自带的读取数据的函数要快很多。R自带的读取数据的函数如下:
? read.csv:读取以逗号为分隔符的数据。
? read.table:读取以空格为分隔符的数据。
? read.delim:读取以换行符为分隔符的数据。
1.4.1 读取Excel数据
读取Excel数据可以使用readxl这个包,它的作者也是哈德利•韦翰等人,它提供了一个**读取Excel数据的方式。readxl包中的主要函数有read_excel、read_xls、read_xlsx。
read_excel函数会自动判断文件的后缀是xls还是xlsx。如果明确知道文件的后缀是xls或xlsx,那么直接使用xls或者xlsx会更合适。读取Excel数据的函数*重要的几个参数如下:
? path:数据文件的路径。
? sheet:用于指定读取Excel的哪一个sheet。
下面的代码是使用read_excel函数读取Excel数据的例子。
# 读取Excel数据
library(readxl)
datasets <- readxl_example("datasets.xlsx")
read_excel(datasets)
## # A tibble: 150 x 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <chr>
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 5 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## # … with 140 more rows
read_excel(datasets,2)
## # A tibble: 32 x 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
## 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
## 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
## 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
## 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
## 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
## 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
## # … with 22 more rows 上面的代码中,readxl_example("datasets.xlsx")会返回一个示例的Excel数据集的路径。read_excel(datasets)函数读取的是datasets这个Excel中**个sheet的数据,read_excel (datasets,2)读取的是datasets这个Exccel中第二个sheet的数据。另外需要注意的是,如果Execl中的sheet有命名,也可以通过sheet的名字来指定,例如下面的代码: # 读取Excel数据
read_excel(datasets,sheet = "chickwts")
## # A tibble: 71 x 2
## weight feed
## <dbl> <chr>
## 1 179 horsebean
## 2 160 horsebean
## 3 136 horsebean
## 4 227 horsebean
## 5 217 horsebean
## 6 168 horsebean
## 7 108 horsebean
## 8 124 horsebean
## 9 143 horsebean
## 10 140 horsebean
## # … with 61 more rows 上面的代码中,sheet="chickwts"表示读取sheet为chickwts的数据。通过这种方式可以非常方便地获取Excel数据。接下来介绍获取其他来源的数据集。
1.4.2 读取SPSS、SAS和STATA数据
在做统计分析的时候,通常还会涉及其他统计软件,比如SAS和SPSS。不同的软件储存数据的格式会不一样,这时需要一个工具对不同格式的数据进行操作。在R语言中,可以使用haven包。这个包用来读取其他统计软件的数据,比如SAS的sas7bdat格式数据,或者SPSS的sav格式数据。
(1)读取SAS数据read_sas,示例代码如下: # 读取SAS数据
library(haven)
path <- system.file("examples", "iris.sas7bdat", package = "haven")
path
## [1] "/Library/Frameworks/R.framework/Versions/3.5/Resources/library/
haven/examples/iris.sas7bdat"
read_sas(path)
## # A tibble: 150 x 5
## Sepal_Length Sepal_Width Petal_Length Petal_Width Species
## <dbl> <dbl> <dbl> <dbl> <chr>
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 5 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## # … with 140 more rows (2)读取SPSS数据read_sav,示例代码如下: # 读取SPSS 数据
path <- system.file("examples", "iris.sav", package = "haven")
path
## [1] "/Library/Frameworks/R.framework/Versions/3.5/Resources/library/
haven/examples/iris.sav"
read_sav(path)
## # A tibble: 150 x 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <dbl lbl>
## 1 5.1 3.5 1.4 0.2 1 [setosa]
## 2 4.9 3 1.4 0.2 1 [setosa]
## 3 4.7 3.2 1.3 0.2 1 [setosa]
## 4 4.6 3.1 1.5 0.2 1 [setosa]
## 5 5 3.6 1.4 0.2 1 [setosa]
## 6 5.4 3.9 1.7 0.4 1 [setosa]
## 7 4.6 3.4 1.4 0.3 1 [setosa]
## 8 5 3.4 1.5 0.2 1 [setosa]
## 9 4.4 2.9 1.4 0.2 1 [setosa]
## 10 4.9 3.1 1.5 0.1 1 [setosa]
## # … with 140 more rows (3)读取STATA数据read_dta,示例代码如下: # 读取STATA数据
path <- system.file("examples", "iris.dta", package = "haven")
path
## [1] "/Library/Frameworks/R.framework/Versions/3.5/Resources/library/
haven/examples/iris.dta"
read_dta(path)
## # A tibble: 150 x 5
## sepallength sepalwidth petallength petalwidth species
## <dbl> <dbl> <dbl> <dbl> <chr>
## 1 5.10 3.5 1.40 0.200 setosa
## 2 4.90 3 1.40 0.200 setosa
## 3 4.70 3.20 1.30 0.200 setosa
## 4 4.60 3.10 1.5 0.200 setosa
## 5 5 3.60 1.40 0.200 setosa
## 6 5.40 3.90 1.70 0.400 setosa
## 7 4.60 3.40 1.40 0.300 setosa
## 8 5 3.40 1.5 0.200 setosa
## 9 4.40 2.90 1.40 0.200 setosa
## 10 4.90 3.10 1.5 0.100 setosa
## # … with 140 more rows 通过上面的几种方式,可以快速获取SAS和SPSS等来源的数据。
1.5 ggplot2介绍
ggplot2是一个强大而灵活的R包,由哈德利•韦翰实现,用于生成优雅的图形。ggplot2包中的gg是指图形语法,它是一个使用“语法”来描述绘图的图形概念。
根据ggplot2的概念,一个统计图形可以被划分为3个部分:Plot(图形)= Data(数据) Aesthetics(图形美学) Geometry(几何变换)。
? 数据:使用ggplot2进行绘图,数据集的格式一般是数据框的格式。
? 图形美学:指定x和y变量,同时用来指定图形的颜色、大小、形状等。
? 几何变换:用于指定绘制何种统计图形,例如,条形图、点图或者其他图形。
ggplot2提出关于统计图形的图形语法,而数据、图形美学、几何变换则是绘制统计图形的几个关键要素。ggplot2包含两个关键的函数:
? qplot:用于快速绘制统计图形;
? ggplot2:通过不同的图层绘制图形,比qplot更加灵活。
在绘制好图形之后,last_plot函数可以返回*近绘制的一幅图形。而ggsave("plot.png", width = 5, height = 5)函数则可以将*近绘制的图形保存下来。
1.5.1 使用qplot函数快速绘图
qplot函数类似于R base中的plot函数。它可以用来快速、轻松地创建不同类型的图,如散点图、小提琴图、直方图和密度图。qplot的简化格式为: qplot(x, y = NULL, data, geom="auto") qplot绘图函数的参数如下:
? x、y:分别为x和y值。参数y是可选的,这取决于要创建的图形类型。
? data:要使用的数据框(可选)。
? geom:指定要使用的geom的字符向量。如果指定了x和y,则默认为"point",如果只指定x,则默认"histogram"。其他参数,如main、xlab和ylab,可用于向绘图添加主标题和轴标签。
首先使用qplot绘制散点图,qplot函数如果指定了两个连续变量的话,默认会绘制散点图,代码如下,结果如图1.6所示。 # 绘制散点图
library(ggplot2)
qplot(x = speed,y = dist,data = cars)
图1.6 使用qplot函数绘图
上面的代码绘制了cars数据集中汽车速度与停车距离的一个散点图,等价于qplot(x = speed,y = dist,data = cars,geom="point")。因为默认的是geom="point",所以在绘制散点图的时候可以省略该参数。需要注意的是,可以同时指定两种几何变换。下面的代码绘制了散点图,同时添加了拟合曲线,结果如图1.7所示。 # 添加拟合曲线
qplot(x = speed,y = dist,data = cars,geom = c("point","smooth"))
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
图1.7 拟合曲线
上面的代码添加了两种几何变换,绘制了散点图,然后添加了散点图的拟合曲线。qplot函数的绘图方式和R中基础的绘图方式非常相似。
1.5.2 使用ggplot函数绘图
如上所述,函数ggplot比qplot功能强大且更灵活。本节简要介绍如何使用ggplot逐步构建一个更加美观的图形。回想一下,ggplot2包的概念是将一个plot分为3个不同的基本部分:plot = data aesthetic geometry。为了演示函数ggplot的工作原理,我们将绘制散点图。函数aes用于指定x和y变量及美学(例如,颜色、形状、大小),然后使用ggplot函数来绘制上文使用qplot函数绘制的图形,如图1.8所示。 # 绘制散点图
ggplot(data = cars,aes(x = speed,y = dist)) geom_point() 上面的代码绘制出的散点图,与使用qplot函数绘制的散点图一样。上面的代码也由三部分组成。首先是数据集,由参数data指定;图形美学用aes函数指定;几何变换用函数geom_point指定。不同的组成部分通过 连接起来,*终绘制成一幅图形。
图1.8 使用ggplot函数绘制图形
如果想要添加多种几何变换,使用ggplot函数很容易实现,如图1.9所示。 # 绘制散点图以及拟合曲线
p <- ggplot(data = cars,aes(x = speed,y = dist)) p geom_point() geom_smooth()
## 'geom_smooth()' using method = 'loess' and formula 'y ~ x'
图1.9 使用ggplot函数绘图
上面的代码绘制了散点图和散点图的拟合曲线,并且分别添加了geom_point函数用于绘制散点图、geom_smooth函数用于添加拟合曲线。注意,这里有一个绘图的小技巧:在绘制图形的时候,可以将数据和图形美学保存为一个变量,然后在接下来的绘图过程中使用保存的变量再加上不同的几何变换来绘制不同的图形,这样可以使代码尽可能*简洁。
以上是关于ggplot函数的介绍,接下来会介绍更多内容。