R语言学习笔记(一)

文章内容非原创,来源于课本和网络,仅供学习交流使用

什么是R语言

来源于维基百科

R 语言是为数学研究工作者设计的一种数学编程语言,主要用于统计分析、绘图、数据挖掘。

如果你是一个计算机程序的初学者并且急切地想了解计算机的通用编程,R 语言不是一个很理想的选择,可以选择 Python、C 或 Java。

R 语言与 C 语言都是贝尔实验室的研究成果,但两者有不同的侧重领域,R 语言是一种解释型的面向数学理论研究工作者的语言,而 C 语言是为计算机软件工程师设计的。

R 语言是解释运行的语言(与 C 语言的编译运行不同),它的执行速度比 C 语言慢得多,不利于优化。但它在语法层面提供了更加丰富的数据结构操作并且能够十分方便地输出文字和图形信息,所以它广泛应用于数学尤其是统计学领域。

R由新西兰奥克兰大学的统计学家罗斯·伊哈卡和罗伯特·杰特曼开发,现在由R核心小组负责开发,同时也有其他用户编写了诸多外挂的软件包。R以S语言为基础,其词法作用域语义来自Scheme。R的后台程序大多由C语言、FORTRAN语言和R自己写成。

R语言是GNU计划的一个项目,所以其源代码可自由下载使用。R也有已编译的可执行文件版本可以下载,可在多种平台下运行,包括UNIX(也包括FreeBSD和Linux)、Windows和MacOS。R可以以命令行操作,同时有人开发了几种图形用户界面,其中包括RStudio与Jupyter。

在TIOBE2022年1月对编程语言人气的排名中,R排名第12。

发展历程

R语言以S语言为基础,增加了Scheme语言中词法作用域这一机制,使程序员得以将代码中某一对象的适用范围限制到一小段代码之中。S由里克·贝克尔、约翰·钱伯斯、道格·邓恩、琼·麦克雷、以及朱迪·席林于1976年前后于贝尔实验室发明。S是一种用于数据分析的解释型语言,无需编译器即可运行。通常用S语言编写的代码都可以不作修改地在R环境下运行。Scheme是Lisp语言的一个分支,由杰拉尔德·J·萨斯曼和小盖伊·L·斯蒂尔于1975年前后在麻省理工学院发明。

1991年,新西兰奥克兰大学的统计学家罗斯·伊哈卡和罗伯特·杰特曼开始对S语言的一个新版本进行开发。伊哈卡与杰特曼两人名前缀字母都是R,R语言因此得名。同时,R这个单一字母的名字也表明R语言与S语言一脉相承。1993年8月,伊哈卡与杰特曼在数据平台StatLib和邮件列表s-news中发布了R的早期版本。1995年,在统计学家马丁·梅克勒的建议下,伊哈卡与杰特曼通过GNU通用公共许可证把R做成了一款免费开源软件。软件于1995年6月进行了首次官方发布。首个稳定测试版本(1.0)于2000年2月29日发布。

R综合文件网(Comprehensive R Archive Network;CRAN)于1997年4月23日正式上线。CRAN除了收藏了R的可执行文件下载版、源代码和帮助文档,也收录了各种用户撰写的R软件包。CRAN最早有3个镜像以及12个软件包。截止2022年1月,CRAN有101个镜像站以及18728个软件包。

同样在1997年,R核心小组正式成立,以进一步对R语言进行开发。截止2022年1月,小组成员包括伊哈卡、杰特曼、钱伯斯以及梅克勒,同时也包括了统计学家库尔特·奥尔尼克、道格拉斯·贝茨、彼得·达尔高、卢克·蒂尔尼、弗里德里希·莱施、托马斯·拉姆利、邓肯·坦普尔·朗、迈克尔·劳伦斯、乌韦·利格斯、布莱恩·里普利、塞巴斯蒂安·迈耶、保罗·默雷尔、马丁·普卢默、迪伊潘·萨卡尔、西蒙·乌尔巴内克以及计算机科学家托马斯·卡利贝拉。小组过去的成员包括塞思·福尔肯、圭多·马萨罗托、邓肯·默多克、马丁·摩根、海纳·施瓦特以及斯特凡诺·雅各斯。2003年4月,一个名为R基金会的非盈利组织正式成立,为的是更好地对R语言的开发提供支持。

内置功能

R主要用于数据分析。在R语言中,用于信息存储的数据结构包括向量、数组、列表以及数据框。向量指一组带有固定顺序, 数据类型唯一的字符串或数值,其内容可以填写到一维或多维的数组之中。二维数组也叫做矩阵。R支持各种数组运算,与自由软件GNU Octave和商业软件MATLAB的功能有所重叠。列表指一组数据类型可能有所不同的对象。一个字符串向量与数值向量合在一起就可以成为一个列表。数据框本质上是一个列表,里面包含了一个或多个长度相同的向量。数据框将这些向量合并成表格,每一行都有一个单一的名称。标量这一数据类型在R语言中并不存在,所谓的标量就是一个长度为一的向量。

用户可以用R来进行一些基本的统计检验,构建线性及非线性的模型,对时间序列加以分析,或对数据进行分类与聚类分析。R的另一强项是绘图功能,画出的图表能够达到专业出版物的要求,也可加入数学符号。计算强度较大时,用户可在程序中嵌入C、C++以及FORTRAN语言以帮助运算。

因为S的血缘,R比其他统计学或数学专用的编程语言有更强的面向对象(面向对象程序设计, S3, S4等)功能。

R基础语法

R 语言的有效的变量名称由字母,数字以及点号 . 或下划线 _ 组成。

