R语言教程-初识R语言

# 本教程中所用到的软件包列表
pkgs <- c(
"assertthat",
"backports", "base64enc", "BH", "bindr", "bindrcpp", "bookdown", "broom",
"callr", "cellranger", "cli", "clipr", "clorspace", "crayon", "curl",
"DBI", "dbplyr", "dichromat", "digest", "dplyr",
"evaluate",
"forcats",
"ggplot2", "glue", "gtable",
"haven", "highr", "hms", "htmltools", "httr",
"jsonlite",
"knitr",
"labeling", "lazyeval", "lubridate",
"magrittr", "markdown", "microbenchmark", "mime", "mnormt", "modelr", "munsell",
"openssl",
"pillar", "pkgconfig", "plogr", "plyr", "psych", "purr",
"R6", "RColorBrewer", "Rcpp", "readr", "readxl",
"rematch", "reprex", "reshape2", "rlang", "rmarkdown",
"rprojroot", "rstudioapi", "rvest",
"scales", "selectr", "stringi", "stringr",
"tibble", "tidyr", "tidyselect", "tidyverse",
"utf8",
"viridisLite",
"whisker",
"xml2", "xtable",
"yaml"
)
install.packages(unique(pkgs))
# 编译本教程所用的R软件环境:
# devtools::session_info()

1. R语言介绍

1.1 R语言历史

R语言来自S语言,是S语言的一个变种。S语言由Rick Becker, John Chambers等人在贝尔实验室开发, 著名的C语言、Unix系统也是贝尔实验室开发的。
R是一个自由软件,GPL授权, 最初由新西兰Auckland 大学的Ross Ihaka 和 Robert Gentleman于1997年发布, R实现了与S语言基本相同的功能和统计功能。 现在由R核心团队开发,但全世界的用户都可以贡献软件包。 R的网站: http://www.r-project.org/

1.2 R的特点

  • 免费;
  • 完整的程序设计语言,基于函数和对象,可以自定义函数,调入C、C++、Fortran编译的代码;
  • 实现了经典的、现代的统计方法,如参数和非参数假设检验、线性回归、广义线性回归、非线性回归、可加模型、树回归、混合模型、方差分析、判别、聚类、时间序列分析等。
  • 支持对象类和类方法。基于对象的程序设计。
  • 是动态类型语言,解释执行,运行速度较慢。
  • 支持对象类和类方法。基于对象的程序设计。
    是动态类型语言,解释执行,运行速度较慢。

1.2.1 辅助软件

R可以把一段程序写在一个以.r或.R为扩展名的文本文件中, 如“date.r”, 称为一个_源程序_文件, 然后在R命令行用

source("date.r")

运行源程序。 这样的文件可以用记事本生成和编辑。编辑器推荐使用notepad++或者sublime text3

1.2.2 R扩展软件包的安装与管理

还可以选择扩展包的安装路径, 如果权限允许, 可以选择安装在R软件的主目录内或者用户自己的私有目录位置。 由于用户的对子目录的读写权限问题, 有时不允许一般用户安装扩展包到R的主目录中。 用.libPaths()查看允许的扩展包安装位置, 在install.packages()中用lib=指定安装位置:

# 安装sos包
install.packages("sos")
print(.libPaths())
## [1] "C:/Users/25835/Documents/R/win-library/3.5"
## [2] "C:/Program Files (x86)/ArrayTools/R/R-3.5.1/library"
install.packages("sos", lib=.libPaths()[1])

如果版本改变比较大,可以用如下方法批量地重新安装原有的软件包。 首先,在更新R软件前,在原来的R中运行:

packages <- .packages(TRUE)
dump("packages", file="packages-20200215.R")

这样可以获得要安装的软件包的列表。 在更新R软件后, 运行如下程序:

options(repos=c(CRAN="http://mirror.tuna.tsinghua.edu.cn/CRAN/"))
source("packages-20180704.R")
install.packages(packages)

安装时如果提问是否安装需要编译的源代码包, 最好选择否, 因为安装源代码包速度很慢还有可能失败。

1.3 基本R软件的用法

如果某个文件如myprog.R在当前工作目录中, 保存的都是R程序, 称这样的文件为源程序文件。 可以在命令行用如下命令运行其中的程序:

source("myprog.R")

但是, 在MS Windows操作系统中, 默认的中文编码是GB18030编码。 R源程序文件的中文编码可能是GB18030也可能是UTF-8。 UTF-8是在世界范围更通用的编码。 如果发现用如下命令运行时出现中文乱码, 可能是因为源程序用了UTF-8编码, 这时source()命令要加上编码选项如下:

source("myprog.R", encoding="UTF-8")
# 获取工作目录
getwd()

显示结果中目录之间的分隔符用了/符号, 在Windows操作系统中一般应该使用\符号, 但是, 在R的字符串中一个\需要写成两个, 所以等价的写法是"C:\work"。

