R语言编程指南(txt+pdf+epub+mobi电子书下载)


发布时间:2020-11-11 18:02:05

点击下载

作者:任坤

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

R语言编程指南

R语言编程指南试读:

前言

R 是为统计计算、数据分析和可视化而设计的。近年来,它已成为数据科学和统计学中最受欢迎的语言。R语言编程很大程度上涉及数据处理。对于不熟悉R语言的人来说,用R进行编程可能是一个挑战。

作为一种动态语言,R可以灵活地使用不同的数据结构,不像C++、Java和C#这类编译型语言那么严格。当我开始使用R处理和分析数据时,发现它的行为很古怪,不可预测,而且有时非常不稳定。

一些数据分析项目并没有在构建模型上做很多工作。相反,数据清洗、处理和可视化花了更多时间。事实上,在代码运行报错或返回的结果很奇怪时,找到问题的根源才是最耗时的。处理编程问题比处理专业领域内的问题更令人受挫,尤其是在遇到错误,但搞了几小时仍然毫无头绪的时候。

但是,随着项目的增多,也积累了更多的经验,我逐渐了解了对象和函数的行为,并且发现R比我想象的更优雅、更稳定。这就是我编这本书的原因,以分享我对R语言编程逐步深入的认识过程。

通过阅读本书,你会对R编程语言及其大量的工具有一个普遍一致的理解,并将学习到提高效率的最佳实践方法,更深入地了解如何使用数据,并且对如何在R中编程,以及用正确的技巧解决问题等更有信心。本书主要内容

第1章“快速入门”讨论了一些有关R的基础内容,包括如何部署R环境,如何在RStudio中编写代码。

第2章“基本对象”介绍基本的R对象及其性质。

第3章“工作空间管理”介绍工作目录、R环境和扩展包库的管理方法。

第4章“基本表达式”介绍R语言的基本表达式:赋值、条件和循环。

第5章“基本对象操作”讨论每个数据分析师都应该了解的基本函数,以便在R中使用基本对象。

第6章“字符串的使用”讨论与字符串相关的R对象,以及一些字符串操作技术。

第7章“数据处理”解释一些简单的读写数据的函数,并通过一些使用基本对象和函数的实际案例进行演示。

第8章“R的内部机制”通过介绍惰性计算、环境、函数和词法作用域,探讨R的计算模式。

第9章“元编程”介绍元编程技术以帮助理解语言对象和非标准化求值。

第10章“面向对象编程”阐释R中众多的面向对象编程系统:S3、S4、RC和社区提供的R6。

第11章“数据库操作”介绍在R中如何使用SQLite和MySQL等流行的关系型数据库,以及MongoDB和Redis等非关系型数据库。

第12章“数据操作”介绍如何使用data.table和dplyr处理关系型数据,以及使用rlist处理非关系型数据的技术。

第13章“高性能计算”讨论R的性能问题和提高计算性能的常用方法。

第14章“网页爬虫”讨论网页、CSS和XPath选择器的基本结构,以及如何使用rvest包从简单的网页中抓取数据。

第15章“效率提升”演示了如何利用R Markdown和shiny app结合交互式图形来提高数据分析报告和展示的效率。阅读本书还需要什么

运行书中的示例代码,需要安装R 3.3.0或更高版本,推荐使用RStudio开发环境。

对于第11章,运行示例代码需要一个可用的MongoDB服务器和一个Redis实例。

对于第13章,在Windows操作系统下需要安装Rtools 3.3来创建Rcpp代码,在Linux或macOS操作系统下,则需要gcc工具链。本书的目标读者

本书主要面向从事数据相关项目并希望提高工作效率的读者,但可能不适合对编程语言和相关工具一无所知的人阅读。

本书也适用于想要系统地学习R编程语言、相关技术和推荐的扩展包及其实际应用的专业数据分析师。

书中的一些章节对于初学者来说比较高深,尽管阅读这些章节并不要求你是计算机专家或者专业的数据分析师,但我认为对基础编程概念有一些了解并具有数据处理的基本经验,会有助于对本书内容的理解。约定

在本书中,你会发现一些用于区分不同信息的文本样式。以下是这些样式的示例及其含义的解释。

文本中包含的代码、数据库表名、文件夹名、文件名、文件扩展名、路径、虚拟的网址(URL)、用户输入和推特名称用代码体显示,如下所示:“apply( )函数也支持数组输入和矩阵输出。”

内联代码(变量和函数名)和代码块的样式设置如下:x c(1, 2, 3)class(x)## [1] "numeric"typeof(x)## [1] "double"str(x)## num [1:3] 1 2 3

当某个函数名或变量名被选中时,相同的函数名或变量名就会高亮显示:x rnorm(100)y rnorm(100) * 0.5m lm(y ~ x)coef(m)

第一次出现的术语和重要词汇会以粗体显示。小技巧:警告或重要的提示出现在这样的框中。提示:提示和技巧以这种形式出现。读者反馈

我们欢迎并重视读者的反馈。请让我们知道你对本书的看法——喜欢或不喜欢什么。读者的反馈对我们很重要,它有助于我们推出对读者更有价值的产品。

若想反馈给我们,可直接发送邮件到feedback@packtpub.com,并在邮件主题中注明书名。