变量名称以字母或点开头。

变量名 是否正确 原因
var_name2. 正确 字符开头,并由字母、数字、下划线和点号组成
var_name% 错误 % 是非法字符
2var_name 错误 不能数字开头
.var_name, var.name 正确 可以 . 号开头,但是要注意 . 号开头后面不能跟着数字
.2var_name 错误 . 号开头后面不能跟着数字
_var_name 错误 不能以下划线 _ 开头

最新版本的 R 语言的赋值可以使用左箭头 <-、等号 = 、右箭头 -> 赋值:

print() 是 R 语言的输出函数,和其他编程语言一样,R 语言支持数字、字符等输出。

输出的语句十分简单:

print("RUNOOB")

R 语言与 node.js 和 Python 一样,是解释型的语言,所以我们往往可以像使用命令行一样使用 R 语言。

如果我们在一行上进输入一个值,那么 R 也会把它直接标准化输出:

> 5e-2 [1] 0.05

如果需要输出结果的拼接,我们可以使用 cat() 函数:
实例
> cat(1, "加", 1, "等于", 2, '\n') 1 加 1 等于 2

cat() 函数会在每两个拼接元素之间自动加上空格。
输出内容到文件

R 语言输出到文件的方法十分多样,而且很方便。

cat() 函数支持直接输出结果到文件:

cat("RUNOOB", file="/Users/runoob/runoob-test/r_test.txt")

这个语句不会在控制台产生结果,而是把 "RUNOOB" 输出到 "/Users/runoob/runoob-test/r_test.txt" 文件中去。

file 参数可以是绝对路径或相对路径,建议使用绝对路径,Windows 路径格式为 D:\r_test.txt。

cat("RUNOOB", file="D:\\r_test.txt")

注意:这个操作是"覆盖写入"操作,请谨慎使用,因为它会将输出文件的原有数据清除。如果想"追加写入",请不要忘记设置 append 参数:

cat("GOOGLE", file="/Users/runoob/runoob-test/r_test.txt", append=TRUE)

sink() 函数可以把控制台输出的文字直接输出到文件中去:

sink("/Users/runoob/runoob-test/r_test.txt")

这条语句执行以后,任何控制台上的输出都会被写入到 "/Users/runoob/runoob-test/r_test.txt" 文件中去,控制台将不会显示输出。

注意:这个操作也是"覆盖写入"操作,会直接清除原有的文件内容。

如果我们依然像保留控制台的输出,可以设置 split 属性:

sink("/Users/runoob/runoob-test/r_test.txt", split=TRUE)

如果想取消输出到文件,可以调用无参数的 sink()

可能我们会联想到 C 语言中的 scanf 、Java 中的 java.util.Scanner,如果你学习过 Python 可能对 input() 函数更熟悉。但是 R 语言本身作为一种解释型的语言,更类似于一些终端脚本语言(比如 bash 或者 PowerShell),这些语言是基于命令系统的,本身就需要输入和输出且不适合开发面向用户的应用程序(因为他们本身就是给最终用户使用的)。因此 R 语言没有专门再从控制台读取的函数,文字输入在 R 的使用中一直在进行。

R 语言中有丰富的文件读取函数,但是如果纯粹的想将某个文件中的内容读取为字符串,可以使用 readLines 函数:

readLines("/Users/runoob/runoob-test/r_test.txt")

读取结果是两个字符串,分别是所读取的文件包含的两行内容。

注意:所读取的文本文件每一行 (包括最后一行) 的结束必须有换行符,否则会报错。

除了文字的简单输入输出以外,R 还提供了很多输入数据和输出数据的方法,R 语言最方便的地方就是可以将数据结构直接保存到文件中去,而且支持保存为 CSV、Excel 表格等形式,并且支持直接地读取。这对于数学研究者来说无疑是非常方便的。但是这些功能对于 R 语言的学习影响不大,我们将在之后的章节提到。

对于文件操作,我们需要设置文件的路径,R 语言可以通过以下两个行数来获取和设置当前的工作目录:

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

注释主要用于一段代码的解析,可以让阅读者更易理解,编程语言的注释会被编译器忽略掉,且不会影响代码的执行。

一般编程语言的注释分为单行注释与多行注释,但是 R 语言只支持单行注释,注释符号为 #。

其实如果有多行注释我们只需要在每一行添加 # 号就好了。

# 这是我的第一个编程代码

数据类型
image

函数定义通常由以下几个部分组成:

函数名: 为函数指定一个唯一的名称,以便在调用时使用。
参数: 定义函数接受的输入值。参数是可选的,可以有多个。
函数体: 包含实际执行的代码块,用大括号 {} 括起来。
返回值: 指定函数的输出结果,使用关键字return。

R 语言中的函数定义使用 function 关键字,一般形式如下:

function_name <- function(arg_1, arg_2, ...) {
	# 函数体
	# 执行的代码块
	return(output)
}

说明:

function_name : 为函数名
arg_1, arg_2, ... : 形式参数列表 

函数返回值使用 return()。

带有参数值的函数

函数参数,可以按函数创建时的顺序来传递,也可以不按顺序,但需要指定参数名:

new.function <- function(a,b,c) {
   result <- a * b + c
   print(result)
}

函数创建时也可以为参数指定默认值,如果调用的时候不传递参数就会使用默认值:

new.function <- function(a = 3, b = 6) {
   result <- a * b
   print(result)
}

懒惰计算将推迟计算工作直到系统需要这些计算的结果。如果不需要结果,将不用进行计算。