项目
用R和RStudio进行研究和数据分析, 每个研究问题应该单独建立一个文件夹(目录)。 该问题的所有数据、程序都放在对应的文件夹中。 在RStudio中, 用“File – New Project – Existing Directory”选中该问题的目录, 建立一个新的“项目”(project)。

在基本R软件而不是RStudio的命令行中运行命令help.start()或者用RGUI的帮助菜单中“html帮助”可以打开系统默认的互联网浏览器, 在其中查看帮助文档。

帮助

在命令行,用问号后面跟随函数名查询某函数的帮助。 用example(函数名)的格式可以运行此函数的样例,如:

example(mean)

有时仅知道一些方法的名字而不知道具体的扩展包和函数名称, 可以安装sos扩展包(package), 用findFn("函数名")查询某个函数, 结果显示在互联网浏览器软件中。

1.4 使用技巧

使用历史

在控制台(命令行窗格)中, 除了可以用左右光标键移动光标位置, 用上下光标键调回以前运行过的命令, 还有一个重要的增强(以MS Windows操作系统为例): 键入要运行的命令的前几个字母,如book, 按“Ctrl+向上光标键”, 就可以显示历史命令中以book开头的所有命令, 单击哪一个, 哪一个就自动复制到命令行。 这一技巧十分重要, 我们需要反复允许同一命令时, 这一方法让我们很容易从许多命令历史中找到所需的命令。

放大显示某一窗格

当屏幕分辨率较低时, 将整个RStudio界面分为四个窗格会使得每个窗格都没有足够的显示精度。 为此, 可以将某个窗格放大到整个窗口区域, 需要使用其它窗格时再恢复到四个窗格的状态或者直接放大其它窗格到整个窗口区域。

使用菜单“View – Panes – Zoom Source”可以将编辑窗格放到最大, 在MS Windows下也可以使用快捷键“Ctrl+Alt+1”。 其它操作系统也有类似的快捷键可用。 使用菜单“View – Panes – Show All Panes”可以显示所有四个窗格。

放大其它窗格也可以用“Ctrl + Alt + 数字”,数字与窗格的对应关系为:

1: 编辑窗格;
2: 控制台(Console);
3: 帮助;
4: 历史;
5: 文件;
6: 图形;
7: 扩展包;
8: 已定义变量和函数;
9: 研究报告或网站结果显示。

运行程序

输入命令的前几个字母后用“Ctrl+向上光标键”可以匹配地查找历史命令。
运行.R结尾的R sceipt时点击窗口的“Run”快捷图标或者用快捷键“Ctrl+Enter键”可以运行这些行。

中文编码问题

在中国国内主要使用GB18030(基本兼容于GB, GBK)和UTF-8, UTF-8是国际上更普遍使用的统一文字编码, 涉及到计算机编程时应尽可能使用此编码系统。

RStdio提供了“File – Reopen with Encoding”命令, 我们主要试验其中GB18030和UTF-8两种选择一般就可以解决问题。 如果选择GB18030显示就没有乱码了, 最好再用菜单“File – Save with Encoding”并选择UTF-8将其保存为UTF-8编码。

2. R语言入门运行样例

练习

  1. 某人存入10000元1年期定期存款,年利率3%, 约定到期自动转存(包括利息)。问:

1.1 10年后本息共多少元?

sum <- 10000*(1+0.03)^10
sum

1.2 需要存多少年这10000元才能增值到20000元?

# 10000*(1+0.03)^x=20000
# (1+0.03)^x=2
year2 <- log(2,1.03)
year2
  1. 成语说:“智者千虑,必有一失;愚者千虑,必有一得”。 设智者作判断的准确率为p1=0.99, 愚者作判断的准确率为p2=0.01, 计算智者做1000次独立的判断至少犯一次错误的概率, 与愚者做1000次独立判断至少对一次的概率。
zhi <- 1-0.99^1000
yu <- 1-0.99^1000
zhi
yu

2.1 数学函数

数学函数

  • 平方根:sqrt() square root的缩写
  • 自然对数底数:exp(1)
  • 自然对数:log

2.2 输出

命令行的计算结果直接显示在命令的后面。 在用source()运行程序文件时, 需要用print()函数显示一个表达式的结果,如:

print(sin(pi/2))
## [1] 1

用cat()函数显示多项内容, 包括数值和文本, 文本包在两个单撇号或两个双撇号中,如:

cat("sin(pi/2)=", sin(pi/2), "\n")
## sin(pi/2)= 1

cat()函数最后一项一般是"\n", 表示换行。 忽略此项将不换行。

用sink()函数作运行记录