如果你精通某一主题,并有兴趣编写或撰稿,请前往作者指南网页:www.packtpub. com/authors。用户支持

作为Packt图书的拥有者,我们准备了很多服务来最大化你的消费权益。下载示例代码

你可以在http://www.packtpub.com登录账户并下载本书对应的示例代码。如果你是在其他地方购买的本书,可以访问http://www.packtpub.com/support进行注册,我们会将代码文件直接发到你的邮箱。

你可以按照以下步骤下载代码文件。

1.使用电子邮箱和密码在网站登录或注册。

2.将鼠标指针悬停在顶部的SUPPORT选项卡上。

3.单击Code Downloads & Errata按钮。

4.在Search对话框中输入书名。

5.选择想要下载的代码文件对应的书名。

6.从下拉菜单中选择购买本书的途径。

7.单击Code Download按钮。

也可以访问Packt出版社网站上的网页,单击Code Files按钮下载代码文件,还可以在搜索框中输入书名来访问该网页。请注意,需要登录你的Packt账户才能执行以上步骤。

文件下载好之后,请务必使用以下软件的最新版本进行解压:● WinRAR/7-Zip for Windows● Zipeg/iZip/UnRarX for Mac● 7-Zip/PeaZip for Linux

本书的代码同时托管在GitHub上:https://github.com/PacktPublishing/learningrprogramming。我们的GitHub主页上还有更多图书和视频资源:https://github.com/PacktPublishing/。快来浏览一下吧!勘误

尽管我们已经尽全力确保本书内容的准确性,但是错误还是在所难免。如果你在我们的某本书中发现了错误(可能是文字或代码错误),请告知,我们将不胜感激。这样,你可以帮助其他读者避免困惑,并帮助我们改进本书的后续版本。如果您发现任何错误,请打开http://www.packtpub.com/submit-errata网页,选择相应图书,单击勘误表的提交表单链接,输入勘误表的详细信息。一旦您的勘误经过验证,我们将接受您提交的内容,并将勘误上传到网站,或追加到该题目现有勘误表的下面。

若想查看之前提交的勘误表,请转到https://www.packtpub.com/books/content/support,并在搜索栏中输入书名,所需信息将显示在勘误部分的下方。盗版

网络上的盗版问题是所有媒体一直面对的问题。在Packt,我们非常严肃认真地保护版权和许可。如果你在网络上发现有关作品的任何形式的盗版版本,请立即向我们提供网址或者网站名称,以便我们及时采取补救措施。

请通过copyright@packtpub.com与我们联系,并附上可疑盗版资料的链接。

衷心地感谢你帮助我们保护作者的权益以及我们为你带来宝贵知识的能力。问题

如果您对本书的任何方面有任何问题,可以通过questions@packtpub.com与我们联系,我们会尽全力为你解决。第1章快速入门

卓越的数据分析需要建立在出色的工具平台上,没有合适的工具,数据分析也是空中楼阁。即使对专家来说,没有得力的分析工具,从大数据集中直接提取模式并得到结论也几乎是不可能的。因此,一款合适的工具,例如 R,会显著地提升处理数据的效率。就我的经验而言,学习一门编程语言就类似于学习一种人类语言。通常情况下,我们先对一门语言有一个全局的了解,激发学习兴趣,然后通过一些小项目进行尝试,这是一条不错的学习路径。而在此之前,若是纠结于词汇和语言的细节就有些本末倒置了。本章对R进行全面概述,以便帮助你快速入门。

本章我们将介绍以下内容:● R简介● 对R的需求● R的安装● R的编辑工具

一旦软件和工具准备就绪,你就可以编写一个简单的R程序来体验它的基本运行方式了。接下来,我们便开始了R的学习之旅,从基础方法到高级技术和应用,一步一步领略R语言的编程之美。1.1 R简介