默认情况下,R 函数对参数的计算是懒惰的,就是只有我们在计算它的时候才会调用:

f <- function(x) {
  10
}
f()

以上代码执行,并没有报错,虽然我们没有传入参数,但函数体内没有使用参数 x,所以不会去调用它,也不会报错。

R 语言提供了很多有用的内置函数,我们无需定义它就可以直接使用。

sum(): 计算向量或矩阵的总和。

mean(): 计算向量或矩阵的平均值。

paste(): 将多个字符串连接成一个字符串。

length(): 返回向量的长度或对象的元素个数。

str(): 显示对象的结构和内容摘要。

以上只列举了一小部分的 R 语言函数实例,R 有大量的内置函数和扩展包提供的函数,可以满足各种数据处理、统计分析、绘图等需求。

列表是 R 语言的对象集合,可以用来保存不同类型的数据,可以是数字、字符串、向量、另一个列表、矩阵、数据框等,当然还可以包含矩阵和函数。列表是一种灵活的数据结构,可以存储和操作多种类型的数据对象,R 语言创建列表使用 list() 函数。

list_data <- list("runoob", "google", c(11,22,33), 123, 51.23, 119.1)
print(list_data)

R 语言为线性代数的研究提供了矩阵类型,这种数据结构很类似于其它语言中的二维数组,但 R 提供了语言级的矩阵运算支持。矩阵里的元素可以是数字、符号或数学式。一个 M x N 的矩阵是一个由 M(row) 行 和 N 列(column)元素排列成的矩形阵列。

image

R 语言的矩阵可以使用 matrix() 函数来创建,语法格式如下:

matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE,dimnames = NULL)

参数说明:

data 向量,矩阵的数据
nrow 行数
ncol 列数
byrow 逻辑值,为 FALSE 按列排列,为 TRUE 按行排列
dimname 设置行和列的名称

R 语言矩阵提供了 t() 函数,可以实现矩阵的行列互换。例如有个 m 行 n 列的矩阵,使用 t() 函数就能转换为 n 行 m 列的矩阵。

如果想获取矩阵元素,可以通过使用元素的列索引和行索引,类似坐标形式。

# 定义行和列的名称
rownames = c("row1", "row2", "row3", "row4")
colnames = c("col1", "col2", "col3")

# 创建矩阵
P <- matrix(c(3:14), nrow = 4, byrow = TRUE, dimnames = list(rownames, colnames))
print(P)
# 获取第一行第三列的元素
print(P[1,3])

# 获取第四行第二列的元素
print(P[4,2])

# 获取第二行
print(P[2,])

# 获取第三列
print(P[,3])

执行以上代码输出结果为:

col1 col2 col3
row1    3    4    5
row2    6    7    8
row3    9   10   11
row4   12   13   14
[1] 5
[1] 13
col1 col2 col3 
6    7    8 
row1 row2 row3 row4 
5    8   11   14 

大小相同(行数列数都相同)的矩阵之间可以相互加减,具体是对每个位置上的元素做加减法。矩阵的乘法则较为复杂。两个矩阵可以相乘,当且仅当第一个矩阵的列数等于第二个矩阵的行数。

# 创建 2 行 3 列的矩阵
matrix1 <- matrix(c(7, 9, -1, 4, 2, 3), nrow = 2)
print(matrix1)

matrix2 <- matrix(c(6, 1, 0, 9, 3, 2), nrow = 2)
print(matrix2)

# 两个矩阵相加
result <- matrix1 + matrix2
cat("相加结果:","\n")
print(result)

# 两个矩阵相减
result <- matrix1 - matrix2
cat("相减结果:","\n")
print(result)

执行以上代码输出结果为:

[,1] [,2] [,3]
[1,]    7   -1    2
[2,]    9    4    3
	 [,1] [,2] [,3]
[1,]    6    0    3
[2,]    1    9    2
相加结果: 
	 [,1] [,2] [,3]
[1,]   13   -1    5
[2,]   10   13    5
相减结果: 
	 [,1] [,2] [,3]
[1,]    1   -1   -1
[2,]    8   -5    1

矩阵乘除法

# 创建 2 行 3 列的矩阵
matrix1 <- matrix(c(7, 9, -1, 4, 2, 3), nrow = 2)
print(matrix1)

matrix2 <- matrix(c(6, 1, 0, 9, 3, 2), nrow = 2)
print(matrix2)

# 两个矩阵相乘
result <- matrix1 * matrix2
cat("相乘结果:","\n")
print(result)

# 两个矩阵相除
result <- matrix1 / matrix2
cat("相除结果:","\n")
print(result)

执行以上代码输出结果为:

[,1] [,2] [,3]
[1,]    7   -1    2
[2,]    9    4    3
	 [,1] [,2] [,3]
[1,]    6    0    3
[2,]    1    9    2
相乘结果: 
	 [,1] [,2] [,3]
[1,]   42    0    6
[2,]    9   36    6
相除结果: 
 [,1]           [,2]        [,3]
[1,] 1.166667     -Inf   0.6666667
[2,] 9.000000 0.4444444 1.5000000

数组也是 R 语言的对象,R 语言可以创建一维或多维数组。R 语言数组是一个同一类型的集合,前面我们学的矩阵 matrix 其实就是一个二维数组。
image

R 语言数组创建使用 array() 函数,该函数使用向量作为输入参数,可以使用 dim 设置数组维度。

array(data = NA, dim = length(data), dimnames = NULL)

参数说明:

data - 指定数组的数据源,可以是一个向量、矩阵或列表。
dim - 指定数组的维度,可以是一个整数向量或一个表示维度的元组,默认是一维数组。例如,dim = c(2, 3, 4) 表示创建一个 2x3x4 的三维数组。
dimnames - 可选参数,用于指定数组每个维度的名称,可以是一个包含维度名称的列表。

在 R 中,数组索引是从 1 开始的,与其他编程语言的习惯有所不同。此外,R 还提供了丰富的函数和操作符用于处理数组数据,如索引、切片、重塑、聚合等。在 R 中,可以使用矩阵(Matrix)或列表(List)来表示多维数组。

矩阵(Matrix):矩阵是 R 中最常用的表示数组的形式,它是一个二维的结构,具有固定的行数和列数。可以使用 matrix() 函数创建矩阵,指定数据元素和维度。

列表(List):列表是 R 中更通用的多维数组形式,它可以包含不同类型的元素,并且每个元素可以是一个矩阵、向量或其他数据结构。

因子用于存储不同类别的数据类型,例如人的性别有男和女两个类别,年龄来分可以有未成年人和成年人。R 语言创建因子使用 factor() 函数,向量作为输入参数。

factor(x = character(), levels, labels = levels,
	   exclude = NA, ordered = is.ordered(x), nmax = NA)

参数说明:

x:向量。
levels:指定各水平值, 不指定时由x的不同值来求得。
labels:水平的标签, 不指定时用各水平值的对应字符串。
exclude:排除的字符。
ordered:逻辑值,用于指定水平是否有序。
nmax:水平的上限数量。 

以下实例把字符型向量转换成因子:

x <- c("男", "女", "男", "男",  "女")
sex <- factor(x)
print(sex)
print(is.factor(sex))

执行以上代码输出结果为:

[1] 男 女 男 男 女
Levels: 男 女
[1] TRUE

使用 labels 参数为每个因子水平添加标签,labels 参数的字符顺序,要和 levels 参数的字符顺序保持一致,

sex=factor(c('f','m','f','f','m'),levels=c('f','m'),labels=c('female','male'),ordered=TRUE)
print(sex)

执行以上代码输出结果为:

[1] female male   female female male  
Levels: female < male

我们可以使用 gl() 函数来生成因子水平,语法格式如下:

gl(n, k, length = n*k, labels = seq_len(n), ordered = FALSE)

n: 设置 level 的个数
k: 设置每个 level 重复的次数
length: 设置长度
labels: 设置 level 的值
ordered: 设置是否 level 是排列好顺序的,布尔值。

v <- gl(3, 4, labels = c("Google", "Runoob","Taobao"))
print(v)

 [1] Google Google Google Google Runoob Runoob Runoob Runoob Taobao Taobao
[11] Taobao Taobao
Levels: Google Runoob Taobao

数据框(Data frame)可以理解成我们常说的"表格"。数据框是 R 语言的数据结构,是特殊的二维列表。数据框每一列都有一个唯一的列名,长度都是相等的,同一列的数据类型需要一致,不同列的数据类型可以不一样。

image

R 语言数据框使用 data.frame() 函数来创建,语法格式如下:

data.frame(…, row.names = NULL, check.rows = FALSE,
		   check.names = TRUE, fix.empty.names = TRUE,
		   stringsAsFactors = default.stringsAsFactors())

…: 列向量,可以是任何类型(字符型、数值型、逻辑型),一般以 tag = value 的形式表示,也可以是 value。
row.names: 行名,默认为 NULL,可以设置为单个数字、字符串或字符串和数字的向量。
check.rows: 检测行的名称和长度是否一致。
check.names: 检测数据框的变量名是否合法。
fix.empty.names: 设置未命名的参数是否自动设置名字。
stringsAsFactors: 布尔值,字符是否转换为因子,factory-fresh 的默认值是 TRUE,可以通过设置选项(stringsAsFactors=FALSE)来修改。

以下创建一个简单的数据框,包含姓名、工号、月薪:

table = data.frame(
	姓名 = c("张三", "李四"),
	工号 = c("001","002"),
	月薪 = c(1000, 2000)

)
print(table) # 查看 table 数据

执行以上代码输出结果为:

姓名 工号 月薪
1 张三  001 1000
2 李四  002 2000

数据框的数据结构可以通过 str() 函数来展示:

table = data.frame(
	姓名 = c("张三", "李四"),
	工号 = c("001","002"),
	月薪 = c(1000, 2000)
)
# 获取数据结构
str(table)

执行以上代码输出结果为:

'data.frame':   2 obs. of  3 variables:
 $ 姓名: chr  "张三" "李四"
 $ 工号: chr  "001" "002"
 $ 月薪: num  1000 2000

summary() 可以显示数据框的概要信息:

table = data.frame(
	姓名 = c("张三", "李四"),
	工号 = c("001","002"),
	月薪 = c(1000, 2000)

)
# 显示概要
print(summary(table))  

执行以上代码输出结果为:

姓名               工号                月薪     
Length:2           Length:2           Min.   :1000  
Class :character   Class :character   1st Qu.:1250  
Mode  :character   Mode  :character   Median :1500  
									  Mean   :1500  
									  3rd Qu.:1750  
									  Max.   :2000  

我们也可以提取指定的列:

table = data.frame(
	姓名 = c("张三", "李四"),
	工号 = c("001","002"),
	月薪 = c(1000, 2000)
)
# 提取指定的列
result <- data.frame(table$姓名,table$月薪)
print(result)

执行以上代码输出结果为:

table.姓名 table.月薪
1       张三       1000
2       李四       2000

以下形式显示前面两行:

table = data.frame(
	姓名 = c("张三", "李四","王五"),
	工号 = c("001","002","003"),
	月薪 = c(1000, 2000,3000)
)
print(table)
# 提取前面两行
print("---输出前面两行----")
result <- table[1:2,]
print(result)

执行以上代码输出结果为:

姓名 工号 月薪
1 张三  001 1000
2 李四  002 2000
3 王五  003 3000
[1] "---输出前面两行----"
  姓名 工号 月薪
1 张三  001 1000
2 李四  002 2000

我们可以通过类似坐标的形式读取指定行的某一列的数据,以下我们读取第 2 、3 行的第 1 、2 列数据:

table = data.frame(
	姓名 = c("张三", "李四","王五"),
	工号 = c("001","002","003"),
	月薪 = c(1000, 2000,3000)
)
# 读取第 23 行的第 12 列数据:
result <- table[c(2,3),c(1,2)]
print(result)

执行以上代码输出结果为:

姓名 工号
2 李四  002
3 王五  003

可以对已有的数据框进行扩展,以下实例我们添加部门列:

table = data.frame(
	姓名 = c("张三", "李四","王五"),
	工号 = c("001","002","003"),
	月薪 = c(1000, 2000,3000)
)
# 添加部门列
table$部门 <- c("运营","技术","编辑")

print(table)

执行以上代码输出结果为:

姓名 工号 月薪 部门
1 张三  001 1000 运营
2 李四  002 2000 技术
3 王五  003 3000 编辑

我们可以使用 cbind() 函数将多个向量合成一个数据框:

# 创建向量
sites <- c("Google","Runoob","Taobao")
likes <- c(222,111,123)
url <- c("www.google.com","www.runoob.com","www.taobao.com")

# 将向量组合成数据框
addresses <- cbind(sites,likes,url)

# 查看数据框
print(addresses)

执行以上代码输出结果为:

	 sites    likes url             
[1,] "Google" "222" "www.google.com"
[2,] "Runoob" "111" "www.runoob.com"
[3,] "Taobao" "123" "www.taobao.com"

如果要对两个数据框进行合并可以使用 rbind() 函数:

table = data.frame(
	姓名 = c("张三", "李四","王五"),
	工号 = c("001","002","003"),
	月薪 = c(1000, 2000,3000)
)
newtable = data.frame(
	姓名 = c("小明", "小白"),
	工号 = c("101","102"),
	月薪 = c(5000, 7000)
)
# 合并两个数据框
result <- rbind(table,newtable)
print(result)

执行以上代码输出结果为:

姓名 工号 月薪
1 张三  001 1000
2 李四  002 2000
3 王五  003 3000
4 小明  101 5000
5 小白  102 7000

R 语言合并数据框使用 merge() 函数。

# S3 方法
merge(x, y,)

# data.frame 的 S3 方法 
merge(x, y, by = intersect(names(x), names(y)),
	  by.x = by, by.y = by, all = FALSE, all.x = all, all.y = all,
	  sort = TRUE, suffixes = c(".x",".y"), no.dups = TRUE,
	  incomparables = NULL,)

常用参数说明:

x, y: 数据框
by, by.x, by.y:指定两个数据框中匹配列名称,默认情况下使用两个数据框中相同列名称。
all:逻辑值; all = L 是 all.x = L 和 all.y = L 的简写,L 可以是 TRUEFALSEall.x:逻辑值,默认为 FALSE。如果为 TRUE, 显示 x 中匹配的行,即便 y 中没有对应匹配的行,y 中没有匹配的行用 NA 来表示。
all.y:逻辑值,默认为 FALSE。如果为 TRUE, 显示 y 中匹配的行,即便 x 中没有对应匹配的行,x 中没有匹配的行用 NA 来表示。
sort:逻辑值,是否对列进行排序。

merge() 函数和 SQL 的 JOIN 功能很相似:
image

Natural joinINNER JOIN:如果表中有至少一个匹配,则返回行
Left outer joinLEFT JOIN:即使右表中没有匹配,也从左表返回所有的行
Right outer joinRIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行
Full outer joinFULL JOIN:只要其中一个表中存在匹配,则返回行

R 语言使用 melt() 和 cast() 函数来对数据进行整合和拆分。

melt() :宽格式数据转化成长格式。
cast() :长格式数据转化成宽格式。

下图很好展示来 melt() 和 cast() 函数的功能(后面实例会详细说明):
image
melt() 将数据集的每个列堆叠到一个列中,函数语法格式:

melt(data, ..., na.rm = FALSE, value.name = "value")

参数说明:

data:数据集。
...:传递给其他方法或来自其他方法的其他参数。
na.rm:是否删除数据集中的 NA 值。
value.name 变量名称,用于存储值。

cast 函数用于对合并对数据框进行还原,dcast() 返回数据框,acast() 返回一个向量/矩阵/数组。

cast() 函数语法格式:

dcast(
  data,
  formula,
  fun.aggregate = NULL,
  ...,
  margins = NULL,
  subset = NULL,
  fill = NULL,
  drop = TRUE,
  value.var = guess_value(data)
)
acast(
  data,
  formula,
  fun.aggregate = NULL,
  ...,
  margins = NULL,
  subset = NULL,
  fill = NULL,
  drop = TRUE,
  value.var = guess_value(data)
)

参数说明:

data:合并的数据框。
formula:重塑的数据的格式,类似 x ~ y 格式,x 为行标签,y 为列标签 。
fun.aggregate:聚合函数,用于对 value 值进行处理。
margins:变量名称的向量(可以包含"grand\_col""grand\_row"),用于计算边距,设置 TURE 计算所有边距。
subset:对结果进行条件筛选,格式类似 subset = .(variable=="length")。
drop:是否保留默认值。
value.var:后面跟要处理的字段。