R使用经常是在命令行逐行输入命令(程序), 结果紧接着显示在命令后面。 如何保存这些命令和显示结果? 在R命令行中运行过的命令会被保存在运行的工作文件夹中的一个名为.Rhistory的文件中。 用sink()函数打开一个文本文件开始记录文本型输出结果。 结束记录时用空的sink()即可关闭文件不再记录。 如

sink("tmpres01.txt", split=TRUE)
print(sin(pi/6))
print(cos(pi/6))
cat("t(10)的双侧0.05分位数(临界值)=", qt(1 - 0.05/2, 10), "\n")
sink()

sink()用作输出记录主要是在测试运行中使用, 正常的输出应该使用cat()函数、write.table()、write.csv()等函数。

练习

用cat()函数显示

log10(2)=*** log10(5)=***
其中***应该代以实际函数值。

cat("log10(2)=",log10(2),"log10(5)=",log10(5))

用sink()函数开始把运行过程记录到文件“log001.txt”中,在命令行试验几个命令,然后关闭运行记录,查看生成的“log001.txt”的内容。

sink("log001.txt",split = TRUE)
sin(pi/6)
9/0.67
cat("log10(2)=",log10(2),"log10(5)=",log10(5))
sink()

2.3 向量计算与变量赋值

R语言以向量为最小单位。用<-赋值。如

x1 <- 1:10
x1
## [1] 1 2 3 4 5 6 7 8 9 10

一般的向量可以用c()生成, 如

marks <- c(3, 5, 10, 5, 6)

在程序语言中,变量用来保存输入的值或计算的结果。 变量可以存放各种不同类型的值, 如单个数值、多个数值(称为向量)、单个字符串、多个字符串(称为字符型向量),等等。 单个数值称为标量。

用程序设计语言的术语描述, R语言是动态类型的, 其变量的类型不需要预先声明, 运行过程中允许变量类型改变, 实际上变量赋值是一种“绑定”(binding), 将一个变量的名称(变量名)与实际的一个存储位置联系在一起。 在命令行定义的变量称为全局变量。

用print()函数显示向量或在命令行中显示向量时, 每行显示的行首会有方括号和数字序号, 代表该行显示的第一个向量元素的下标。如

1:80

向量可以和一个标量作四则运算, 结果是每个元素都和这个标量作四则运算,如:

x1 <- 1:10
x1 + 100

两个等长的向量可以进行四则运算, 相当于对应元素进行四则运算,如

x2 <- x1 * 3
cat("x2:",x2,"\n")
cat("x2-x1:",x2 - x1,"\n")
cat("x2*x1:",x2 * x1)

R的许多函数都可以用向量作为自变量, 结果是自变量的每个元素各自的函数值。 如

sqrt(x1)

结果是1到10的整数各自的平方根。

2.4 工作空间介绍

在命令行中定义的变量, 在退出R时,会提问是否保存工作空间, 初学时可选择保存, 真正用R进行数据分析时往往不保存工作空间。 再次启动R后, 能够看到以前定义的各个变量的值。

如果使用RStudio软件, 也需要把不同项目放在不同文件夹, 并且每个项目在RStudio中单独建立一个“项目”(project)。 要分析那个项目的数据, 就打开那个项目。 不同项目使用不同的工作空间。

RStudio中的“Environment”窗格会显示当前已定义的R变量与函数。

练习

  1. 某人存入10000元1年期定期存款,年利率3%, 约定到期自动转存(包括利息)。列出1、2、……、10年后的本息金额。
for x in range(1,11):
y=1000*(1.003)**x
print(y)
  1. 显示2的1,2,……, 20次方。
  2. 定义x1为1到10的向量,定义x2为x1的3倍,然后退出R,再次启动R,查看x1和x2的值。

2.5 绘图示例

2.5.1 函数曲线示例

如下程序用curve()函数制作函数的曲线图, curve()函数第二、第三自变量是绘图区间:

curve(x^2,-2,2)

类似地,函数曲线图用如下程序可制作, 用abline()函数添加参考线:

curve(sin(x), 0, 2*pi)
abline(h=0)

2.5.2 条形图示例

假设有10个男生,7个女生,如下程序绘制男生、女生人数的条形图:

barplot(c("男生"=10, "女生"=7), 
main="男女生人数")

2.5.3 散点图示例

下面的例子用plot()函数做了散点图, plot()函数第一个自变量是各个点的横坐标值, 第二个自变量是对应的纵坐标值。

plot(1:10,sqrt(1:10))

2.5.4 R软件自带的图形示例

R软件中自带了一些演示图形。通过如下程序可以调用:

demo("graphics")
demo("image")

画exp(x)在(-2,2)区间的函数图形。

plot(-2:2,exp(-2:2),main="自然对数底数")

画ln(x)在(0.01,10)区间的函数图形。

plot(0.01:10,log(0.01:10), main="ln",xlab = "横轴",ylab = "ln(0.01,10)")

2.6 汇总统计示例

2.6.1 表格数据