R 是一门强大的编程语言和统计计算环境,也是数据探索、分析和可视化的利器。它是免费、开源的,并且具有一个活跃且强大的、快速成长的社区。在这里,用户和开发者共享彼此的经验,他们贡献了超过7500个扩展包,因此,R 可以处理众多领域的各种各样的问题(参见https://cran.r-project.org/web/views/)。

尽管R编程语言的起源只追溯到1993年,但数据相关行业普遍采用R语言编程,因此在近十年里,R已迅速成长并成为数据科学领域的通用工具。

一般来说,R不仅是一门编程语言,而且是一个综合计算环境,一个活跃且强大的社区,一个快速生长和扩大的生态系统。1.1.1 编程语言

作为一门编程语言,R已经演变和发展了20多年。开发者的目标非常清晰,就是使R成为一款简单易用且灵活的,能够综合执行统计计算、数据探索和可视化的工具。

然而,易用性和灵活性通常是相互冲突的。如果可以通过简单单击几个按钮就可以完成多种多样的统计分析任务,那么在实现自定义和自动化,并保证工作的可重复性时就不可能兼具灵活性。另一方面,R可以非常灵活地使用多种函数进行数据转换,构建复杂的图形等,但学习和正确地组合这些函数就会有一定的难度。R良好地平衡了易用性和灵活性,使得它在众多工具中脱颖而出。1.1.2 计算环境

作为一个计算环境,R 具有轻量级和安装即用的特点。相比其他著名的统计软件,例如Matlab和SAS,R更小且更容易配置。

在本书中,我们使用RStudio处理绝大部分R中的工作。该集成开发环境提供了丰富的功能,如语法高亮、自动补齐、扩展包管理、图形查看器、帮助查看器、环境查看器以及调试功能。这些功能极大地提高了用户的工作效率。1.1.3 社区

作为一个社区,R是强大且活跃的。你现在就可以访问Try R(http://tryr.codeschool.com/),通过交互式教程对R的基本知识有个初步的了解。在实际编写代码时,你可能会遇到各种各样的问题,但是不必独自解决所有问题。你可以在google上搜索一个R的问题,就会发现几乎总是可以在Stack Overflow(http://stackoverflow.com/questions/tagged/r)上找到很多解答。如果你的问题没有完全解决,也可以在上面继续提问,往往几分钟就可以得到回答。

如果你需要使用某个扩展包,并且详细地了解它的工作方式,可以访问它的在线存储库(repo)获取源代码。许多存储库托管在GitHub(https://www.github.com)上。在GitHub上,你可以做更多事情。当发现一个扩展包不能正确运行时,你可以提交一份问题报告。如果你需要的某个功能正好契合某个扩展包的开发目的,也可以提交一份需求报告。同样,如果你有兴趣解决某个扩展包的问题或者丰富它的功能,也可以加入该项目,编辑代码并发送合并请求,这样你做的更改就可以被原开发者接收到。如果你的更改被接受了,那么,恭喜你,你就会成为该扩展包的一个贡献者。令人惊奇的是,R和它的数千个扩展包就是被世界各地的贡献者们开发创建的。1.1.4 生态系统

作为一个生态系统,R在除IT行业以外的所有数据相关领域中迅速发展壮大。大多数用户并不是专业开发者,而是数据分析师和统计人员。这些用户可能不会写最优质的代码,但是他们有助于拓展R语言的前沿工具,任何人都可以自由地使用这些工具,而不必重新研究开发。

举个例子,假设一个计量经济学家写了一个扩展包,实现了检测某类时间序列模式的新方法。一些用户可能会发现它有趣又有用。还有一些专业用户可能改进了原来的代码使其更快、更通用。不久之后,量化投资者可能会将该方法纳入到交易策略中,因为它可以检测到通常在其投资组合中引起风险的模式。一天结束时,投资者会发现,将计量经济学家的工具应用到现实世界中,借此构建的投资组合风险较小。

这就是R生态系统的工作方式。这也是R在这些领域闪耀的原因之一:它能够快速地将IT行业之外(通常是数据科学、学术界和工业界)的前沿知识应用到生态系统中可用且合适的工具上。换句话说,它有助于将这些领域的知识和数据科学转变为生产力和价值。1.2 对R的需求

在众多统计软件中,R能够脱颖而出,有以下几个方面的原因。● 免费:R是完全免费的。你不需要购买许可证书,因此,使用R

和大部分扩展包是没有准入障碍的。● 开源:R和大部分扩展包都是完全开源的。数以千计的开发者不

断地审查包的源代码,查看是否存在需要修复的漏洞或者可以改

进的地方。如果你遇到了异常,可以研究和挖掘源代码,找到问

题所在,并解决问题。● 流行:即使R不是最流行的编程语言,但在统计编程语言和数据

挖掘、数据分析与可视化平台方面,它也是相当受欢迎的。高度

通用性意味着你和其他用户之间的沟通更加方便,因为你们“讲”同一种语言。● 灵活:R是动态脚本语言。它的高度灵活性允许多种范式的编程

风格,包括函数式编程和面向对象编程,它还支持灵活的元编程。

此外,R的灵活性使你能够执行高度定制的复杂的数据转换和可

视化。● 可重复性:当使用基于图形用户界面的软件时,你只需要从菜单

中点选。但是,如果你没有编写脚本,就很难自动并准确地复制

你已经完成的工作。

在大多数科研领域和许多工业应用中,由于各种原因,重复性是

必要的。R脚本可以精确地描述和记录你使用计算环境和数据的

各项操作,因此,可以从头开始完全重现之前的所有步骤。● 丰富的资源:R拥有数量巨大、增速迅猛的在线资源。一类资源

就是扩展包。当我编写本书时,在CRAN(Comprehensive R

Archive Network)上就有超过7500个扩展包。CRAN是一个全球

网络镜像服务器,你可以从中获取一致的最新版本的R软件和扩

展包。

世界各地有超过4500个开发者创建并维护着这些扩展包,开发

者们几乎遍布所有的数据相关领域,例如多元统计分析、时间序

列分析、计量经济学、贝叶斯推断、最优化、金融学、遗传学、

化学计量学、计算物理学等。你可以访问CRAN任务视图(https:// cran.r-project.org/web/views/)获取全面的总结。

除了这些数量庞大的扩展包之外,还有很多开发者经常编写个人

博客,并在Stack Overflow上回答问题,分享他们的观点、经验

和一些实战方法。同时,还有很多关于R的社区网站,例如R-

bloggers(http://www.r-bloggers.com/)、R

documentation(http://www.rdocumentation.org/)和

METACRAN(http://www.r-pkg.org/)。● 强大的社区:R的社区成员不仅有R的开发者,还有(并且大多

数都是)R用户,他们有不同的专业背景,例如统计学、计量经

济学、金融学、生物信息学、机械工程学、物理学、医学等。

有非常多的R开发者积极地贡献开源项目或者扩展包。社区的共

同目标就是使数据分析、数据探索和可视化变得简单有趣。

如果你在使用R的过程中被某个问题绊住了,只需在Google上搜

索一下,极有可能已经存在解决方案了。如果没有,你也可以在

Stack Overflow上提问,并且很快就会得到回复。● 前沿:很多R用户都是统计学、计量经济学或其他学科的专业研

究者。很多时候,作者在发表一篇新论文的时候都会贡献一个新

的扩展包,该扩展包就纳入了论文中前沿技术的实现算法,可能

是一个新的统计检验、一种模式识别方法或者更好的调整优化算

法。

无论是何种前沿技术,R社区都有幸将数据科学知识应用于现实

世界,进一步提高其功能并揭示其潜力。1.3 R的安装

为了安装R,你需要前往R的官网(https://www.r-project.org/)去下载R软件(https://cran.r- project.org/mirrors.html),选择适合的镜像,并下载与你的计算机操作系统相适应的版本。在编写本书时,R最新的版本是3.2.3。本书中的例子就是在这个版本下创建和运行的,适用的操作系统是Windows和Linux,但是使用更早版本的R或者其他操作系统,其运行结果也没有显著差异。

如果你使用的是Windows操作系统,只需下载最新版的安装程序,并运行安装。安装过程简单便捷,但是仍会有许多使用者在某一些步骤上遇到问题。

当你在Windows操作系统下进行安装时,在选择安装内容时,会看到安装列表中有4项内容。其中,Core files是指R的核心库,Message translations提供了关于警告和错误的多种翻译版本。可能使你感到困惑的是选择32-bit Files选项,还是64-bit Files选项。其实不必担心,你只需了解64位版本的R比32位的在单一过程中能够处理更多数据即可。如果你的计算机是最近几年买的,那么,极有可能是64位操作系统,支持64位程序,因此,默认选择64位文件。如果你使用的是32位操作系统,很遗憾的是,你不能使用64位的R,除非你的计算机硬件支持并安装了64位的操作系统。

我建议使用默认选项进行安装,如图1-1所示。图1-1

另一个可能使你感到困惑的选项是要不要保存许可证中的数字。检查这些选项会使其他程序识别安装的是R的哪个版本更简单。如果你确定仅在R环境中使用,请保持默认选项,直接下一步即可,如图1-2所示。图1-2

然后,安装程序开始将文件复制到你的硬盘中,如图1-3所示。图1-3

最终,R就部署在你的计算机中了。此时,你只能通过两种方式使用R:命令提示符(终端)或者R GUI。

如果允许安装程序创建快捷方式到桌面上,你就会发现有两个R的快捷方式。R在命令提示符中运行,R GUI在极其简单的GUI中运行。

尽管你现在就可以启动R,但不意味着就要用这种方式使用它。我强力推荐使用RStudio编辑和调试R脚本。实际上,本书就是在RStudio的R Markdown中编写的。虽然RStudio很强大,但没有正确安装R的话,它也没有办法工作。换句话说,R是底层,RStudio是前端,RStudio帮助你更好地使用R。

如果你使用 Windows 操作系统,也可以安装Rtools(http://cran.rstudio.com/bin/ windows/ Rtools/),这样就可以在R中编写、编译和调用C++代码,也可以安装包含C++代码的扩展包,并在C++的环境中进行编译。1.4 RStudio

RStudio是R编程语言强大的用户界面。它是免费、开源的,适用于多种操作系统,包括Windows、Mac和Linux。

RStudio具有非常强大的功能,能够极大地提升数据分析和可视化的工作效率。它支持语法高亮、自动补齐、多标签视图、文件管理、图形窗口、扩展包管理、集成帮助查看器、代码格式化、版本控制、交互式调试以及其他功能。

你可以从https://www.rstudio.com/products/rstudio/download下载最新发布的RStudio。如果你想体验预览版本的新功能,就需要从https://www.rstudio.com/products/rstudio/download/ preview下载预览版。注意,RStudio并没有内嵌在R中,所以你需要确保在使用RStudio时已经安装了R。

接下来,我将向你简要介绍RStudio的用户界面。1.4.1 RStudio的用户界面

图1-4展示的是Windows操作系统中的RStudio用户界面。如果你使用Mac OS X或者Linux支持的版本,界面看起来几乎是一样的。图1-4

你可能注意到,主窗口是由几部分构成。每个部分都称为一个窗格,分别执行不同的函数。这些窗格都是为数据分析师处理数据而精心设计的。

1.控制台

图1-5 展示的是内嵌在RStudio中的R控制台。在大多数情况下,控制台的工作原理和命令提示符或者终端完全一致。实际上,当你在控制台输入一条命令时,RStudio便向R引擎提交请求,由R引擎执行所有命令。RStudio 的作用就是中介传输,将用户的输入提交给R引擎,再将返回的结果呈现出来。图1-5

使用控制台,你可以很方便地执行一条命令,定义一个变量,或者交互式地执行表达式来计算一个统计测度,转换数据,或者生成图表。

2.编辑器

处理数据时,我们通常不在控制台输入命令。相反,我们会编写一份脚本文件,即一组命令的集合,来表示整个操作过程的逻辑流,该脚本文件可以直接读取并由R引擎执行。如图1-6 所示,脚本文件的编写就是在编辑器中完成的。编辑器可用于编辑 R 脚本、markdown 文档、网页,以及许多类型的配置文件,甚至是C++源代码。图1-6

代码编辑器的功能比纯文本编辑器的功能多很多:它支持语法高亮、自动补齐R代码、断点调试等。具体来说,当编辑R脚本时,你可以使用以下快捷键。● 按Ctrl + Enter组合键运行选中的命令行。● 按Ctrl + Shift + S组合键执行当前文档,也就是依次执行当前文

档中的所有表达式。● 按Tab键或Ctrl + Space组合键展示匹配当前输入变量和函数的自

动补齐列表。● 单击行数的左侧边缘并设置一个断点;下次执行这行命令时,程

序会停下来等待检查。

3.环境窗格

环境窗格展示已经被创建的变量和函数,这些变量和函数可以重复使用。默认情况下,它展示的是全局环境中的变量,即你正在使用的工作空间,如图1-7所示。图1-7

每次创建一个新的对象(一个变量或函数),环境窗格中就会出现一个新的元素。这个元素展示了变量名和其值的简短描述。当你改变某个符号的值,或者移除这个符号时,实际上是修改了环境,因此环境窗格会反映出你的更改。

4.历史窗格

历史窗格展示了在控制台执行过的表达式。只需双击命令行或者选中命令行再单击“To Console”,你就可以重复执行之前运行过的任务,如图1-8所示。图1-8

历史记录保存在工作目录中的.Rhistory文件中。

5.文件窗格

文件窗格展示了文件夹中的文件列表。你可以在文件夹之间进行操作:创建新文件夹、删除或重命名文件夹或文件等,如图1-9所示。图1-9

如果你的工作正在一个RStudio项目上进行,在文件窗格可以很方便地查看和整理项目文件。

6.绘图窗格

绘图窗格用来展示R代码生成的图形。如果你生成了多个图形,前面的图形会被保存下来,单击向前或向后便可以查看所有图形(只要你没有清除它们),如图1-10所示。图1-10

当你调整绘图窗格的尺寸时,其中的图形会自动调整以适应窗格大小,这样一来,图形看起来就像未曾调整过一样友好,你也可以将图形导出到文件中备用。

7.扩展包窗格

R 的很多强大之处来自于它的扩展包。扩展包窗格展示所有安装的扩展包,你可以从CRAN中安装或更新包,或将已有包从库中移除,如图1-11所示。图1-11

8.帮助窗格

R 的强大之处也源自其非常详细的帮助文档。如图1-12所示,帮助窗格展示帮助文档,这样你就可以很方便地学习如何使用函数。图1-12

有很多方式可以查看函数的帮助文档。● 在搜索框输入函数名就可以直接找到。● 在控制台输入函数名并按F1键。● 输入“?函数名”,并执行它。

实战中,你不必记住所有的R函数,只需记住,在面对不熟悉的函数时要如何寻求帮助。

9.查看器窗格

查看器窗格是一项新特征;R包的数量一直在增加,查看器窗格的引入,就是将R和现有的JavaScript库的功能相结合,使数据的展示形式更加丰富,也增加了交互功能。

图1-13就是我编写的formattable(http://renkun.me/formattable)扩展包中的一个例子,这个例子展示了在R的数据框中进行Excel的条件化格式操作的一种简单实现。图1-131.4.2 RStudio服务器

如果你使用的是基于Linux的版本,就可以轻松地构建RStudio或RStudio Server的服务器版本。这样一来,RStudio在主机服务器(可能比你的笔记本电脑更强大更稳定)上运行,你就可以在网页浏览器中运行RStudio中的R会话。虽然用户界面没有什么差别,但是连接至服务器后,就可以像使用本地计算机一样使用服务器的计算和内存资源。1.5 入门示例

在这一小节中,我将通过一个简单的例子,演示如何在控制台中输入命令来执行计算、模型拟合和生成图形。

首先,我们创建一个向量x,它由100个服从正态分布的随机数构成。然后,创建另一个向量y,它也包含100个数,而且每一个数都是x中对应数的3倍加2,再加上一些随机噪声。注意,<-是赋值操作符,我们后面会讲到。使用str( )函数输出向量的结构:x rnorm(100)y rnorm(100) * 0.5str(x)## num [1:100] -0.4458 -1.2059 0.0411 0.6394 -0.7866 ...str(y)## num [1:100] -0.022 -1.536 2.067 4.348 -0.295 ...

既然我们知道x和y之间的真实关系是y = 3x+2+ε,那么,就可以利用x和y的样本拟合一个简单的线性回归,并查看线性模型如何还原线性参数(即2和3)。调用lm(y~x)拟合这个模型:model1 lm(y ~ x)

模型拟合的结果保存在名为model1的对象中。我们只需输入model1或者明确地输入print(model1)就可以查看模型的拟合情况:model1## ## Call:## lm(formula = y ~ x)#### Coefficients:## (Intercept)x## 2.051 2.973

如果你想查看更多细节,可以对model1调用summary( ):summary(model1)#### Call:## lm(formula = y ~ x)#### Residuals:## Min 1Q Median 3Q Max## -1.14529 -0.30477 0.03154 0.30042 0.98045#### Coefficients:## Estimate Std. Error t value Pr(>|t|)## (Intercept) 2.05065 0.04533 45.24 <2e-16 ***## x 2.97343 0.04525 65.71 <2e-16 ***## ---## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1#### Residual standard error: 0.4532 on 98 degrees of freedom## Multiple R-squared: 0.9778, Adjusted R-squared: 0.9776## F-statistic: 4318 on 1 and 98 DF, p-value: < 2.2e-16

我们将样本点和拟合的模型展示在图1-14中:plot(x, y, main = "Simple linear regression")abline(model1$coefficients, col = "blue")图1-14

上面这个例子演示了一些简单函数,帮助你对如何使用R建立一个初步印象。即使不熟悉例子中出现的符号和函数,也没有关系,后面的章节会讲解你需要了解的基本对象和函数。1.6 小结

在本章中,你掌握了R的基本情况和主要优点。我们已经学习了如何在Windows操作系统下安装R。为了使R编程更简单,我们选择使用RStudio。通过RStudio的用户界面,你了解了主窗口中各个窗格的功能。最后,我们通过运行几行R命令拟合了一个模型,并绘制了一幅简单的图形,对使用R有了初步的认识。

下一章将介绍R中的基本概念和数据结构,帮助你熟悉R对象的行为。之后,你便可以轻松地展示、操作和处理各种形式的数据。第2章基本对象

学习R语言编程的第一步是熟悉基础的R对象和它们的性质。在本章中,你将学到以下内容。● 原子向量(atomic vector)的创建和构建子集(subsetting

vector),例如数值向量(numeric vector)、字符向量(character vector)和逻辑向量(logical vector),以及矩阵(matrice)、数组(array)、列表(list)和数据框(data

frame)。● 定义和使用函数。“万物皆对象,万事乃函数。”——John Chambers

例如,在统计分析中,我们经常将一组数据输入到一个线性回归模型中来获得回归系数。

尽管在R中有不同类型的R对象,但在实际工作中,我们仅需提供一个包含数据集的数据框,将其代入一个线性回归模型中,获得一个包含回归结果的信息列表,最后从这一列表中提取出另一种类型的对象——数值向量,来展示回归系数。

每项工作都涉及各种各样的对象,每个对象都有不同的用途和性质。其中非常重要的一点是,要理解一个基础对象在解决现实问题的过程中是如何运作的,尤其是如何用更优雅更简练的代码,以更少的步骤来实现它。更为重要的是,越是深入地了解对象的行为,越能让你有更多的时间用在解决实际问题上,而不是花费大量时间调试编程中的小问题。

在接下来的小节中,我们将看到多种多样的R对象,它们展示了不同类型的数据结构,并且能够使数据集的分析和可视化变得简单易行。你将对这些对象如何工作,以及它们之间如何互动有一个基本的了解。2.1 向量

一个向量是由一组相同类型的原始值构成的序列。它可以是一组数字、一组逻辑值、一组文本或者是其他类型的值。它是所有R对象的基础数据结构之一。

在R中,有多种类型的向量,区别在于它们存储的元素类型互不相同。在接下来的小节中,我们将会看到最常使用的向量类型,包括数值向量、逻辑向量和字符向量。2.1.1 数值向量

一个数值向量就是由数值组成的向量。单个数值(标量数值)就是最简单的数值向量。举一个例子:1.5## [1] 1.5

数值向量是最常用的数据类型,也几乎是所有数据分析的基础。在其他流行的编程语言中,存在一些标量类型,例如整型、双精度型和字符串型。这些标量是构成如向量等其他容器类型的基础。然而,在R中并没有对于标量类型的正式定义。标量数值只不过是数值向量的特例,并且仅仅特殊之处在其长度为1。

当我们创建一个值的时候,会很自然地想到如何存储它以备后续使用。为了存储这个值,我们可以使用<-将这个值赋给一个“符号”。换句话说,我们为这个值(1.5)创建了一个名为x的变量:x <- 1.5

这个值被分配给了符号x,之后我们可以用x来表示它:x## [1] 1.5

创建一个数值向量有许多种方法。我们可以调用numeric( )来创建一个由0组成的指定长度的向量:numeric (10)## [1] 0 0 0 0 0 0 0 0 0 0

我们也可以使用c( )把多个向量组合成一个向量。最简单的情况是,组合多个单元素向量构成一个多元素向量:c(1, 2, 3, 4, 5)## [1] 1 2 3 4 5

我们还可以将多个单元素向量和多元素向量连接起来构成一个向量,使其和之前创建的向量具有相同的元素:c(1, 2, c(3, 4, 5))## [1] 1 2 3 4 5

如果想要创建一系列连续的整数值,运算符“:”能够轻松地实现这一点。1:5## [1] 1 2 3 4 5

准确地说,以上代码产生的是整数值向量而不是数值向量。在很多情况下,它们之间的区别并不重要。我们之后将会讨论这个问题。

产生一个数值序列,更通用的方法是使用seq( )。例如,以下代码产生了一个数值向量,它由从1开始,到10结束,步长为2的序列组成:seq(1, 10, 2)## [1] 1 3 5 7 9

像seq( )这样的函数有很多参数。我们可以通过提供其所有的参数来调用这个函数,但在大多数时候并不必要。大部分函数对其部分参数提供了合理的默认值,这使得我们能够更加轻松地调用它们。在现在这种情况下,我们只需指定想要更改的参数即可。

例如,可以通过指定length.out这个参数来创建另外一个从3开始,长度为10的数值向量:seq(3, length.out = 10)## [1] 3 4 5 6 7 8 9 10 11 12

如上所示的函数调用过程,只修改了参数length.out的取值,其他参数的值保持默认值。

尽管我们可以使用多种方法定义数值向量,但是必须始终小心地使用“:”运算符,举一个例子:1 + 1:5## [1] 2 3 4 5 6

从结果来看,1 + 1:5并不意味着一个从2~5的序列,而是一个从2~6的序列。这是因为“:”比“+”具有更高的优先级,这使得首先产生的是1:5,接着才对每一个值加1,这才产生了你在结果中所看到的序列。我们之后会讨论关于运算符优先级的问题。2.1.2 逻辑向量

与数值向量不同,一个逻辑向量储存一组TRUE或FALSE值。它们基本上以“是”或“否”来表示对一组逻辑问题的回答。

最简单的逻辑向量是TRUE或者FALSE本身:TRUE## [1] TRUE

获得一个逻辑向量更一般的方法是询问关于R对象的逻辑性问题。例如,我们可以询问R,1是否大于2:1 > 2## [1] FALSE

如果回答“是”,就返回TRUE;如果回答是“否”,就返回FALSE。有时,写TRUE或者FALSE太繁琐了,我们可以使用TRUE的缩写T和FALSE的缩写F。如果我们想同时进行多个比较,可以直接在问题中使用数值向量:c(1, 2) > 2## [1] FALSE FALSE

R 会将这一表达式理解为在c(1, 2)和2之间依次进行元素比较。换句话说,这实际上等价于c(1 > 2, 2 > 2)。

我们可以比较两个多元素数值向量,只要较长向量的长度是较短向量长度的整数倍:c(1, 2) > c(2, 1)## [1] FALSE TRUE

上述代码等价于c(1 > 2, 2 > 1)。为了验证两个不同长度的向量是如何比较的,请看下面的例子:c(2, 3) > c(1, 2, -1, 3)## [1] TRUE TRUE TRUE FALSE

这个结果可能会使你有些困扰。以上代码的运算机制是不断地循环较短的向量并进行比较,等价于c(2 > 1, 3 > 2, 2 > −1, 3 > 3)。更明确地说,较短的向量将会不断地循环直到和较长向量中的元素全部完成比较。

在R中,定义了一些二元逻辑运算符,例如“==”表示相等,“>”表示大于,“>=”表示大于或等于,“<”表示小于,“<=”表示小于或等于。此外,R还提供了一些其他运算符,例如用%in%判断运算符左侧向量的每一个元素是否都包含在运算符右侧的向量中:1 %in% c(1, 2, 3)## [1] TRUEc(1, 4) %in% c(1, 2, 3)## [1] TRUE FALSE

你可能注意到了所有等式运算符都执行了循环,但是%in%并没有。相反,它总是通过迭代左侧向量的单个元素,在上述例子中,就像c(1 %in% c(1, 2, 3), 4 %in% c(1, 2, 3))这样完成运算。2.1.3 字符向量

一个字符向量是由字符串组成的向量。这里的一个字符不是指着文学意义上的单独的字母或者符号,而是一个类似this is a string这样的字符串。双引号和单引号都可以用来生成字符向量,例如:"hello, world!"## [1] "hello, world!"'hello, world!'## [1] "hello, world!"

我们也可以使用组合函数c( )来创建一个多元素的字符向量:c("Hello", "World")## [1] "Hello" "World"

使用==来判断两个向量中处于对等位置的值是否相等,这同样适用于字符向量:c("Hello", "World") == c('Hello', 'World')## [1] TRUE TRUE

因为单引号 ' 和双引号 " 都可以用来生成字符串并且不影响其含义,所以上述两个字符向量相等:c("Hello", "World") == "Hello, World"## [1] FALSE FALSE

上述表达式产生了两个FALSE,是因为Hello和World都不等于Hello, World。两种引号之间的唯一区别是,当生成一个包含引号的字符串时,它们的行为是不同的。

如果你想要在双引号内部嵌套双引号时,需要用反斜杠(\)来转义内部的双引号,类似使用“生成一个包含了其本身的字符串(一个单元素的字符向量),你需要在字符串内部输入\ 来转义”,用以防止编译时将字符串内部的”当作字符串的末引号。

接下来的例子展示了引号的转义。我们使用函数cat( )来生成指定文本:cat("Is \"You\" a Chinese name?")## Is "You" a Chinese name?

如果你感觉这不易于阅读,也可以使用 ’ 来生成该字符串,这样可以变得更简单:cat('Is "You" a Chinese name?')## Is "You" a Chinese name?

也就是说,双引号内部可以嵌套单引号,同样,单引号内部也可以嵌套双引号,即:"允许'存在于没有转义过的字符串中,'也允许"存在于没有转义过的字符串中。

现在我们掌握了关于生成数值向量、逻辑向量和字符向量的基本知识。实际上,在R中也有复数向量(complex vector)和原向量(raw vector)。复数向量是由复数组成的向量,例如c(1 + 2i, 2 + 3i)。原向量主要存储用十六进制格式表示的原始二进制数据。这两种类型的向量很少使用,但是它们与之前介绍过的3种类型的向量(整数型、逻辑型、字符型)具有很多相同的性质。

在下一节中,我们将学习到几种访问向量子集的方法。通过对向量取子集,你将理解不同类型的向量间是如何相互联系的。2.1.4 构建向量子集

如果想访问一些特定元素或者向量的一个子集,使用向量子集是一个不错的方法。在这一节中,我们将展示几种不同的构建向量子集的方法。

首先,生成一个简单的数值向量并且赋值给v1:v1 c(1, 2, 3, 4)

接下来的每一行都是用来获取v1的特定子集。

例如,提取第2个元素:v1[2]## [1] 2

也可以提取第2~4个元素:v1[2:4]## [1] 2 3 4

还可以获取除第3个以外的其他所有元素:v1[-3] ## [1] 1 2 4

这个模式很清晰,我们可以在向量后面的方括号中放入任何一个数值向量获取相应的子集:a <- c(1, 3)v1[a]## [1] 1 3

上述所有例子都是通过位置信息来构造子集,也就是说,通过指定元素的位置来得到一个向量的子集。方括号中使用负数将排除相应位置的元素。需要注意的一点是,在方括号中不能同时使用正数和负数:v1[c(1, 2, -3)]## Error in v1[c(1, 2, -3)]: 只有负下标里才能有零

如果使用向量范围之外的位置来获取子向量会发生什么呢?接下来的例子尝试获取向量v1的子集,范围是v1的第3~6个(不存在)元素:v1[3:6]## [1] 3 4 NA NA

正如我们所看到的一样,在不存在元素的位置用NA替代了缺失值。在现实世界的数据中,缺失值是普遍存在的。一方面,对所有包含NA的数据进行数值运算的结果都是NA,而不是其他不确定的结果;另一方面,因为直接假设数据中不存在缺失值并不恰当,所以我们需要付出额外的工作来处理数据。

另一种构造子集的方法是使用逻辑向量。我们可以输入与要获取向量子集的向量具有相等长度的逻辑向量,以此决定每一个元素是否要被获取:v1[c(TRUE, FALSE, TRUE, FALSE)]## [1] 1 3

除此之外,我们也可以给向量中特定的子集重新赋值(覆盖原值):v1[2] <- 0

在这种情况下,v1变成:v1## [1] 1 0 3 4

也可以同时覆盖处于不同位置的多个元素:v1[2:4] <- c(0,1,3)

现在,v1变成:v1## [1] 1 0 1 3

同样,重新赋值时,逻辑选择也是适用的:v1[c(TRUE, FALSE, TRUE, FALSE)] <- c(3, 2)

正如你所期待的,此时v1变成:v1## [1] 3 0 2 3

一个常用的技巧是可以通过逻辑标准来选择元素。例如,以下的代码挑选出v1中所有不大于2的元素:v1[v1 <= 2]## [1] 0 2

这种方法也适用于更复杂的选择标准。下面的例子挑选出v1中所2有满足x−x+10的元素:v1[v1 ^ 2 - v1 + 1 >= 0]## [1] 3 0 2 3

以下代码用0替代所有满足x <= 2的元素:v1[v1 <= 2] <- 0

像你期待的一样,此时v1变成:v1## [1] 3 0 0 3

如果我们对一个并不存在的元素重新赋值,向量将自动用NA填充未被指定的位置,当作缺失值处理:v1[10] <- 8v1## [1] 3 0 0 3 NA NA NA NA NA 82.1.5 命名向量

命名向量是一种不同于数值向量或逻辑向量的特定向量类型。它指的是该向量中的每一个元素都有相应的名称。我们可以在创建向量的同时对其命名:x <- c(a = 1, b = 2, c = 3)x## a b c ## 1 2 3

这样就可以通过单值字符向量来访问其中的元素:x["a"]## a ## 1

也可以通过一个字符向量来获取多个元素:x[c("a", "c")]## a c ## 1 3

如果字符向量中含有重复元素,则会选出相应的重复元素。x[c("a", "a", "c")]## a a c ## 1 1 3

除此之外,其余所有的能够用于向量中的操作也适用于命名向量。我们可以通过names( )获取向量中的元素名称:names(x)## [1] "a" "b" "c"

向量中的名称不是固定的,可以通过对向量赋予不同的字符向量来更改元素名称:names(x) <- c("x", "y", "z")x["z"]## z ## 3

当不需要元素名称时,也可以用NULL来移除原有的名称。NULL表示一个未定义值的特殊对象:names(x) <- NULLx## [1] 1 2 3

你可能会比较好奇,如果访问一个不存在的名称时会发生什么呢?我们对原始的x进行测试:x <- c(a = 1, b = 2, c = 3)x["d"]## ## NA

直觉上,访问一个不存在的元素应该会报错,但结果却返回一个无名的缺失值:

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载