包是 R 函数、实例数据、预编译代码的集合,包括 R 程序,注释文档、实例、测试数据等。

R 语言相关的包一般存储安装目录下对 "library" 目录,默认情况在 R 语言安装完成已经自带来一些常用对包,当然我们也可以在后期自定义添加一些要使用的包。

R 语言完整的相关包可以查阅:https://cran.r-project.org/web/packages/available_packages_by_name.html

接下来我们主要介绍如何安装 R 语言的包。我们可以使用以下函数来查看 R 包的安装目录:

> .libPaths()
[1] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library"
>
查看已安装的包

我们可以使用以下函数来查看已安装的包:

library()

我们可以使用以下函数来查看编译环境已载入的包:

> search()
[1] ".GlobalEnv"        "package:stats"     "package:graphics"
[4] "package:grDevices" "package:utils"     "package:datasets"
[7] "package:methods"   "Autoloads"         "package:base"  
安装新包

安装新包可以使用 install.packages() 函数,格式如下:

install.packages("要安装的包名")

我们可以直接设置包名,从 CRAN 网站上获取包,如下实例我们载入 XML 包:

# 安装 XML 包
install.packages("XML")

或者我们可以直接在 CRAN 上下载相关包,直接在本地安装:

install.packages("./XML_3.98-1.3.zip")

我们国内一般建议大家使用国内镜像,以下实例使用中国科学技术大学源进行安装:

# 安装 XML 包
install.packages("XML", repos = "https://mirrors.ustc.edu.cn/CRAN/")

新安装的包需要先载入 R 编译环境中才可以使用,格式如下:

library("包名")

以下实例载入 XML 包:

library("XML")

R 作为统计学专业工具,如果只能人工的导入和导出数据将使其功能变得没有意义,所以 R 支持批量的从主流的表格存储格式文件(例如 CSV、Excel、XML 等)中获取数据。

CSV(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号) 是一种非常流行的表格存储文件格式,这种格式适合储存中型或小型数据规模的数据。由于大多数软件支持这个文件格式,所以常用于数据的储存与交互。CSV 本质是文本,它的文件格式极度简单:数据一行一行的用文本保存起来而已,每条记录被分隔符分隔为字段,每条记录都有同样的字段序列。

以下是一个简单的 sites.csv 文件(存储在测试程序的相同目录下):

id,name,url,likes
1,Google,www.google.com,111
2,Runoob,www.runoob.com,222
3,Taobao,www.taobao.com,333

CSV 用逗号来分割列,如果数据中含有逗号,就要用双引号将整个数据块包括起来。
注意:包含非英文字符的文本要注意保存的编码,由于很多计算机普遍使用 UTF-8 编码,所以我是用 UTF-8 进行保存的。
注意: CSV 文件最后一行需要保留一个空行,不然执行程序会有警告信息。