统计用的输入数据典型样式是Excel表那样的表格数据。 表格数据特点:每一列应该是相同的类型(或者都是数值, 或者都是文字,或者都是日期), 每一列应该有一个名字。

这样的表格数据,一般可以保存为.csv格式: 数据项之间用逗号分开,文件本身是文本型的, 可以用普通记事本程序查看和编辑。 Excel表可以用“另存为”命令保存为.csv格式。 常用的数据库管理系统一般也可以把表保存为.csv格式。

2.6.2 读入表格数据

tax.tab <- read.csv("taxsamp.csv", header = TRUE, as.is = TRUE)
print(head(tax.tab))
tax.tab <- read.csv("taxsamp.csv", header=TRUE, as.is=TRUE)
print(head(tax.tab))

出现错误:Error in make.names(col.names, unique = TRUE) : 多字节字符串1有错,只要加上编码方式就可以了。如下:

tax.tab <- read.csv("taxsamp.csv", header=TRUE, as.is=TRUE,sep = ",", encoding = "UTF-8")
print(head(tax.tab))

程序中的选项header=TRUE指明第一行作为变量名行, 选项as.is=TRUE说明字符型列要原样读入而不是转换为因子(factor)。 读入的变量tax.tab称为一个数据框(data.frame)。 head()函数返回数据框或向量的前几项。 比较大的表最好不要显示整个表, 会使得前面的运行过程难以查看。

变量可归结为名义型、有序型或连续型变量。

  • 名义型变量是没有顺序之分的类别变量。糖尿病类型Diabetes(Type1、Type2)是名义型变量的一例。即使在数据中Type1编码为1而Type2编码为2,这也并不意味着二者是有序的。
  • 有序型变量表示一种顺序关系,而非数量关系。病情Status(poor、improved、excellent)是顺序型变量的一个上佳示例。我们明 白,病情为poor(较差)病人的状态不如improved(病情好转)的病人,但并不知道相差多少。
  • 连续型变量可以呈现为某个范围内的任意值,并同时表示了顺序和数量。年龄Age就是一个连续型变量,它能够表示像14.5或22.8这样的值以及其间的其他任意值。

类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor)

2.6.3 分类变量频数统计

在tax.tab中, “征收方式”是一个分类变量。 用table()函数计算每个不同值的个数,称为频数(frequency):

table(tax.tab[["征收方式"]])
table(tax.tab[["申报渠道"]])

也可以用table()函数统计“征收方式”和“申报渠道”交叉分类频数,如:

table(tax.tab[["征收方式"]], tax.tab[["申报渠道"]])

绘制Markdown格式表格:

knitr::kable(table(tax.tab[["征收方式"]], tax.tab[["申报渠道"]]))
大厅申报 网上申报
查帐征收 9 20
定期定额征收 9 7
定期定率征收 0 2

2.6.4 数值型变量的统计

数值型变量可以计算各种不同的统计量, 如平均值、标准差和各个分位数。 summary()可以给出最小值、最大值、中位数、四分之一分位数、四分之三分位数和平均值。如

summary(tax.tab[["营业额"]])

统计函数以一个数值型向量为自变量, 包括sum(求和), mean(平均值), var(样本方差), sd(样本标准差), min(最小值), max(最大值), range(最小值和最大值)等。

如果数据中有缺失值, 可以删去缺失值后计算统计量, 这时在mean, sd等函数中加入na.rm=TRUE选项。

练习
用如下程序定义一个变量x, 然后求x的平均值和最小值、最大值。

x <- c(3, 5, 10, 5, 6)
# 平均值
mean(x)
# 最大值
max(x)

2.7 运行源程序文件

用source()函数可以运行保存在一个文本文件中的源程序。 比如,如下内容保存在文件ssq.r中:

sum.of.squares <- function(x){
sum(x^2)
}

用如下source()命令运行:

source("ssq.r")

运行后就可以调用自定义函数sum.of.squares()了。

2.7.1 源文件编码

对于源程序编码与系统默认编码不同的情况, 保存为UTF-8编码的源程序在简体中文MS Windows系统的R中运行, 可以在source()函数中可以添加encoding="UTF-8"选项。 保存为GBK编码的源程序文件在MAC系统的R中运行, 可以在source()函数中可以添加encoding="GBK"选项。

getwd(): 获取当前工作目录
setwd(): 设置当前的工作目录

  • 使用RStudio软件时, 将某个研究项目所有数据和程序放在某个文件夹中, 然后建立一个新项目(project)指向该文件夹。

  • 文件路径写法:setwd("d:/work")setwd("d:\\work")

练习

编辑生成ssq.r源程序文件并用source()函数运行, 然后计算:
sum.of.squares(1:5)

# 即为sum(x^2)的值
source("ssq.r")
sum.of.squares(1:5)

reference:

R语言教程