Warning message:
In read.table(file = file, header = header, sep = sep, quote = quote,  :
  incomplete final line found by readTableHeader on 'sites.csv'

接下来我们就可以使用 read.csv() 函数来读取 CSV 文件的数据:

data <- read.csv("sites.csv", encoding="UTF-8")
print(data)

如果不设置 encoding 属性,read.csv 函数将默认以操作系统默认的文字编码进行读取,如果你使用的是 Windows 中文版系统且没有设置过系统的默认编码,那系统的默认编码应该是 GBK。所以大家请尽可能地统一文字编码以防出错。

执行以上代码输出结果为:

  id   name            url likes
1  1 Google www.google.com   111
2  2 Runoob www.runoob.com   222
3  3 Taobao www.taobao.com   333

read.csv() 函数返回的是数据框,我们可以很方便的对数据进行统计处理,以下实例我们查看行数和列数:

data <- read.csv("sites.csv", encoding="UTF-8")

print(is.data.frame(data))  # 查看是否是数据框
print(ncol(data))  # 列数
print(nrow(data))  # 行数

执行以上代码输出结果为:

[1] TRUE
[1] 4
[1] 3

以下统计数据框中 likes 字段最大对数据:

data <- read.csv("sites.csv", encoding="UTF-8")

# likes 最大的数据
like <- max(data$likes)
print(like)

执行以上代码输出结果为:

[1] 333

我们也可以指定查找条件,类似 SQL where 子句一样查询数据,需要用到到函数是 subset()。

以下实例查找 likes 为 222 到数据:

data <- read.csv("sites.csv", encoding="UTF-8")

# likes 为 222 的数据
retval <- subset(data, likes == 222)
print(retval)

执行以上代码输出结果为:

  id   name            url likes
2  2 Runoob www.runoob.com   222

注意:条件语句等于使用 ==。
多个条件使用 & 分隔符,以下实例查找 likes 大于 1 name 为 Runoob 的数据:

data <- read.csv("sites.csv", encoding="UTF-8")

# likes 大于 1 name 为 Runoob 的数据
retval <- subset(data, likes > 1 & name=="Runoob")
print(retval)

执行以上代码输出结果为:

  id   name            url likes
2  2 Runoob www.runoob.com   222

R 语言可以使用 write.csv() 函数将数据保存为 CSV 文件。

Excel 格式的文件主要是 xls 或 xlsx,这两种文件可以在 R 语言中导入 xlsx 库来实现直接的读取。R 语言读写 Excel 文件需要安装扩展包,我们可以在 R 到控制台输入以下命令来安装:

install.packages("xlsx", repos = "https://mirrors.ustc.edu.cn/CRAN/")

事实上,几乎所有的 Excel 软件与大多数表格软件一样支持 CSV 格式的数据,所以完全可以通过 CSV 与 R 交互,没必要再使用 Excel。
查看 xlsx 是否安装成功:

any(grepl("xlsx",installed.packages()))

XML 指的是可扩展标记语言(eXtensible Markup Language),XML 被设计用来传输和存储数据。R 语言读写 XML 文件需要安装扩展包,我们可以在 R 到控制台输入以下命令来安装:

install.packages("XML", repos = "https://mirrors.ustc.edu.cn/CRAN/")

查看是否安装成功:

> any(grepl("XML",installed.packages()))
[1] TRUE

JSON: JavaScript Object Notation(JavaScript 对象表示法)是存储和交换文本信息的语法。JSON 类似 XML,但比 XML 更小、更快,更易解析。R 语言读写 JSON 文件需要安装扩展包,我们可以在 R 到控制台输入以下命令来安装:

install.packages("rjson", repos = "https://mirrors.ustc.edu.cn/CRAN/")

查看是否安装成功:

> any(grepl("rjson",installed.packages()))
[1] TRUE

MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。R 语言读写 MySQL 文件需要安装扩展包,我们可以在 R 到控制台输入以下命令来安装:

install.packages("RMySQL", repos = "https://mirrors.ustc.edu.cn/CRAN/")

查看是否安装成功:

> any(grepl("RMySQL",installed.packages()))
[1] TRUE

MySQL 目前被甲骨文收购,所以很多人使用来它的复制版本 MariaDB,MariaDB 在 GNU GPL下开源,MariaDB 的开发是由 MySQL 的一些原始开发者领导的,所以语法操作都差不多:

install.packages("RMariaDB", repos = "https://mirrors.ustc.edu.cn/CRAN/")

饼图,或称饼状图,是一个划分为几个扇形的圆形统计图表,用于描述量、频率或百分比之间的相对关系。
R 语言使用 pie() 函数来实现饼图,语法格式如下:

pie(x, labels = names(x), edges = 200, radius = 0.8,
	clockwise = FALSE, init.angle = if(clockwise) 90 else 0,
	density = NULL, angle = 45, col = NULL, border = NULL,
	lty = NULL, main = NULL, …)

x: 数值向量,表示每个扇形的面积。
labels: 字符型向量,表示各扇形面积标签。
edges: 这个参数用处不大,指的是多边形的边数(圆的轮廓类似很多边的多边形)。
radius: 饼图的半径。
main: 饼图的标题。
clockwise: 是一个逻辑值,用来指示饼图各个切片是否按顺时针做出分割。
angle: 设置底纹的斜率。
density: 底纹的密度。默认值为 NULL
col: 是表示每个扇形的颜色,相当于调色板。

条形图,也称为柱状图条形图,是一种以长方形的长度为变量的统计图表。条形图可以是水平或垂直的,每个长方形可以有不同的颜色。R 语言使用 barplot() 函数来创建条形图,格式如下:

barplot(H,xlab,ylab,main, names.arg,col,beside)

H 向量或矩阵,包含图表用的数字值,每个数值表示矩形条的高度。
xlab x 轴标签。
ylab y 轴标签。
main 图表标题。
names.arg 每个矩形条的名称。
col 每个矩形条的颜色。

R 中 curve() 函数可以绘制函数的图像,代码格式如下:

curve(expr, from = NULL, to = NULL, n = 101, add = FALSE,
	  type = "l", xname = "x", xlab = xname, ylab = NULL,
	  log = NULL, xlim = NULL, …)

# S3 函数的方法
plot(x, y = 0, to = 1, from = y, xlim = NULL, ylab = NULL, …)

注:R 语言的类有 S3 类和 S4 类,S3 类用的比较广,创建简单粗糙但是灵活,而 S4 类比较精细。

expr:函数表达式
fromto:绘图的起止范围
n:一个整数值,表示 x 取值的数量
add:是一个逻辑值,当为 TRUE 时,表示将绘图添加到已存在的绘图中。
type:绘图的类型,p 为点、l 为直线, o 同时绘制点和线,且线穿过点。
xname:用于 x 轴变量的名称。
xlim 和 ylim 表示x轴和y轴的范围。
xlab,ylab:x 轴和 y 轴的标签名称。

plot 函数中,x 和 y 分别表示所绘图形的横坐标和纵坐标。
以下我们绘制一个 sin(x) 函数的图表:

curve(sin(x), -2 * pi, 2 * pi)

image

注意:任何计算机绘图工具绘制的都是模式图,它并不能保证与真的函数图像一模一样,它只是每隔一段距离取一个点,然后计算这个点的"高度"并绘制出来,为了保证曲线连续性,相邻两个点之间会有直线连接,所以在某些情况下例如 tan(x) 可能会出现错误:
image

在每一个 (2n+1)Pi / 2 的位置都会出现断点,但是 R 的图像将它们连接了,希望大家理解这一点。
当然,不是所有的函数都像 sin 一样支持向量处理,我们也可以手动生成一个数字序列然后用 plot 函数生成函数图像。假设函数 f 仅支持单个数值作为参数。

散点图是将所有的数据以点的形式展现在直角坐标系上,以显示变量之间的相互影响程度,点的位置由变量的数值决定,每个点对应一个 X 和 Y 轴点坐标。

散点图可以使用 plot() 函数来绘制,语法格式如下:

plot(x, y, type="p", main, xlab, ylab, xlim, ylim, axes)

x 横坐标 x 轴的数据集合
y 纵坐标 y 轴的数据集合
type:绘图的类型,p 为点、l 为直线, o 同时绘制点和线,且线穿过点。
main 图表标题。
xlab、ylab x 轴和 y 轴的标签名称。
xlim、ylim x 轴和 y 轴的范围。
axes 布尔值,是否绘制两个 x 轴。

type 参数可选择值:

p:点图
l:线图
b:同时绘制点和线
c:仅绘制参数 b 所示的线
o:同时绘制点和线,且线穿过点
h:绘制出点到横坐标轴的垂直线
s:阶梯图,先横后纵
S:阶梯图,先纵后竖
n: 空图

生存一个散点图

# 数据
input <- mtcars[,c('wt','mpg')]

# 生成 png 图片
png(file = "scatterplot.png")

# 设置坐标 x 轴范围 2.5 到 5, y 轴范围 15 到 30.
plot(x = input$wt,y = input$mpg,
   xlab = "Weight",
   ylab = "Milage",
   xlim = c(2.5,5),
   ylim = c(15,30),              
   main = "Weight vs Milage"
)

image

散点图矩阵是借助两变量散点图的作图方法,它可以看作是一个大的图形方阵,其每一个非主对角元素的位置上是对应行的变量与对应列的变量的散点图。而主对角元素位置上是各变量名,这样,借助散点图矩阵可以清晰地看到所研究多个变量两两之间的相关关系。

散点图矩阵就是把数据集中的每个数值变量两两绘制散点图。

R 语言使用以下函数创建散点图矩阵:

pairs(formula, data)

formula 变量系列
data 变量的数据集

# 输出图片
png(file = "scatterplot_matrices.png")

# 4 个变量绘制矩阵,12 个图
pairs(~wt+mpg+disp+cyl,data = mtcars, main = "Scatterplot Matrix")

image

线性回归方程

在统计学中,线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。简单对来说就是用来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。

一元线性回归分析法的数学方程:

y = ax + b

y 是因变量的值。
x 是自变量的值。
a 与 b 为一元线性回归方程的参数。

接下来我们可以创建一个人体身高与体重的预测模型:

1、收集样本数据:身高与体重。
2、使用 lm() 函数来创建一个关系模型。
3、从创建的模型中找到系数,并创建数学方程式。
4、获取关系模型的概要,了解平均误差即残差(估计值与真实值之差)。
5、使用 predict() 函数来预测人的体重。

准备数据

以下是人的身高与体重数据:

# 身高,单位 cm
151, 174, 138, 186, 128, 136, 179, 163, 152, 131

# 体重,单位 kg
63, 81, 56, 91, 47, 57, 76, 72, 62, 48

在 R 中,你可以通过函数 lm() 进行线性回归。lm() 函数用于创建自变量与因变量之间的关系模型。

lm(formula,data)

参数说明:

formula - 一个符号公式,表示 x 和 y 之间的关系。
data - 应用数据。 

创建关系模型,并获取系数:

# 样本数据
x <- c(151, 174, 138, 186, 128, 136, 179, 163, 152, 131)
y <- c(63, 81, 56, 91, 47, 57, 76, 72, 62, 48)

# 提交给 lm() 函数
relation <- lm(y~x)

print(relation)

执行以上代码输出结果为:

Call:
lm(formula = y ~ x)

Coefficients:
(Intercept)            x  
	-38.4551       0.6746  

使用 summary() 函数获取关系模型的概要:

x <- c(151, 174, 138, 186, 128, 136, 179, 163, 152, 131)
y <- c(63, 81, 56, 91, 47, 57, 76, 72, 62, 48)

# 提交给 lm() 函数
relation <- lm(y~x)

print(summary(relation))

执行以上代码输出结果为:

Call:
lm(formula = y ~ x)

Residuals:
	Min      1Q     Median      3Q     Max 
-6.3002    -1.6629  0.0412    1.8944  3.9775 

Coefficients:
			 Estimate Std. Error t value Pr(>|t|)    
(Intercept) -38.45509    8.04901  -4.778  0.00139 ** 
x             0.67461    0.05191  12.997 1.16e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1

Residual standard error: 3.253 on 8 degrees of freedom
Multiple R-squared:  0.9548,    Adjusted R-squared:  0.9491 
F-statistic: 168.9 on 1 and 8 DF,  p-value: 1.164e-06

predict() 函数用于根据我们建立的模型来预测数值。

predict(object, newdata)

参数说明:

object - lm() 函数创建的公式。
newdata - 要预测的值。

以下实例我们预测一个新的体重值:

# 样本数据
x <- c(151, 174, 138, 186, 128, 136, 179, 163, 152, 131)
y <- c(63, 81, 56, 91, 47, 57, 76, 72, 62, 48)

# 提交给 lm() 函数
relation <- lm(y~x)

# 判断身高为 170cm 的体重
a <- data.frame(x = 170)
result <-  predict(relation,a)
print(result)

执行以上代码输出结果为:

1 
76.22869 

我们也可以生成一个图表:

# 样本数据
x <- c(151, 174, 138, 186, 128, 136, 179, 163, 152, 131)
y <- c(63, 81, 56, 91, 47, 57, 76, 72, 62, 48)
relation <- lm(y~x)

# 生成 png 图片
png(file = "linearregression.png")

# 生成图表
plot(y,x,col = "blue",main = "Height & Weight Regression",
abline(lm(x~y)),cex = 1.3,pch = 16,xlab = "Weight in Kg",ylab = "Height in cm")

图表:
image

posted @   StuBoo  阅读(84)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
点击右上角即可分享
微信分享提示