第二章:数据与运算
2.1基础知识
211向量
向量是R语言中用于构成数据的基本单位。它们可以包含数值、字符或逻辑值,并且是创建更复杂数据结构(如数据框和矩阵)的基础。
创建向量
-
赋值创建向量:使用赋值操作符
<-
可以创建向量。例如,创建一个包含数字1到4的向量:a <- c(1, 2, 3, 4)
注意:在创建向量时,应该使用函数
c()
,它代表“合并”(combine)。 -
使用
c()
函数:c()
函数可以合并多个值来创建向量。例如:b <- c(1, 2, 3, 4)
这里,
b
是一个包含四个数字的向量。 -
使用
:
运算符::
运算符可以创建一个数值序列。例如,创建一个从1到4的序列:c <- 1:4
这将创建一个向量
c
,包含数字1, 2, 3, 4。
212对象
在R语言中,几乎所有事物都是对象。对象是类的具体实例,而类则是对具有共同特征的对象的抽象描述。
对象和类的概念
- 对象:在R中,数据结构(如向量、矩阵、数组、数据框、列表)和其他实体都是对象。对象是存储数据和函数的地方。
- 类:类定义了对象的类型和它能够执行的操作。例如,向量类定义了向量对象可以进行的操作,如数学运算和子集选择。
创建对象
在R中,使用赋值语句可以创建对象。例如:
x <- c(1, 2, 3, 4) # 创建一个向量对象
y <- matrix(1:9, nrow = 3) # 创建一个矩阵对象
查看对象和类
- 查看当前环境中的所有对象:使用
ls()
函数可以列出当前环境中的所有对象名。 - 查看对象的类:使用
class()
函数可以查看一个对象所属的类。例如,class(x)
将显示对象x
的类。
213函数
函数是由若干语句组成的代码块,用于执行特定的任务或计算。在R中,函数是重用代码和实现复杂操作的核心。
内置函数分类
R语言内置了大量的函数,这些函数可以根据其功能进行分类:
- 数值计算函数:用于执行数学运算,如
sum()
,mean()
,sqrt()
等。 - 字符串处理函数:用于处理文本数据,如
paste()
,gsub()
,strsplit()
等。 - 创建数据结构的函数:用于生成数据结构,如
c()
,matrix()
,data.frame()
等。 - 描述统计函数:用于生成数据的统计摘要,如
summary()
,var()
,sd()
等。 - 数据切片和抽取方法:用于选择和分析数据的子集,如
subset()
,slice()
,filter()
等。 - 其他函数:包括数据处理、图形绘制、模型拟合等功能的函数。
用户自定义函数
除了使用内置函数外,R还允许用户编写自己的函数。自定义函数可以增强代码的可重用性和模块化。一个简单的自定义函数示例:
my_function <- function(x) {
return(x^2)
}
这个函数接受一个参数 x
,并返回其平方。
214标识符与保留字
标识符
标识符是用于命名对象和函数的字符串。在R中,标识符的命名和使用遵循以下规则:
- 组成:标识符可以由数字、字母(区分大小写)、点和下划线组成。
- 开头:标识符可以以点开头,但第二位不能是数字。
- 区分大小写:R是区分大小写的,因此
MyVar
和myvar
是不同的标识符。
保留字
保留字是R语言中具有特定意义的单词,不能用作标识符。这些包括:
- 控制流语句:
if
,else
,repeat
,while
,function
,for
,in
,break
,next
- 常量:
TRUE
,FALSE
,NULL
,Inf
,NaN
- 特殊值:
NA
, 以及以NA_
开头的一系列特殊值表示不同类型的缺失数据(如NA_character_
)
使用这些保留字作为标识符会导致语法错误。因此,在命名变量和函数时,应避免使用这些单词。
2.2数据类型与数据表示
221基本数据类型
在R语言中,基本数据类型共有六种:
-
逻辑型(logical):表示真(TRUE)或假(FALSE),也可以是逻辑表达式,如
2 < 3
。 -
浮点型(double):表示带小数的实数,以十进制形式表示。
-
整数型(integer):在R中,为了明确表示一个整数,需要在其后加上后缀
L
,例如3L
。 -
字符型(character):包含文本的数据,需要用双引号或单引号括起来。
-
复数类型(complex):包含实部和虚部,虚部以
i
或j
结尾,例如2+3i
。 -
原始类型(raw):用于存储原始的字节数据。
要检查一个对象的类型,可以使用 typeof()
函数。此外,is.*()
函数族(如 is.logical()
, is.double()
, is.integer()
等)可以用来测试一个对象是否属于特定的数据类型,如果属于则返回 TRUE
,否则返回 FALSE
。
在R中处理字符串时,字符串向量中的每个元素都需要用引号括起来。若要合并向量中的字符串并创建一个句子,paste()
函数是一个更好的选择,而不是 str()
。paste()
函数可以合并字符串,并且可以指定分隔符。cat()
函数则用于打印输出,它会合并并显示字符串,但不会改变原始对象。
关于转义字符,R语言使用反斜杠 \
作为转义字符。例如,\n
用于换行,\t
用于制表符(相当于四个空格),以及其他如 \r
(回车)、\b
(退格)等。要表示一个反斜杠本身或引号,需要使用转义字符,例如 \\
表示一个反斜杠,\"
或 \'
表示双引号或单引号。
222变量
在R语言中,变量用于存储数据,这些数据存储在内存中,并且可以根据需要改变。变量的命名规则与标识符的命名规则相同,但有一些特定的规则需要遵守:
-
变量名必须以字母或点号开头:这意味着变量名不能以数字或特殊字符(如
%
,#
,$
等)开头。 -
可以使用字母、数字、点号和下划线:变量名可以包含字母(大写或小写)、数字、点号(
.
)和下划线(_
)。 -
区分大小写:在R中,大写字母和小写字母是区分开的,因此
Variable
和variable
是两个不同的变量。 -
不能使用R的关键字:变量名不能是R语言中的关键字,如
if
,else
,function
等。 -
长度限制:虽然R没有硬性限制变量名的长度,但为了代码的可读性和易用性,建议变量名简洁明了。
223常量
在R语言中,常量是指那些在程序执行过程中不会改变的量。它们通常用于表示固定的值,如数学常数、预定义的序列等。R语言中的一些内置常量包括:
-
letters:包含所有小写字母的字符向量。
-
LETTERS:包含所有大写字母的字符向量。
-
month.name:包含所有月份全名的字符向量。
-
month.abb:包含所有月份缩写的字符向量。
-
pi:数学常数π的近似值。
这些常量在R中预定义,可以直接在代码中使用,无需额外定义。例如,要引用数学常数π,可以直接使用 pi
而不是写出一个近似的数值。
虽然R语言没有像其他编程语言那样明确规定常量,但通常的做法是将不会改变的值定义为常量,以提高代码的可读性和可维护性。在R中,可以通过将变量赋值给一个不变的值来模拟常量的行为,并遵循命名惯例,如使用大写字母来命名常量,以区别于普通变量。
224特殊值
在R语言中,有几种特殊值用于表示特定的数据状态:
-
NA:表示缺失值,用于表示数据中缺少的或不可用的值。NA可以用于任何数据类型。
-
Inf:表示无穷大。在数值计算中,当一个结果超过了R能够表示的最大数值时,会返回Inf。例如,
1/0
将返回 Inf。 -
-Inf:表示负无穷大。与Inf相对,当数值计算结果是一个非常小的负数,小于R能够表示的最小数值时,会返回-Inf。例如,
-1/0
将返回 -Inf。 -
NaN:表示“不是一个数字”(Not a Number)。当进行一个无意义的数学运算(如
0/0
)时,结果将是NaN。 -
NULL:表示空值或不存在。在R中,NULL是一个不包含任何值的数据类型。它通常用于表示空数据结构或初始化变量。需要注意的是,NULL在计算长度时不会被计算在内。
这些特殊值在数据处理和分析中非常重要,因为它们提供了处理缺失数据、异常值和空值的标准方法。
2.3基本运算
在R语言中,基本运算符用于执行数学运算、比较值和逻辑操作。除了常见的运算符,R还提供了一些特殊的运算符:
-
%%:求余 - 对两个数进行除法运算后,返回余数。例如,
7 %% 3
的结果是1
。 -
%/%:整除 - 对两个数进行除法运算,并返回结果的整数部分。例如,
7 %/% 3
的结果是2
。 -
&:与 - 逻辑与运算符,当两边的表达式都为真时,结果为真。例如,
TRUE & TRUE
的结果是TRUE
。 -
|:或 - 逻辑或运算符,当两边的表达式至少有一个为真时,结果为真。例如,
FALSE | TRUE
的结果是TRUE
。 -
!:非 - 逻辑非运算符,用于反转表达式的真值。例如,
!TRUE
的结果是FALSE
。
在R中,运算符的优先级决定了它们在表达式中的执行顺序。运算优先级从高到低依次是:
-
括号 - 使用括号可以改变运算的顺序。
-
函数运算 - 函数调用。
-
算术运算符 - 如
+
,-
,*
,/
等。 -
字符连接 - 使用
paste()
函数或运算符paste0()
进行字符连接。 -
关系运算符 - 如
==
,!=
,<
,>
,<=
,>=
。 -
逻辑运算符 - 如
!
,&
,|
。
理解运算符的优先级对于编写正确的R代码非常重要,尤其是在复杂的表达式中。
2.4数据类型转换
241自动转换类型
在R语言中,数据类型的自动转换遵循一定的规律,通常发生在进行运算或比较时。这种转换被称为“隐式类型转换”。自动转换的规律可以概括为“大小听话轮”,即:
-
逻辑型(logical):在需要转换时,逻辑值
TRUE
被转换为1
,而FALSE
被转换为0
。 -
整数型(integer):当与浮点数进行运算时,整数会被转换为浮点数。
-
浮点型(double):在进行字符连接或与字符进行比较时,浮点数会被转换为字符型。
-
字符型(character):在R中,字符型数据通常不会自动转换为其他类型,除非在特定情况下,例如在使用数学函数时。
这种转换遵循从“小”类型到“大”类型的方向:逻辑型(最小)→ 整数型 → 浮点型 → 字符型(最大)。这种转换机制确保了在混合类型数据进行运算时,R能够合理地处理数据,但也可能导致意外的结果。因此,了解和预期这些转换对于编写准确和高效的R代码至关重要。
242强制转换类型
在R语言中,除了自动类型转换,还可以通过强制类型转换来显式地将一个对象转换为特定的数据类型。强制类型转换使用 as.*()
函数族,其中 *
代表目标数据类型。基本格式是 as.A(n)
,其中 A
是目标数据类型,n
是要转换的对象。
例如:
-
转换为逻辑型:
as.logical(x)
将x
转换为逻辑型。非零数值转换为TRUE
,零转换为FALSE
。 -
转换为整数型:
as.integer(x)
将x
转换为整数型。小数部分会被截断。 -
转换为浮点型:
as.double(x)
将x
转换为浮点型。整数和字符型数据可以被转换为相应的浮点数值。 -
转换为字符型:
as.character(x)
将x
转换为字符型。数值会被转换为它们的字符表示。 -
转换为复数型:
as.complex(x)
将x
转换为复数型。如果x
是字符型,它应该表示为一个复数。
强制类型转换是一种非常有用的工具,特别是在处理来自不同源的数据时,或者当需要确保变量是特定类型以进行某些操作时。然而,需要注意的是,不恰当的强制类型转换可能会导致数据丢失或意外的结果。
第三章:程序设计基础
3.1控制流
控制流是编程语言中用于控制程序执行顺序的结构。在R语言中,控制流主要有以下四种结构:
1. 顺序结构
顺序结构是程序中最基本的结构,它表示程序按代码的先后顺序依次执行。在R中,除非特别指定,代码默认就是按照顺序执行的。
2. 分支结构
分支结构基于条件执行不同的代码路径。R语言提供了if
、else if
和else
关键字来实现单分支、双分支和多分支选择结构。此外,分支结构可以嵌套,即一个分支结构内部可以包含另一个分支结构。
- 单分支:只有
if
语句,当条件满足时执行一段代码。 - 双分支:
if
语句加上else
语句,条件满足时执行一段代码,不满足时执行另一段代码。 - 多分支:使用
if
、else if
和else
,根据多个条件选择不同的代码路径。 - 嵌套分支:一个分支结构内包含另一个分支结构。
3. 循环结构
循环结构允许重复执行一段代码,直到满足某个条件。R语言中有几种循环结构:
- repeat循环:创建一个永久循环,直到使用
break
语句跳出。 - while循环:当条件成立时,重复执行一段代码。
- for循环:执行固定次数的循环,通常与序列一起使用。
- next/break:在循环内部使用
next
跳过当前迭代,或使用break
提前退出循环。
4. 选择函数
R语言还提供了特定的函数来处理控制流,例如:
- lftest函数:用于执行逻辑函数测试。
- switch函数:根据给定的表达式选择执行不同的代码路径。
示例代码
以下是每种控制流结构的简单示例:
# 顺序结构
x <- 5
y <- x + 3
print(y)
# 分支结构
if (x > 10) {
print("x is greater than 10")
} else if (x > 5) {
print("x is between 5 and 10")
} else {
print("x is 5 or less")
}
# 循环结构
for (i in 1:5) {
print(i)
}
# 选择函数
result <- switch(
x,
"one" = "x is 1",
"two" = "x is 2",
"x is not 1 or 2"
)
print(result)
311顺序结构
顺序结构是R语言中的基本控制流,它按照代码的书写顺序自上而下执行。以下是两个关于顺序结构的重要点:
1. 将多行命令并入一行
在R中,您可以在一行内执行多个命令,只需在每个命令后添加分号(;
)。这样做可以使代码更加紧凑。
x <- 5; y <- x + 3; print(y)
2. 使用大括号{}
连接多行命令
当您需要执行一系列相互关联的语句时,使用大括号{}
将这些语句组合成一个代码块。这在编写if
语句或其他控制流结构时特别有用。
例如,在if
函数内部:
if (x > 0) {
y <- x^2
print(y)
}
在这个例子中,y <- x^2
和print(y)
只有在x > 0
时才执行。使用大括号将这些命令组合起来,确保它们作为一个整体被执行。
312分支结构
R语言中的分支结构允许程序根据条件选择性地执行代码。这些结构主要由if
、else if
和else
语句构成。
1. 单分支结构 - if
单分支结构仅检查一个条件,如果该条件为真,则执行相应的代码块。
if (condition) {
# 执行某些操作
}
2. 双分支结构 - if...else
双分支结构检查一个条件,并根据条件的真假执行两个不同的代码块。
if (condition) {
# 条件为真时执行的代码
} else {
# 条件为假时执行的代码
}
3. 多分支结构 - if...else if...else
多分支结构检查多个条件,并根据这些条件的真假执行不同的代码块。
if (condition1) {
# 条件1为真时执行的代码
} else if (condition2) {
# 条件1为假且条件2为真时执行的代码
} else {
# 所有条件都为假时执行的代码
}
4. 嵌套分支结构 - if...if...if...else
嵌套分支结构中,if
语句嵌套在其他if
语句中。else
子句与最近的未配对的if
语句配对。
if (condition1) {
if (condition2) {
# 条件1和条件2都为真时执行的代码
} else {
# 条件1为真但条件2为假时执行的代码
}
} else {
# 条件1为假时执行的代码
}
在嵌套分支中,每个else
子句与最近的未配对的if
语句配对。
313循环结构
R语言中的循环结构用于重复执行代码块,直到满足某个条件。主要的循环结构包括repeat
、while
和for
循环。
1. repeat
循环
repeat
循环会无限重复执行其内部的代码块,直到遇到break
语句。
repeat {
# 语句块
if (condition) {
break
}
}
在repeat
循环中,if
语句通常用于设置停止条件。如果没有满足if
条件,循环将一直重复执行。
2. while
循环
while
循环在满足条件表达式的情况下重复执行代码块。
while (condition) {
# 语句块
}
只要条件表达式为真,while
循环就会一直执行其内部的代码块。
3. for
循环
for
循环通过一个序列(通常是向量)来重复执行代码块。
for (name in vector) {
# 语句块
}
在这个循环中,代码块对向量vector
中的每个元素执行一次。
4. next
和break
语句
next
语句用于跳过当前循环的剩余部分,直接进入下一次循环。break
语句用于立即退出循环。
for (i in 1:5) {
if (i == 3) next # 跳过i等于3的情况
print(i)
if (i == 4) break # 当i等于4时退出循环
}
在这个例子中,当i
等于3时,next
语句会导致循环跳过打印操作。而当i
等于4时,break
语句会导致循环完全停止。
314选择相关函数
R语言中的选择函数用于根据条件选择性地执行或返回不同的值。两个常用的选择函数是ifelse
和switch
。
1. ifelse
函数
ifelse
函数是R中的一个向量化的if-else
语句,它根据条件向量来选择返回值。
ifelse(test, yes, no)
test
: 一个逻辑向量,用于测试每个元素是否为真。yes
: 如果test
中的元素为真,则返回这个值。no
: 如果test
中的元素为假,则返回这个值。
示例:
result <- ifelse(c(T, F, T), "Yes", "No")
print(result) # 输出: "Yes" "No" "Yes"
在这个例子中,result
的每个元素根据test
的逻辑值选择返回"Yes"
或"No"
。
2. switch
函数
switch
函数用于根据给定的值选择性地执行或返回函数列表中的元素。
switch(EXPR, ...)
EXPR
: 一个表达式,用于选择列表中的元素。...
: 一个或多个表达式或函数,用于EXPR
的每个可能值。
示例:
# 当EXPR为整数时
result <- switch(2, "One", "Two", "Three")
print(result) # 输出: "Two"
# 当EXPR为字符串时
result <- switch("Three", One="First", Two="Second", Three="Third")
print(result) # 输出: "Third"
在第一个例子中,switch
根据整数索引选择列表中的第二个元素。在第二个例子中,它根据字符串匹配选择相应的元素。如果找不到匹配项,switch
默认返回NULL
。
3.2函数设计
321函数的声明,定义和调用
在R中,函数是用于执行特定任务的自包含代码块。函数通过将输入参数(形式参数)转换为输出(返回值)来实现这一目的。
1. 函数的声明和定义
函数通过function
关键字来声明和定义。函数的基本结构如下:
函数名 <- function(arg1, arg2, ...) {
# 函数体
return(表达式)
}
函数名
: 用于调用函数的名称。arg1, arg2, ...
: 函数的形式参数,用于接收传递给函数的值。函数体
: 函数的具体实现步骤,包括计算和处理数据。return
: 语句用于指定函数的返回值,并停止执行函数。
2. 函数的调用
定义函数后,可以通过提供实际参数来调用它。调用格式如下:
函数名(实际参数1, 实际参数2, ...)
实际参数是将传递给函数的形式参数的具体值。
下面是一个简单的函数示例,该函数接受两个数字作为输入,计算它们的和,并返回结果:
add <- function(x, y) {
sum <- x + y
return(sum)
}
result <- add(3, 4)
print(result) # 输出: 7
在这个例子中,add
是一个接受两个参数x
和y
的函数。函数体计算它们的和,并使用return
语句返回结果。然后,我们通过add(3, 4)
调用这个函数,并将结果存储在result
变量中。
3.3综合应用
331求最大公约数和最小公倍数
最大公约数(GCD)
最大公约数是两个或多个整数共有的最大的约数。在R中,我们可以使用gcd
函数从numbers
包中计算最大公约数。
首先,确保安装了numbers
包:
install.packages("numbers")
然后,使用gcd
函数:
library(numbers)
gcd <- function(a, b) {
return(gcd(a, b))
}
# 示例
result_gcd <- gcd(60, 48)
print(result_gcd) # 输出: 12
最小公倍数(LCM)
最小公倍数是能被两个或多个整数共同整除的最小正整数。在R中,我们可以使用以下公式计算最小公倍数:
在R中实现:
lcm <- function(a, b) {
return(abs(a * b) / gcd(a, b))
}
# 示例
result_lcm <- lcm(60, 48)
print(result_lcm) # 输出: 240
在这个例子中,我们首先定义了一个gcd
函数来计算最大公约数,然后定义了一个lcm
函数来计算最小公倍数。这两个函数都接受两个整数作为输入,并返回相应的结果。
332求素数
检查素数的函数
is_prime <- function(n) {
if (n <= 1) {
return(FALSE)
}
for (i in 2:sqrt(n)) {
if (n %% i == 0) {
return(FALSE)
}
}
return(TRUE)
}
这个is_prime
函数接受一个整数n
作为输入,并返回一个逻辑值,指示该数是否为素数。函数首先检查n
是否小于或等于1,如果是,则返回FALSE
。然后,函数使用一个for
循环来检查从2到sqrt(n)
的每个数是否能整除n
。如果能找到任何这样的数,函数返回FALSE
;否则,返回TRUE
。
找出一定范围内的所有素数
使用is_prime
函数,我们可以找出一定范围内的所有素数:
find_primes <- function(max_number) {
primes <- c()
for (i in 2:max_number) {
if (is_prime(i)) {
primes <- c(primes, i)
}
}
return(primes)
}
# 示例:找出1到100之间的所有素数
primes_up_to_100 <- find_primes(100)
print(primes_up_to_100)
在这个例子中,find_primes
函数接受一个整数max_number
作为输入,并返回一个包含从2到max_number
之间所有素数的向量。函数内部,我们使用is_prime
函数来检查每个数是否为素数,并将素数添加到结果向量中。
333打印金字塔图形
print_pyramid <- function(height) {
for (i in 1:height) {
# 打印空格
cat(rep(" ", height - i))
# 打印星号
cat(rep("* ", i))
# 换行
cat("\n")
}
}
# 示例:打印一个高度为5的金字塔
print_pyramid(5)
在这个例子中,print_pyramid
函数接受一个整数height
作为输入,表示金字塔的高度。函数使用一个for
循环来控制金字塔的每一行。在内循环中,首先打印一定数量的空格,然后打印星号,每行的星号数量比上一行多一个。最后,使用cat("\n")
进行换行,开始下一行的打印。
运行这个函数将打印出一个漂亮的金字塔图形:
*
* *
* * *
* * * *
* * * * *
第五章:数据结构与数据处理
5.1向量
511创建向量
在R语言中,创建向量是基础且常用的操作。有几种方法可以创建向量:
- 直接赋值:直接给向量赋值。
- 使用
c()
函数:通过连接多个值来创建向量。 - 使用“:”操作符:创建一个数值序列。
此外,还有一些特殊函数可以用来创建特定类型的向量。
使用seq()
创建等差数列
seq()
函数用于生成等差数列。其格式如下:
seq(from = num1, to = num2, by = num3, length.out = num4)
from
:序列的起始值。to
:序列的结束值。by
:序列中每两个相邻值的差(步长)。默认为1。length.out
:生成的序列的长度。例如,要生成一个长度为5的序列,即使from
和to
的数量级相差很大。
使用rep()
创建重复向量
rep()
函数用于重复向量中的元素。其格式如下:
rep(x, times = num)
x
:要重复的向量。times
:重复的次数。
示例
-
使用
seq()
创建一个从1到10的等差数列:seq(1, 10)
-
使用
rep()
重复向量c(1, 2, 3)
三次:rep(c(1, 2, 3), times = 3)
通过这些方法,可以灵活地在R中创建各种向量,满足不同的数据需求。
512使用索引访问向量元素
在R中,可以使用索引来访问和修改向量中的元素。索引的使用方法如下:
向量1[向量2]
这里,向量2
通常包含正整数,表示从向量1
中提取索引值对应的元素。
使用正数索引
R中的索引从1开始,这与Python等其他编程语言不同(它们从0开始)。
使用负数索引
在R中,使用负数索引表示删除对应位置的元素,并返回剩余的元素。例如,对于向量a <- c("a", "b", "c", "d")
,a[-1]
将返回"b", "c", "d"
。
使用逻辑索引
逻辑索引使用逻辑值(TRUE
或FALSE
)来选择元素。例如,a[c(TRUE, FALSE)]
将从a
中选择所有在TRUE
位置的元素。
修改向量元素
可以使用索引来修改向量中的元素。例如,mec_vec[10] <- 33
会将mec_vec
中索引为10的元素值改为33。如果向量原长度不足10,R会自动扩展向量,并在新位置填充NA
。
在向量中添加元素
要在向量的特定位置添加元素,可以使用以下方法:
A <- c(A[1:n], m, A[(n+1):length(A)])
这段代码将向量A
重新初始化,保持1:n
位置的元素不变,在n
之后添加新元素m
,然后保持n+1
到向量末尾的元素不变。
另外,也可以使用append()
函数来简化这一过程:
append(A, m, after=n)
这会在n
之后添加m
。需要注意的是,如果添加的是字符串(如'm'
),而原向量是数值型,那么整个向量的类型可能会变为字符型。
513循环补齐
循环补齐是R中一种特殊的向量操作机制,当进行运算或函数调用时,如果两个向量的长度不同,R会自动重复较短向量的元素,以匹配较长向量的长度。
例子
考虑以下向量相加的例子:
c(1, 2, 3) + c(1, 2, 3, 4, 5, 6, 7)
在这个例子中,第一个向量c(1, 2, 3)
长度为3,而第二个向量c(1, 2, 3, 4, 5, 6, 7)
长度为7。为了进行相加,R会将第一个向量循环补齐,使其长度与第二个向量相同。补齐后的向量变为c(1, 2, 3, 1, 2, 3, 1)
。
然后进行逐元素相加:
1 + 1 = 2
2 + 2 = 4
3 + 3 = 6
1 + 4 = 5
2 + 5 = 7
3 + 6 = 9
1 + 7 = 8
最终结果为c(2, 4, 6, 5, 7, 9, 8)
。
注意事项
- 循环补齐只在必要且可行时才会发生。如果向量长度差异太大,或者无法通过重复较短向量来匹配较长向量,R会报错。
- 循环补齐是R的一种特性,在其他编程语言中可能不存在或表现不同。
514向量的比较
在R中,向量之间的比较是按索引位置进行的,比较结果是一个逻辑向量,其中每个元素表示相应位置上的比较结果。
按索引比较
例如,比较两个向量c(1, 2, 3)
和c(1, 3, 2)
:
c(1, 2, 3) == c(1, 3, 2)
这将返回一个逻辑向量c(TRUE, FALSE, FALSE)
,表示第一个元素相等,后两个元素不相等。
使用identical()
进行比较
identical()
函数用于检查两个对象是否完全相同。如果两个向量在所有元素和属性上都相同,则返回TRUE
,否则返回FALSE
。
identical(V1, V2)
需要注意的是,由于浮点数的精度问题,即使数值上看起来相等,identical()
也可能返回FALSE
。例如,1.4 - 0.9
并不完全等于0.5
。
使用all()
和any()
函数
all()
和any()
函数用于检查逻辑向量中的元素。
all()
:如果所有元素都是TRUE
,则返回TRUE
。any()
:如果至少有一个元素是TRUE
,则返回TRUE
。
例如,对于向量V1
,使用all(V1 > 3)
将检查V1
中所有元素是否都大于3。
515按条件提取元素
在R中,可以使用条件表达式在方括号[]
内来提取满足特定条件的向量元素。这种操作通常称为子集选择。
语法和示例
假设有一个向量v
,您想要提取所有大于某个值x
的元素。可以使用以下语法:
v[v > x]
例如,对于向量v <- c(1, 3, 5, 7, 9)
,如果您想要提取所有大于5的元素,可以这样做:
v[v > 5]
这将返回7
和9
,因为它们是v
中大于5
的元素。
使用逻辑运算符
您可以使用各种逻辑运算符来构建更复杂的条件,例如:
>
:大于<
:小于==
:等于>=
:大于或等于<=
:小于或等于!=
:不等于
例如,提取所有大于等于5且小于等于7的元素:
v[v >= 5 & v <= 7]
结合多个条件
您还可以结合多个条件,使用逻辑运算符&
(且)和|
(或):
- 使用
&
来选择同时满足多个条件的元素。 - 使用
|
来选择满足任一条件的元素。
例如,提取所有大于5或小于3的元素:
v[v > 5 | v < 3]
注意事项
- 条件表达式必须返回一个逻辑向量,其长度与被筛选的向量相同。
- 确保使用适当的括号来明确逻辑运算的顺序。
5.2矩阵与数组
521创建矩阵
矩阵是R中的一种基本数据结构,用于存储和操作二维数组。在R中,有多种方法可以创建矩阵。
使用dim()
转换向量
通过dim()
函数,可以将一个向量转换成矩阵。方法是先创建一个向量,然后用dim()
指定行数和列数。
vec <- c(1, 2, 3, 4, 5, 6)
dim(vec) <- c(2, 3)
这将创建一个2行3列的矩阵。在R中,默认是按列填充矩阵。
使用matrix()
函数
matrix()
函数是创建矩阵的另一种方法。其格式如下:
matrix(data = NA, nrow = num1, ncol = num2, byrow = FALSE, dimnames = NULL)
data
:用于指定矩阵的数据。nrow
:指定矩阵的行数。ncol
:指定矩阵的列数。byrow
:逻辑值,表示元素是否按行填充。默认为FALSE
,即按列填充。dimnames
:为矩阵的行和列命名。
例如,创建一个3行2列的矩阵:
matrix(c(1, 2, 3, 4, 5, 6), nrow = 3, ncol = 2)
特殊矩阵
-
使用
diag()
创建对角矩阵:diag(c(1, 2, 3))
这将创建一个3x3的对角矩阵,其对角线上的元素为1, 2, 3。
合并矩阵
- 使用
rbind()
按行合并矩阵或向量。 - 使用
cbind()
按列合并矩阵或向量。
例如,合并两个向量:
rbind(c(1, 2, 3), c(4, 5, 6))
cbind(c(1, 2, 3), c(4, 5, 6))
522矩阵乘法
R提供了丰富的函数来进行矩阵运算,包括矩阵乘法、转置、求逆矩阵等。
矩阵乘法
在R中,矩阵乘法使用%*%
运算符。例如,如果A
和B
是两个矩阵,它们的乘积可以用以下方式计算:
result <- A %*% B
转置矩阵
矩阵的转置可以通过t()
函数得到。例如,A
的转置为t(A)
。
求逆矩阵
solve()
函数用于求解矩阵的逆。如果A
是一个方阵,其逆矩阵可以用solve(A)
得到。
计算行列式
行列式可以使用det()
函数计算。例如,矩阵A
的行列式为det(A)
。
求解特征值和特征向量
eigen()
函数用于计算矩阵的特征值和特征向量。例如,eigen(A)
将返回矩阵A
的特征值和特征向量。
求解线性方程组
在R中,线性方程组Ax = b
可以通过solve()
函数求解。其中A
是系数矩阵,b
是常数列向量。解向量x
可以通过以下方式得到:
x <- solve(A, b)
这个例子中的描述有一点小错误,solve(A, b)
实际上是求解Ax = b
,返回的是方程组的解向量x
,而不是A + b
的逆。
523使用矩阵索引
在R中,可以使用索引来访问和修改矩阵中的元素。索引使用方括号[]
,并可以指定行和列的位置。
访问单个元素
要访问矩阵中的单个元素,可以指定其行号和列号。例如,对于矩阵M
,访问第i
行第j
列的元素可以这样写:
element <- M[i, j]
访问行或列
使用:
运算符可以访问矩阵中的行或列。例如,要访问矩阵M
的第i
行到第j
行和第k
列到第l
列的所有元素:
sub_matrix <- M[i:j, k:l]
使用负数索引
在R中,使用负数索引可以从矩阵中去除指定的行或列。例如,M[-i, ]
将返回除了第i
行之外的所有行。
赋值操作
同样,可以使用索引来修改矩阵中的元素。例如,将矩阵M
中第i
行第j
列的元素赋值为value
:
M[i, j] <- value
524apply函数族
apply()
函数族是R中用于对矩阵或数组进行批量操作的函数。它通过应用函数来简化对矩阵或数组的行或列的处理。
apply()
函数的基本用法
apply()
函数的基本格式如下:
apply(X, MARGIN, fun)
X
:矩阵或数组。MARGIN
:一个或两个整数,表示要应用函数的维度。对于矩阵,MARGIN=1
表示对每一行应用函数,MARGIN=2
表示对每一列应用函数。fun
:要应用的函数。
应用场景
apply()
函数常用于计算矩阵的行或列的统计量,如均值、标准差、求和等。例如,计算矩阵M
每一行的均值:
row_means <- apply(M, 1, mean)
apply()
函数的灵活性
apply()
函数非常灵活,可以与各种统计函数结合使用。- 它适用于矩阵或数组,但对于更高维的数据结构,
apply()
可能不是最佳选择。
示例
计算矩阵M
每一列的和:
col_sums <- apply(M, 2, sum)
这个操作会将矩阵M
“压扁”,即计算每一列的元素和。
525多维数组
多维数组是R中用于存储和操作多维数据的基本数据结构。在R中,可以使用array()
函数来创建多维数组。
array()
函数的基本用法
array()
函数的基本格式如下:
array(data = NA, dim = length(data), dimnames = NULL)
data
:必选参数,用于指定数组中的元素值。可以是向量、矩阵或其他R支持的数据类型。dim
:可选参数,一个整数向量,用于指定数组的维度。例如,dim = c(2, 3)
表示创建一个2行3列的数组。dimnames
:可选参数,用于指定数组各维度的名称。是一个嵌套的列表,例如dimnames = list(c("row1", "row2"), c("col1", "col2", "col3"))
表示给数组的第一维定义名为"row1"和"row2",第二维定义名为"col1"、“col2"和"col3”。
示例
创建一个2行3列的数组,元素为向量c(1, 2, 3, 4, 5, 6)
:
my_array <- array(c(1, 2, 3, 4, 5, 6), dim = c(2, 3), dimnames = list(c("row1", "row2"), c("col1", "col2", "col3")))
注意事项
- 数组的维度必须是一个整数向量,其中每个元素表示相应维度的大小。
dimnames
参数是可选的,但提供了对数组元素进行更清晰标注的途径。
5.3数据框
531创建数据框
数据框是R中用于存储和操作表格数据的基本数据结构,它允许不同的列包含不同类型的数据。
data.frame()
函数的基本用法
data.frame()
函数的基本格式如下:
data.frame(col1, col2, stringsAsFactors = FALSE)
col1
、col2
等:数据框中的列,可以是向量、因子、数值型或逻辑型数据。stringsAsFactors
:一个逻辑值,表示是否将字符串向量自动转换为因子向量。默认为TRUE
,但建议设置为FALSE
,特别是在处理外部数据时。
添加行或列
-
使用
rbind()
添加行:rbind(df, list(row1, row2, ...))
-
使用
cbind()
添加列:cbind(df, colname1 = c(value1, value2, ...), colname2 = c(value2, value3, ...))
合并数据框
使用merge()
函数可以合并两个或多个数据框。合并时,数据框必须具有相同的列作为合并的依据。
merge(df1, df2)
注意事项
row.names
参数用于指定行名,默认为NULL,即不指定行名。check.names
参数用于指定是否检查列名是否合法,默认为TRUE
。
532访问数据库中的元素
在R中,可以使用多种方法来访问数据框中的元素,包括使用索引、列名和行名。
使用索引访问数据框
-
使用方括号
[]
和行号来访问数据框中的特定行。例如,访问数据框df
的第二行:second_row <- df[2, ]
-
使用方括号和列名来访问数据框中的特定列。例如,访问数据框
df
的名为"col1"
的列:specific_column <- df[, "col1"]
-
使用美元符号
$
来访问数据框中的特定列。例如,访问数据框df
的名为"col1"
的列:specific_column <- df$col1
查询和修改行名和列名
-
使用
rownames()
函数查询或修改行名。例如,查询数据框df
的行名:rownames(df)
-
使用
colnames()
函数查询或修改列名。例如,修改数据框df
的名为"col1"
的列名:colnames(df)[1] <- "new_col1_name"
-
在查询时,直接在方括号中加上数据框名。例如,查询名为
df
的数据框的第二个元素:second_element <- df[2, 1]
-
在修改时,指定数据框后使用
<-
符号来赋值。例如,将数据框df
的第二行第一个元素修改为5
:df[2, 1] <- 5
5.4因子
因子是R中用于存储和操作分类数据的一种特殊数据类型。它将文本或数字数据转换为可以进行分类统计的变量。
创建因子
使用factor()
函数可以创建因子。例如,将一个向量转换为因子:
my_vector <- c("A", "B", "A", "C", "B")
my_factor <- factor(my_vector)
在factor()
函数中,重复的元素会被合并为一种因子。
修改因子水平
创建因子后,可以使用levels()
函数来重新定义因子水平。例如,将因子df$my_factor
的水平顺序从factor1, factor2, factor3
改为2, 3, 1
:
levels(df$my_factor) <- c("因子2", "因子3", "因子1")
因子的设定原因
因子的一个重要用途是确保数据的分类一致性。例如,一个样本的类别设定为ABC
,创建因子后,如果输入不属于ABC
的数据,R会提示错误。
向因子中添加新元素
向已有的因子中添加一个不存在的元素会导致该位置为空值。
因子的应用
因子在数据分析中广泛应用于分类汇总和统计。例如,在描述性统计分析中,因子可以用来表示不同类别之间的差异。
5.5列表
列表是R中用于存储和操作不同类型对象的复合数据结构。它允许将多个向量、矩阵、数据框、函数等对象组合在一起。
创建列表
使用list()
函数可以创建列表。例如,创建一个包含向量、矩阵和数据框的列表:
my_list <- list(vec = c(1, 2, 3), mat = matrix(1:9, nrow = 3), df = data.frame(col1 = 1:3, col2 = 4:6))
在列表中,使用=
符号来赋值,而不是<-
。
访问列表元素
-
使用方括号
[]
和整数索引来访问列表中的特定元素。例如,访问列表my_list
的第二个元素:second_element <- my_list[[2]]
-
使用美元符号
$
来访问列表中的特定项目。例如,访问列表my_list
中名为"mat"
的项目:mat_element <- my_list$mat
-
使用方括号和项目名来访问列表中的特定元素。例如,访问列表
my_list
中名为"col1"
的数据框的列:column <- my_list$df$col1
如果通过方括号输入整数索引,R会返回整个列表,而不是直接访问项目。
列表的应用
列表在数据分析中用于存储和操作复杂数据结构,如数据预处理步骤的集合、模型的参数列表等。
5.6数据的导入与导出
561数据文件的读写
R提供了多种函数来读取和写入数据文件,如read.table()
和write.table()
。
读取数据文件
使用read.table()
函数可以读取数据文件。其基本格式如下:
data <- read.table("文件名地址(通常是盘符:/文件名带后缀)", header = TRUE, sep = "")
header = TRUE
:表示文件包含表头,即文件的第一行包含列名。sep = ""
:表示文件中各列之间的分隔符。对于CSV文件,通常使用逗号","
作为分隔符,此时应将sep
设置为","
。
例如,读取一个CSV文件:
data <- read.csv("file.csv")
写入数据文件
使用write.table()
函数可以将数据写入文件。其基本格式如下:
write.table(数据, file = "带盘符文件名")
数据
:要写入文件的数据,可以是数据框、矩阵或其他R支持的类型。file
:写入文件的路径和名称。
例如,将数据框df
写入一个CSV文件:
write.table(df, file = "output.csv")
注意事项
- 确保文件路径和名称正确无误。
- 根据文件格式选择合适的分隔符。
562数据编辑器
R提供了数据编辑器功能,允许用户直接编辑R中的数据对象。
使用数据编辑器
通过edit()
函数可以指定编辑一个对象。例如,编辑名为my_data
的数据对象:
my_data <- edit(my_data)
这将打开一个编辑器,允许用户直接修改数据对象的内容。
查看数据集的子集
-
使用
head()
函数可以查看数据集的前几项。例如,查看数据集my_data
的前5项:head(my_data, 5)
-
使用
tail()
函数可以查看数据集的后几项。例如,查看数据集my_data
的后5项:tail(my_data, 5)
保存修改后的数据
完成编辑后,可以使用fix()
函数来保存修改后的数据。例如,保存对my_data
的修改:
fix(my_data)
这将确认保存更改并关闭编辑器。
注意事项
- 数据编辑器适用于数据框、矩阵等R支持的数据类型。
- 确保在保存修改后重新加载数据对象,以应用更改。
第六章:绘图与数据可视化
6.1基本图形与绘图函数
611基础图形的创建
plot()
函数是R中用于绘制基础图形的核心函数。
plot()
函数的基本用法
plot()
函数的基本格式如下:
plot(x, y, main, xlab, ylab, type = "参数")
x
:x轴的数值或数值向量。y
:y轴的数值或数值向量。main
:图形标题。xlab
:x轴标题。ylab
:y轴标题。type
:图形类型,如“l”表示线图,“p”表示点图,“s”表示散点图等。
示例
-
绘制一条直线:
x <- 1:10 y <- 2 * x plot(x, y, main = "线性方程图", xlab = "X轴", ylab = "Y轴")
-
绘制散点图:
x <- rnorm(100) y <- rnorm(100) plot(x, y, main = "散点图", xlab = "X轴", ylab = "Y轴")
注意事项
type
参数可以改变绘图类型,根据需要选择合适的参数值。- 确保x和y的数据类型和长度匹配。
612新增绘图窗口和导出
新增绘图窗口
使用window()
函数可以新增一个绘图窗口,这样在后续调用plot()
函数时,新的图形将不会替代已有的图形。
window()
导出图形
R提供了多种函数来导出图形到不同格式的文件。常用的格式包括PNG、JPEG和TIFF。
-
使用
png()
函数保存图形为PNG格式:png("plot.png") x <- ... y <- ... plot(x, y) dev.off()
-
使用
jpeg()
函数保存图形为JPEG格式:jpeg("plot.jpg") x <- ... y <- ... plot(x, y) dev.off()
-
使用
tiff()
函数保存图形为TIFF格式:tiff("plot.tiff") x <- ... y <- ... plot(x, y) dev.off()
注意事项
- 确保在调用导出函数后,使用
dev.off()
关闭图形设备。 - 根据需要选择合适的文件格式。
6.2调整绘图参数
621自定义特征
R中的图形可以通过多种方式进行自定义,以满足特定的绘图需求。
使用plot()
函数自定义特征
plot()
函数提供了多种参数来定制图形特征。
type
:指定绘制点的类型,如“p”表示点图,“l”表示线图,“o”表示点线图等。lty
:指定线条的类型,如1表示实线,2表示虚线,3表示点线等。pch
:指定点的形状,如1表示圆形,2表示三角形,3表示正方形等。cex
:指定点的大小。lwd
:指定线条的宽度。
例如,绘制一个具有特定特征的散点图:
x <- rnorm(100)
y <- rnorm(100)
plot(x, y, pch = 19, cex = 2, lwd = 2, col = "blue")
使用par()
函数保存设置
par()
函数用于设置图形参数,但它不会立即生成图形。相反,它保存当前的设置,用于后续的所有绘图。
par(pch = 19, cex = 2, lwd = 2, col = "blue")
x <- rnorm(100)
y <- rnorm(100)
plot(x, y)
注意事项
- 确保在使用
par()
函数后,调用plot()
函数来生成图形。 par()
设置会覆盖plot()
函数中的相同设置。
622调整符号与线条
R中可以通过调整点符号和线条特征来创建更个性化的图形。
调整点符号
-
pch
参数用于指定点的形状。例如,pch = 1
表示圆形,pch = 2
表示三角形,等等。plot(x, y, pch = 19) # 绘制一个具有特定形状的点
调整点的大小
-
cex
参数用于调整点的大小。例如,cex = 2
表示将点的大小调整为默认大小的两倍。plot(x, y, pch = 19, cex = 2) # 绘制一个更大的点
调整线条类型
-
lty
参数用于指定线条的类型。例如,lty = 1
表示实线,lty = 2
表示虚线,等等。plot(x, y, type = "l", lty = 2) # 绘制一条虚线
调整线条宽度
-
lwd
参数用于调整线条的宽度。例如,lwd = 2
表示将线条的宽度调整为默认宽度的两倍。plot(x, y, type = "l", lwd = 2) # 绘制一条更粗的线条
注意事项
- 确保在使用这些参数时,图形中的其他元素(如坐标轴标签、标题等)也得到适当调整,以保持整体的一致性。
623调整颜色
R中可以通过多种方式来调整图形颜色,以增强图形的表现力和可读性。
调整坐标轴颜色
-
col.axis
:设置坐标轴字符的颜色。plot(x, y, col.axis = "blue") # 将坐标轴字符颜色设置为蓝色
调整标题和标签颜色
-
col.lab
:设置x和y坐标标记的颜色。 -
col.main
:设置图形标题的颜色。 -
col.sub
:设置副标题的颜色。plot(x, y, col.lab = "red", col.main = "green", col.sub = "purple")
调整前景色和背景色
-
fg
:设置绘图的前景色。 -
bg
:设置绘图的背景色。plot(x, y, fg = "white", bg = "black") # 将前景色设置为白色,背景色设置为黑色
使用colors()
函数查看颜色名
-
colors()
函数可以列出R中可用的颜色名。colors()
使用palette()
函数设置和查看调色板
-
palette()
函数用于设置和查看调色板。 -
palette(rainbow(n))
:从光谱色中均匀选取n种颜色组成向量。 -
palette("default")
:恢复默认调色板。palette() palette(rainbow(5)) # 创建一个包含5种颜色的调色板
绘制调色板
-
使用
pie()
函数可以绘制调色板,展示当前调色板中的颜色。pie(rep(1, length(palette())), labels = seq_along(palette()), col = palette())
注意事项
- 颜色可以使用颜色名称、RGB值或十六进制代码表示。
- 确保颜色设置与图形的其他元素(如线条、点符号等)协调一致。
624调整标签与标题文本
R中可以通过title()
函数来调整图形中的标题和标签文本。
title()
函数的基本用法
title()
函数的基本格式如下:
title(main = "", sub = "", xlab = "", ylab = "", line = 1, col.main = NULL, col.sub = NULL, col.lab = NULL, font.main = NULL, font.sub = NULL, font.lab = NULL)
main
:主标题。sub
:副标题。xlab
:x轴标签。ylab
:y轴标签。line
:标题的行数,一般为1或2。col.main
:主标题颜色。col.sub
:副标题颜色。col.lab
:标签颜色。font.main
:主标题字体。font.sub
:副标题字体。font.lab
:标签字体。
示例
-
设置一个带副标题的主标题:
title(main = "主标题", sub = "副标题", col.main = "blue", col.sub = "green")
-
设置x轴和y轴的标签:
xlab("X轴标签") ylab("Y轴标签")
注意事项
- 确保标题和标签的设置与图形的其他元素(如颜色、线条等)协调一致。
6.3其他自定义元素
631坐标轴
R中的坐标轴可以通过多种方式进行调整,以满足特定的绘图需求。
屏蔽默认坐标轴
-
使用
axes = FALSE
参数在plot()
函数中屏蔽默认的坐标轴。plot(x, y, axes = FALSE)
调整坐标轴参数
-
axis()
函数用于调整坐标轴的细节。axis(side, at = , labels = , pos = , lty = , col = )
side
:坐标轴的位置,取值为1、2、3、4,分别表示下、左、上、右。at
:选择在坐标轴上显示的刻度标记位置。labels
:在刻度标记位置显示的标签。如果为 NULL,则使用at
的值。tick
:一个逻辑值,表示是否绘制刻度线。line
:此参数可选择坐标轴的长度和位置。当值为负数时,坐标轴向内向图形区域移动。当值为正数时,坐标轴向外移动。pos
:坐标轴标签的位置。outer
:表示是否把坐标轴画到图像外面。lty
:刻度线的类型。col
:标签和刻度线的颜色。
示例
-
设置一个特定位置和颜色的坐标轴:
axis(3, at = 1:5, labels = c("A", "B", "C", "D", "E"), col = "red", lty = 2)
-
在左侧坐标轴上绘制刻度线:
axis(2, tick = TRUE)
注意事项
- 确保坐标轴的调整与图形的其他元素(如标题、标签、颜色等)协调一致。
632次要刻度线
在R中,可以通过安装和使用特定包来添加次要刻度线,以提高坐标轴的精确度和可读性。
安装必要的包
首先,需要安装Hmsic
包来添加次要刻度线。
install.packages("Hmsic")
library(Hmsic)
使用minor.tick()
添加次要刻度线
-
minor.tick()
函数用于在坐标轴上添加次要刻度线。minor.tick(nx = 5, ny = 5, tick.ratio = 0.5, tick.col = "gray")
nx
:x轴次要刻度线的个数。ny
:y轴次要刻度线的个数。tick.ratio
:次要刻度线长度与主要刻度线长度的比率。tick.col
:次要刻度线的颜色。
示例
-
添加x轴和y轴的次要刻度线,设置颜色为灰色:
minor.tick(nx = 5, ny = 5, tick.ratio = 0.5, tick.col = "gray")
注意事项
- 确保在添加次要刻度线之前,坐标轴已经被正确设置。
- 次要刻度线的数量、长度和颜色可以根据需要进行调整。
633网格线
abline()
函数是R中用于绘制直线和网格线的常用函数。
abline()
函数的基本用法
abline()
函数的基本格式如下:
abline(a = 0, b = 1, h = NULL, v = NULL, coef = NULL, untf = FALSE, ...)
a
和b
:直线的截距和斜率,它们指向y = a + bx
。默认为y = x
。其中,当斜率为0(即水平直线)时,a
表示直线在y
轴上的截距;当截距为0(即竖直直线)时,b
表示无穷大的斜率。h
:横向的直线的位置。它可以是一组坐标,表示要绘制的水平线的y
值。例如,h = c(1, 2, 3)
表示在y = 1, 2, 3
三个位置画直线。v
:纵向的直线的位置。它可以是一组坐标,表示要绘制的垂直线的x
值。coef
:一个包含两个元素的向量,表示截距和斜率。untf
:逻辑变量。如果为TRUE
,则x
和y
的向量将被视为未转换(即不设置坐标系)。
示例
-
添加x轴和y轴的网格线:
abline(h = 1:3, v = 1:3)
-
使用
coef
参数添加一条斜率为2,截距为1的直线:abline(coef = c(1, 2))
注意事项
- 确保网格线的添加与图形的其他元素(如坐标轴、标题、标签等)协调一致。
634叠加绘图
叠加绘图是一种在同一图形窗口中绘制多个图层的方法,用于比较和展示不同数据集或同一数据集的不同视图。
绘制基础图形
首先,绘制一个基础图形。例如,绘制x和y的关系图:
x <- 1:20
y <- (1:20)^2
plot(x, y, type = "b")
这里,type = "b"
表示绘制点图和线图。
叠加其他图形
接着,可以叠加其他图形。例如,添加蓝色的点图和红色的线图:
points(1:20, seq(1, 200, length.out = 20), col = "blue", pch = 17)
lines(1:20, seq(1, 200, length.out = 20), col = "red")
points()
函数用于在现有图形上绘制点图。lines()
函数用于在现有图形上绘制线图。
示例结果
执行上述代码后,将会在同一图形窗口中看到一个基础的点线图,以及两个叠加的图形:蓝色点图和红色线图。
注意事项
- 确保在绘制每个图形时,坐标轴和图形的其他元素(如标题、标签等)已经正确设置。
- 叠加的图形应该有清晰的区分,如使用不同的颜色和线型。
635图例
legend()
函数是R中用于在图形中添加图例的函数。
legend()
函数的基本用法
legend()
函数的基本格式如下:
legend(x, y = NULL, legend, fill = NULL, col = par("col"), pch, title=NULL, ...)
x
和y
:图例的位置。legend
:图例中要显示的文本或符号。fill
:图例中不同类别填充的颜色。col
:图例中不同类别的颜色。pch
:图例中不同类别的点形符号。title
:图例的标题。
示例
-
添加一个自定义的图例:
legend(x = 0.5, y = 385, legend = c("power", "linear"), col = c("black", "blue"), pch = c(1, 17), text.col = c("black", "red"), title = "My Legend")
这个例子中,图例显示了两个类别(“power” 和 “linear”),每个类别用不同的颜色、点形符号和文本颜色表示。
注意事项
- 确保图例的位置和内容与图形的其他元素(如坐标轴、标题、标签等)协调一致。
636标注
在R中,可以通过多种方式在图形中添加标注,以增强图形的信息传递和解释性。
在绘图区内部添加文字
-
text()
函数用于在绘图区内部添加文字。text(x, y, labels, cex = 1.2, col = "blue")
x
和y
:标注的位置。labels
:要添加的文字。cex
:文字的大小。col
:文字的颜色。
例如,在x=10, y=200的位置添加蓝色文字,文字大小为默认大小的1.2倍:
text(10, 200, expression(y == x^2), cex = 1.2, col = "blue")
在边框上添加文字
-
mtext()
函数用于在图形边框上添加文字。mtext(text, side, font)
text
:要添加的文字。side
:文字出现在边框的哪一侧,取值为1(下)、2(左)、3(上)、4(右)。font
:文字的字体。
例如,在边框的不同位置添加文字,并设置不同的字体:
for (s in 1:4) { mtext(paste("mtext(..., side=", s, ")"), side = s, font = s) }
这将分别在边框的下、左、上、右四个位置添加文字,并使用不同的字体。
注意事项
- 确保标注的位置和内容与图形的其他元素(如坐标轴、标题、标签等)协调一致。
在R中,可以通过多种方式在图形中添加标注,以增强图形的信息传递和解释性。
在绘图区内部添加文字
-
text()
函数用于在绘图区内部添加文字。text(x, y, labels, cex = 1.2, col = "blue")
x
和y
:标注的位置。labels
:要添加的文字。cex
:文字的大小。col
:文字的颜色。
例如,在x=10, y=200的位置添加蓝色文字,文字大小为默认大小的1.2倍:
text(10, 200, expression(y == x^2), cex = 1.2, col = "blue")
-
在边框上添加文字
-
mtext()
函数用于在图形边框上添加文字。mtext(text, side, font)
text
:要添加的文字。side
:文字出现在边框的哪一侧,取值为1(下)、2(左)、3(上)、4(右)。font
:文字的字体。
例如,在边框的不同位置添加文字,并设置不同的字体:
for (s in 1:4) { mtext(paste("mtext(..., side=", s, ")"), side = s, font = s) }
这将分别在边框的下、左、上、右四个位置添加文字,并使用不同的字体。
-
注意事项
-
确保标注的位置和内容与图形的其他元素(如坐标轴、标题、标签等)协调一致。
6.4描述性统计图
641柱形图
barplot()
函数是R中用于创建柱形图的函数,适用于展示不同类别或组的数据比较。
barplot()
函数的基本用法
barplot()
函数的基本格式如下:
barplot(height, names.arg, beside = FALSE, horiz = FALSE, col = NULL, border = "white", density = NULL, angle = 45, xlim = NULL, ylim = NULL, xlab = NULL, ylab = NULL, axes = TRUE, axisnames = TRUE, cex.names = 1, ...)
height
:一个数值向量,表示每种类别的高度。names.arg
:一个字符向量,包含每个条形的标签。beside
:逻辑标量,确定是否在同一坐标轴上放置多个条形组。如果为TRUE,则子序列(或方块)被放置在一起的相邻位置,成为组。horiz
:逻辑标量,确定绘图是否为水平(TRUE)或垂直(FALSE)。col
:用于填充柱状图的颜色向量。一般来说,会填充每个例子组成员的不同的颜色。border
:用于柱形边框线的颜色向量。density
:一个介于0和1之间的数字,表示填充模式的密度。0表示没有填充,1表示100%的填充。angle
:用于柱状边线的夹角。xlim
,ylim
:x轴和y轴的范围。xlab
,ylab
:x轴和y轴标签。axes
:逻辑标量,确定是否绘制坐标轴。axisnames
:逻辑标量,确定是否绘制坐标轴刻度上的标签。cex.names
:每个组名的缩放比例。
示例
-
创建一个基本的柱形图:
barplot(c(5, 10, 15), names.arg = c("Group1", "Group2", "Group3"))
-
自定义柱形图,包括颜色、边框和标签:
barplot(c(5, 10, 15), names.arg = c("Group1", "Group2", "Group3"), col = c("blue", "green", "red"), border = "black", xlab = "Groups", ylab = "Values")
注意事项
- 确保柱形图的参数设置与数据的性质和分析目的相匹配。
642饼图
pie()
函数是R中用于创建饼图的函数,适用于展示不同类别或组的数据比例。
pie()
函数的基本用法
pie()
函数的基本格式如下:
pie(x, labels = names(x), clockwise = FALSE, radius = 1, main = NULL, col = NULL, border = NULL, lty = NULL, lwd = NULL, init.angle = if(clockwise) 90 else 0, density = NULL, angle = 45, xlim = NULL, ylim = NULL, ...)
x
:一个数值向量,表示每个分片的大小。labels
:一个字符向量,表示每个分片的标签。clockwise
:一个逻辑值,指定扇形是否顺时针绘制。默认是逆时针。radius
:一个数字,指定饼图的半径大小。main
:一个字符串,指定饼图的主标题。col
:一个颜色向量,用于指定每个类别的填充颜色。border
:一个颜色向量,用于指定饼图的边框线颜色。lty
:一个数值,用于设置饼图的线型。lwd
:一个数值,用于设置饼图的线宽。init.angle
:一个数值,用于指定饼图的初始角度(每个类别的起始角度)。density
:指定填充颜色的线密度,介于0和1之间。angle
:一个数值,用于创建3D饼图的旋转角度。xlim
,ylim
:x轴和y轴的范围。
示例
-
创建一个基本的饼图:
pie(c(30, 20, 50))
-
自定义饼图,包括颜色、标签和旋转角度:
pie(c(30, 20, 50), labels = c("A", "B", "C"), col = c("blue", "green", "red"), angle = 45)
注意事项
- 确保饼图的参数设置与数据的性质和分析目的相匹配。
643直方图
hist()
函数是R中用于创建直方图的函数,适用于展示数据的分布情况。
hist()
函数的基本用法
hist()
函数的基本格式如下:
hist(x, breaks = "Sturges", freq = TRUE, probability = FALSE, main = NULL, xlab = NULL, ylab = NULL, xlim = NULL, ylim = NULL, ...)
x
:一个数值向量,表示要绘制的直方图数据。breaks
:指定数据分组的区间数量。比如"Sturges"
可做自动选择,或者以数值向量表示每个bin的边缘位置,或者在指定区间宽度的情况下,可以使用一个数字来表示最小和最大值。freq
:一个逻辑值,指定y轴上显示计数(TRUE
)还是相对频率(FALSE
)。probability
:一个逻辑值,指定是否绘制针对密度曲线的直方图而不是计数(TRUE
)。main
:一个字符串,表示直方图的标题。xlab
:一个字符串,表示x轴的标签。ylab
:一个字符串,表示y轴的标签。xlim
:x轴范围的长度为2的数值向量,表示显示范围的最小值和最大值。ylim
:y轴范围的长度为2的数值向量,表示显示范围的最小值和最大值。
示例
-
创建一个基本的直方图:
hist(rnorm(1000), main = "Basic Histogram")
-
自定义直方图,包括分组数、频率和标题:
hist(rnorm(1000), breaks = 10, freq = TRUE, main = "Customized Histogram")
注意事项
- 确保直方图的参数设置与数据的性质和分析目的相匹配。
第七章:统计与回归分析
7.1定性数据与定量数据
711定性数据
定性数据,也称为分类数据,用于表示事物的类别属性。在R中,可以轻松地处理这类数据。
计算频数
-
table()
函数用于计算各分类的频数。table(数据集名)
例如,计算数据集
my_data
中各分类的频数:table(my_data$分类变量)
计算相对频数
-
相对频数是频数与数据集总行数的比例。
相对频数 <- 频数 / nrow(数据集名)
计算特定分类的平均值
-
计算特定分类(如“setosa”)的平均值。
s_shuju <- 数据集名[数据集名$Species == "setosa", ] mean(s_shuju$Sepal.Length)
这段代码首先筛选出属于“setosa”类别的数据,然后计算该数据集中
Sepal.Length
列的平均值。
示例
-
假设我们有一个数据集
iris
,其中包含花萼长度和物种信息。s_shuju <- iris[iris$Species == "setosa", ] mean(s_shuju$Sepal.Length)
注意事项
- 在处理定性数据时,确保理解数据的结构和分类方式。
- 针对不同的分析目的,选择合适的统计方法。
712定量数据
定量数据,也称为连续型数值数据,用于表示可以度量的属性。在R中,可以对这类数据进行各种统计分析。
计算数据的范围
-
range()
函数用于计算数据的上下界。range(duration)
例如,计算
duration
变量的取值范围。
将变量活动范围分成不重叠的区间
-
seq()
函数用于生成数值序列。breaks <- seq(1.5, 5.5, by = 0.5)
例如,生成一个数值序列,起始值为1.5,终止值为5.5,步长为0.5。
对变量进行区间分类
-
cut()
函数用于将变量按照指定的间隔进行分割。duration.cut <- cut(duration, breaks, right = FALSE)
例如,将
duration
变量按照breaks
所定义的间隔进行分割。
得到统计信息
-
table()
函数用于计算每个区间的频数。duration.freq <- table(duration.cut)
例如,根据
duration.cut
变量中的值计算每个区间的频数。
导出结果
-
使用
print()
函数输出结果。print(duration.freq)
绘制频数直方图
-
hist()
函数用于绘制频数直方图。hist(duration, right = FALSE, main = "老忠实喷发次数", xlab = "持续时间(分钟)", ylab = "频数")
例如,绘制
duration
变量的频数直方图。
注意事项
- 在处理定量数据时,确保选择合适的区间划分和统计方法。
- 直方图的绘制应与数据的性质和分析目的相匹配。
7.2数据的数值度量
数值度量是描述数据集中趋势和离散程度的重要统计量。在R中,可以轻松计算这些度量。
721 均值
-
mean()
函数用于计算数据的均值。mean(数据集名)
例如,计算数据集
my_data
的均值。
722 中位数、四分位数、百分位数
-
median()
函数用于计算中位数。median(数据集名)
例如,计算数据集
my_data
的中位数。 -
quantile()
函数用于计算四分位数和百分位数。quantile(数据集名, c(.25, .75)) # 计算中位数和四分位数 quantile(数据集名, c(0.5)) # 计算中位数 quantile(数据集名, c(0.1, 0.9)) # 计算第一个和第三个四分位数 quantile(数据集名, c(0.01, 0.99)) # 计算第一个和第九十九个百分位数
例如,计算数据集
my_data
的中位数和四分位数。
723 四分位距
-
IQR()
函数用于计算四分位距。IQR(数据集名)
例如,计算数据集
my_data
的四分位距。
724 方差与标准差
-
var()
函数用于计算方差。var(数据集名)
例如,计算数据集
my_data
的方差。 -
sd()
函数用于计算标准差。sd(数据集名)
例如,计算数据集
my_data
的标准差。
725 协方差
-
cov()
函数用于计算两个向量的协方差。cov(A, B)
例如,计算两个向量
A
和B
的协方差。
726 相关系数
-
cor()
函数用于计算两个向量的相关系数。cor(A, B)
例如,计算两个向量
A
和B
的相关系数。
示例
-
假设我们有一个数据集
my_data
,包含数值型变量。mean(my_data) # 计算均值 median(my_data) # 计算中位数 quantile(my_data, c(0.25, 0.75)) # 计算四分位数 IQR(my_data) # 计算四分位距 var(my_data) # 计算方差 sd(my_data) # 计算标准差 cov(A, B) # 计算协方差 cor(A, B) # 计算相关系数
这些函数可以用于各种数据分析和统计任务中,帮助理解数据的分布和特征。
注意事项
- 在计算数值度量时,确保理解数据的性质和分布。
- 选择合适的度量来描述数据的中心趋势和离散程度。
7.3概率分布与假设检验
731概率分布
R语言提供了一系列函数来生成和操作各种概率分布。这些函数通常以d
、p
、q
、r
开头,分别代表概率密度函数(PDF)、累积分布函数(CDF)、分位数函数和随机数生成函数。
正态分布(Normal Distribution)
-
dnorm()
:返回正态分布的概率密度。 -
pnorm()
:返回正态分布的累积分布。 -
qnorm()
:返回正态分布的分位数。 -
rnorm()
:生成正态分布的随机数。dnorm(x, mean = 0, sd = 1, log = FALSE) pnorm(q, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE) qnorm(p, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE) rnorm(n, mean = 0, sd = 1)
其他常见分布
beta()
:Beta分布。binom()
:二项式分布。cauchy()
:柯西分布。chisq()
:卡方分布。exp()
:指数分布。f()
:F分布。gamma()
:伽马分布。geom()
:几何分布。logis()
:逻辑分布。lnorm()
:对数正态分布。pois()
:泊松分布。t()
:学生t分布。unif()
:均匀分布。weib()
:威布尔分布。
示例
-
生成一个正态分布的随机数向量,均值为0,标准差为1,长度为10:
set.seed(123) # 设置随机数种子 normal_random <- rnorm(10, mean = 0, sd = 1) print(normal_random)
注意事项
- 在使用这些函数时,确保理解每个分布的参数含义。
- 根据数据的特性和分析需求选择合适的分布。
732统计假设检验
统计假设检验是用于评估样本数据与假设模型之间是否存在显著差异的方法。下面是一个使用R进行假设检验的示例。
下尾检验
下尾检验用于检验样本均值是否小于某个假设的均值。
- 样本均值
xbar
:9900 - 假设的均值
mu0
:10000 - 总体标准差
sigma
:120 - 样本规模
n
:30
xbar <- 9900
mu0 <- 10000
sigma <- 120
n <- 30
z <- (xbar - mu0) / (sigma / sqrt(n))
alpha <- 0.05
z.alpha <- qnorm(1 - alpha)
-z.alpha
上尾检验
上尾检验用于检验样本均值是否大于某个假设的均值。
- 样本均值
xbar
:2.1 - 假设的均值
mu0
:2 - 总体标准差
sigma
:0.25 - 样本规模
n
:35
xbar <- 2.1
mu0 <- 2
sigma <- 0.25
n <- 35
z <- (xbar - mu0) / (sigma / sqrt(n))
alpha <- 0.05
z.alpha <- qnorm(1 - alpha)
z.alpha
双尾检验
双尾检验用于检验样本均值是否与某个假设的均值有显著差异,不论是大于还是小于。
- 样本均值
xbar
:14.6 - 假设的均值
mu0
:15.4 - 总体标准差
sigma
:2.5 - 样本规模
n
:35
xbar <- 14.6
mu0 <- 15.4
sigma <- 2.5
n <- 35
z <- (xbar - mu0) / (sigma / sqrt(n))
alpha <- 0.05
z.half.alpha <- qnorm(1 - alpha / 2)
c(-z.half.alpha, z.half.alpha)
示例结果
- 下尾检验的临界值为
-1.644854
。 - 上尾检验的临界值为
1.644854
。 - 双尾检验的临界值为
-1.9600
和1.9600
。
注意事项
- 在进行假设检验时,确保样本数据和假设模型符合统计学的要求。
- 根据研究目的和数据特性选择合适的检验方法。
7.4回归分析
回归分析是一种统计方法,用于探究自变量(或多个自变量)与因变量之间的定量关系。
一元线性回归
一元线性回归分析用于研究一个自变量和一个因变量之间的线性关系。它假设因变量是自变量的线性函数。
多元线性回归
多元线性回归分析用于研究两个或两个以上自变量和一个因变量之间的线性关系。它假设因变量是多个自变量的线性组合。
示例
-
一元线性回归示例:
# 假设数据集包含一个自变量 x 和一个因变量 y # 使用 lm() 函数进行线性回归分析 model <- lm(y ~ x, data = my_data) summary(model)
-
多元线性回归示例:
# 假设数据集包含两个自变量 x1 和 x2,以及一个因变量 y # 使用 lm() 函数进行线性回归分析 model <- lm(y ~ x1 + x2, data = my_data) summary(model)
注意事项
- 在进行回归分析时,确保自变量和因变量之间存在实际的相关性。
- 选择合适的模型拟合数据,并检查模型的假设是否得到满足。
741一元线性回归
一元线性回归分析用于研究一个自变量和一个因变量之间的线性关系。下面是一个使用R进行一元线性回归分析的示例。
构建模型
-
首先,使用
lm()
函数拟合线性回归模型。eruption.lm <- lm(eruptions ~ waiting, data = faithful)
这个模型假设喷发时间
eruptions
是等待时间waiting
的线性函数。 -
然后,使用
coefficients()
函数获取模型的系数估计值。coeffs <- coefficients(eruption.lm)
coeffs
将包含截距b0
和斜率b1
。
绘图展示
-
使用
plot()
函数绘制散点图和回归线。plot(eruptions ~ waiting, faithful, col = "blue", main = "老忠实线性回归结果", xlab = "等待时间", ylab = "持续喷发时间") abline(fit, col = "red")
这里,
abline(fit, col = "red")
函数用于绘制回归线。 -
模型评估
-
使用
predict()
函数进行预测。waiting <- 80 duration <- coeffs[1] + coeffs[2] * waiting
例如,预测等待时间为80分钟的喷发持续时间。
-
计算判定系数(R²值)来评估模型的拟合程度。
summary(eruption.lm)$r.squared
-
进行显著性检验。
summary(eruption.lm)
这将为每个系数提供p值,用于判断其是否显著。
示例结果
- 预测等待时间为80分钟的喷发持续时间。
- 判定系数(R²值)提供模型拟合优度的度量。
- 显著性检验结果帮助判断模型系数是否有效。
注意事项
- 在进行一元线性回归分析时,确保自变量和因变量之间存在线性关系。
- 检查模型的假设是否得到满足,如线性、独立性、同方差性等。
742多元线性回归
多元线性回归分析用于研究两个或两个以上自变量和一个因变量之间的线性关系。下面是一个使用R进行多元线性回归分析的示例。
构建多元线性回归模型
-
使用
lm()
函数拟合多元线性回归模型。Boston.lm <- lm(medv ~ ., data = BostonHousing)
这里,
medv
是因变量,而BostonHousing
数据集中的所有其他变量都是自变量。
模型评估
-
计算判定系数(R²值)来评估模型的拟合程度。
summary(Boston.lm)$r.squared
R²值表示模型解释因变量的变异性的比例。
示例结果
- R²值提供模型拟合优度的度量。
注意事项
- 在进行多元线性回归分析时,确保自变量和因变量之间存在实际的相关性。
- 检查模型的假设是否得到满足,如线性、独立性、同方差性等。
743逻辑回归
逻辑回归是一种用于二分类问题的统计方法,它用于估计一个事件发生的概率。下面是一个使用R进行逻辑回归分析的示例。
构建逻辑回归模型
-
使用
glm()
函数拟合逻辑回归模型。am.glm <- glm(formula = am ~ hp + wt, data = mtcars, family = binomial)
这里,
am
是因变量,表示汽车的传动类型(0=自动,1=手动),而hp
和wt
是自变量,分别表示汽车的马力和重量。
模型预测
-
使用
predict()
函数进行预测。newdata <- data.frame(hp = 120, wt = 2.8) predict(am.glm, newdata, type = "response")
这里,
type = "response"
参数用于输出预测的概率值,即逻辑回归模型中指定的似然函数类型为二项式,需要输出预测为1的概率。
示例结果
- 预测120马力的发动机和2800磅重量的汽车属于手动类型的概率。
注意事项
- 在进行逻辑回归分析时,确保自变量和因变量之间存在实际的相关性。
- 检查模型的假设是否得到满足,如线性、独立性等。
第八章:统计机器学习
8.1特征空间与距离
811特征空间与距离
在数据分析中,每个样本通常通过一组特征属性来描述,这些特征可以看作是样本在特征空间中的坐标。样本之间的距离反映了它们在特征空间中的相似程度。
距离的定义
- 距离是样本空间中点之间的间隔,用来衡量点之间的相似性。
- 不同的距离度量反映了不同的相似性度量标准。
距离的计算
-
曼哈顿距离(Manhattan Distance):
其中,p和q是特征空间中的两个点,是特征空间中的两个点,和和
是它们的第是它们的第i个特征。
-
欧几里得距离(Euclidean Distance):
这是最常用的距离度量,反映了点之间的直线距离。 -
Minkowski距离(Minkowski Distance):
当p = 1 时,得到曼哈顿距离;当 p = 2 时,得到欧几里得距离。
在R中计算距离
-
在R中,可以使用
dist()
函数计算点与点之间的距离。dist(x, method = "euclidean", diag = FALSE, upper = FALSE, p = 2)
x
:一个n行m列的矩阵,表示n个m维的数据点。method
:计算距离的方法,如"euclidean"(欧几里得距离)、“manhattan”(曼哈顿距离)等。diag
:是否包含对角线元素,默认为FALSE。upper
:是否只输出矩阵的上三角,默认为FALSE。p
:Minkowski求范数时的参数,默认为2,即欧几里得距离。
数据标准化
-
在计算距离之前,通常需要对数据进行标准化处理,以消除不同特征的量纲和取值范围差异。
scale(x, center = TRUE, scale = TRUE)
x
:需要标准化的向量、矩阵或数据框。center
:是否对数据进行中心化处理,默认为TRUE。scale
:是否对数据进行缩放处理,默认为TRUE。
示例结果
- 执行
dist()
函数计算样本之间的距离。 - 执行
scale()
函数对数据进行标准化处理。
注意事项
- 在计算距离时,选择合适的距离度量方法对于后续的分析和建模非常重要。
- 数据标准化有助于提高距离计算的准确性和模型的性能。
812KNN分类算法
KNN(K-Nearest Neighbors)分类是一种基于实例的机器学习算法,它通过比较新样本与训练集中样本的相似度来进行分类。
KNN算法原理
- KNN分类的基本思想是,如果一个未知样本在特征空间中的K个最近邻居大多数属于某一个类别,则该未知样本也属于这个类别。
- KNN分类依赖于距离度量,常用的距离度量有曼哈顿距离、欧几里得距离等。
R中的KNN实现
-
在R中,可以使用
class
包中的knn()
函数实现KNN分类。library(class) knn(train, test, cl, k = 1, l = 0, prob = FALSE, use.all = TRUE)
train
:训练数据集,通常是一个数据框或矩阵,表示特征向量。test
:测试数据集,也是一个数据框或矩阵,表示需要预测的特征向量。cl
:训练数据的类别标签,通常是一个因子向量或字符向量。k
:K的值,即选择最近邻居的数量,默认为1。l
:平滑因子,控制类别的平滑程度,默认为0。prob
:是否需要估计后验概率,默认为FALSE。use.all
:是否使用所有邻居,默认为TRUE。
knn()
函数返回一个向量,表示每个测试集实例的分类结果。
示例结果
- 执行
knn()
函数对测试数据进行分类。
注意事项
- KNN分类的性能很大程度上取决于K值的选择和距离度量的选择。
- 在实际应用中,可能需要对数据进行预处理,如标准化或特征选择。
8.2聚类算法
821k均值聚类
K均值聚类是一种基于距离的聚类算法,用于将相似的样本聚集在一起形成簇。
K均值聚类原理
- K均值聚类的基本思想是将数据点划分为K个簇,使得簇内的点相似度尽可能高,而簇间的点相似度尽可能低。
- 算法的步骤包括:选择K个初始簇心,计算每个数据点到各个簇心的距离,将数据点分配到最近的簇心,计算每个簇的新簇心,重复分配和计算直到簇心不再改变或达到最大迭代次数。
R中的K均值聚类实现
-
在R中,可以使用
stats
包中的kmeans()
函数实现K均值聚类。kmeans(x, centers, iter.max = 10, nstart = 1)
x
:用于聚类的数据矩阵或数据框。centers
:类别的个数或初始聚类中心。iter.max
:最大迭代次数,默认为10。nstart
:进行聚类的次数,默认为1。
kmeans()
函数返回一个包含簇中心和簇分配结果的对象。
示例结果
- 执行
kmeans()
函数对数据进行聚类分析。
注意事项
- K值的选择对聚类结果有重要影响,通常需要根据数据特性进行尝试。
- K均值聚类对初始簇心的选择敏感,
nstart
参数可以用来尝试不同的初始簇心。
822层次聚类
层次聚类是一种将样本按照其相似程度进行层次划分的方法,它通过比较样本之间的距离来进行聚类。
层次聚类原理
- 层次聚类的基本思想是,从单个样本开始,逐步合并距离最近的样本,形成簇,直到所有样本都属于同一簇。
- 算法的步骤包括:计算样本间的距离,将距离最近的两个样本合并为一个簇,更新距离矩阵,重复合并和更新直到所有样本合并为一个簇。
R中的层次聚类实现
-
在R中,可以使用
stats
包中的hclust()
函数实现层次聚类。hclust(d, method = "ward.D", members = NULL)
d
:数据矩阵或距离矩阵。method
:指定聚类的方法,如"ward.D"(Ward方差最小化)、“complete”(最大距离法)等。members
:提供一个数值向量指定每个样本所属的组别。
hclust()
函数返回一个层次聚类树,可以用来查看聚类的层次结构。
示例结果
- 执行
hclust()
函数对数据进行层次聚类。
注意事项
- 层次聚类算法不要求预先指定簇的数量,但簇的合并顺序会影响最终结果。
- 选择合适的距离度量和合并方法对聚类结果有重要影响。
8.3分类算法
831决策树
决策树是一种常见的机器学习算法,用于分类和回归任务。下面是一个使用R中的rpart()
函数构建决策树的示例。
构建决策树
-
使用
rpart()
函数拟合决策树模型。rpart(formula, data, weights, subset, na.action, method, model, x, y, parms, control, cost, ...)
formula
:表示因变量与自变量关系的响应公式。data
:用于解释公式中的变量名,通常是包含formula中变量的数据框。weights
:案例权重。subset
:表示哪些数据行构成的子集可以用于拟合。na.action
:处理缺失项的方法。method
:指定方法,如"anova"、“poisson”、“class"或"exp”。model
:是否保存模型,默认为FALSE。x
:是否保存模型参数,默认为FALSE。y
:是否保存因变量,默认为TRUE。parms
:额外的参数。control
:控制参数。cost
:成本参数。
rpart()
函数返回一个rpart
对象,表示决策树模型。
绘制决策树
-
使用
rpart.plot()
函数绘制决策树。rpart.plot(决策树对象)
例如,使用
rpart.plot()
绘制上述rpart
对象。
示例结果
- 执行
rpart()
函数构建决策树模型。 - 使用
rpart.plot()
函数绘制决策树。
注意事项
- 在构建决策树时,确保自变量和因变量之间存在实际的相关性。
- 选择合适的参数和方法以获得最佳模型性能。
832朴素贝叶斯方法
朴素贝叶斯分类是一种基于贝叶斯定理的分类方法,它假设特征之间相互独立。下面是一个使用R中的naiveBayes()
函数实现朴素贝叶斯分类的示例。
构建朴素贝叶斯模型
-
使用
naiveBayes()
函数拟合朴素贝叶斯分类模型。naiveBayes(x, y, formula, data, laplace = 0, ..., subset, na.action = na.pass)
x
:特征矩阵。y
:响应变量。formula
:表示因变量与自变量关系的响应公式。data
:用于解释公式中的变量名,通常是包含formula中变量的数据框。laplace
:拉普拉斯估计值,默认为0。subset
:抽取要分析的训练数据子集。na.action
:处理缺失值的方法。
naiveBayes()
函数返回一个naiveBayes
对象,表示朴素贝叶斯模型。
模型预测
-
使用
predict()
函数进行预测。predict(朴素贝叶斯模型对象, newdata, type = "class")
例如,使用上述
naiveBayes
对象对新数据newdata
进行预测。
示例结果
- 执行
naiveBayes()
函数构建朴素贝叶斯模型。 - 使用
predict()
函数进行模型预测。
注意事项
- 在构建朴素贝叶斯模型时,确保自变量和因变量之间存在实际的相关性。
- 选择合适的参数和方法以获得最佳模型性能。
833支持向量机SVM
支持向量机(SVM)是一种强大的机器学习算法,广泛用于分类和回归任务。下面是一个使用R中的svm()
函数实现SVM的示例。
构建SVM模型
-
使用
svm()
函数拟合SVM模型。svm(formula, data = NULL, ..., type, kernel)
formula
:表示因变量与自变量关系的响应公式。data
:用于解释公式中的变量名,通常是包含formula中变量的数据框。kernel
:指定核函数类型,如"linear"(线性核)、“polynomial”(多项式核)、“radial”(径向基核)、“sigmoid”(Sigmoid核)。type
:指定模型类型,如分类问题中的"C-classification"(硬间隔分类,默认)或"nu-classification"(软间隔分类),文本分类中的"one-classification",回归问题中的"eps-regression"(ε-不敏感损失函数,默认)或"nu-regression"。
svm()
函数返回一个svm
对象,表示SVM模型。
模型预测
-
使用
predict()
函数进行预测。predict(SVM模型对象, newdata)
例如,使用上述
svm
对象对新数据newdata
进行预测。
示例结果
- 执行
svm()
函数构建SVM模型。 - 使用
predict()
函数进行模型预测。
注意事项
- 在构建SVM模型时,选择合适的核函数和参数对于模型的性能至关重要。
- SVM特别适用于小数据集和高维特征空间。
8.4集成学习
841基本方法
集成学习是一种通过组合多个弱学习器来构建强学习器的机器学习方法。这种方法的关键在于利用单个学习器的多元性来提高整体性能。
集成学习的基本策略
- 均值法:在回归问题中,对所有单一算法的预测值取均值。在分类问题中,对所有类别出现的概率求均值。
- 投票法:在分类问题中,选取票数最多的类别作为最终预测结果。
- 加权平均法:给不同的算法赋予不同的权值,对它们的预测结果做加权平均,将加权平均值作为最终输出。
R中的集成学习实现
- R语言提供了多种集成学习算法,如随机森林(RandomForest)、支持向量机(SVM)等。
几种集成学习策略
- Bagging(Bootstrap Aggregating):一种有放回的随机抽样方法,用于构建多个独立的弱学习器,然后对这些学习器的预测结果进行平均。
- Boosting:通过调整每个弱学习器的权重,使后续学习器专注于纠正前一个学习器的错误,形成一个强学习器。
- Stacking:构建多个不同类型的模型和一个超级模型,超级模型学习如何利用这些模型的输出来得到最佳的整体预测。
示例结果
- 执行集成学习算法构建模型。
- 使用模型进行预测。
注意事项
- 集成学习的关键是选择合适的弱学习器和组合策略。
- 在实际应用中,可能需要对数据进行预处理和特征选择。
842随机森林
随机森林是一种基于集成学习的机器学习算法,它由多个决策树组成。每个决策树都基于训练数据的一个随机子集,并且使用不同的特征集。随机森林通过“Bagging”技术(有放回的随机抽样)来减少单个决策树的过拟合,并通过投票机制来提高预测的准确性。在R中,可以使用randomForest
包来实现随机森林。
集成学习策略
-
Bagging(Bootstrap Aggregating):随机森林首先使用Bagging技术从原始数据集中随机选择样本,每个决策树都使用这些样本进行训练。这个过程减少了单个决策树的过拟合,提高了模型的泛化能力。
-
Boosting:在随机森林的构建过程中,不同的决策树之间存在一定的依赖关系。每个决策树都试图纠正前一个决策树的错误,这种方法称为Boosting。通过调整每个决策树的权重,可以优化整体模型的性能。
-
Stacking:随机森林还可以与其它模型结合使用,形成一个超级模型。这个超级模型学习如何最佳地组合不同模型的输出,以得到最终的预测结果。
randomForest()
函数的基本用法
-
randomForest()
函数的基本格式如下:randomForest(formula, data = NULL, ..., ntree, mtry)
formula
:表示因变量与自变量关系的响应公式。data
:用于解释公式中的变量名,通常是包含formula中变量的数据框。ntree
:树的数量,控制模型的复杂度。mtry
:随机抽取的最大特征数,控制模型对特征的考虑范围。
randomForest()
函数返回一个randomForest
对象,表示随机森林模型。
随机森林的构建步骤
-
随机选择样本:随机森林使用Bagging技术从原始数据集中随机选择样本,每个决策树都使用这些样本进行训练。
-
随机选择变量:在用于预测的全部特征变量中随机选取若干个,将其中划分效果最好的特征变量用于树的节点划分。
-
构建决策树:使用选定的样本和特征,构建决策树。
-
集成多个决策树:构建多棵决策树,并对它们的预测结果进行集成,如投票或取平均值。
随机森林的局限性
尽管随机森林是一种强大的机器学习方法,但它也存在一些局限性。例如,对于全新的数据,随机森林的泛化效果可能一般。此外,随机森林的训练过程需要大量的时间和计算资源,特别是在处理高维数据时。
示例结果
- 执行随机森林模型对数据集进行预测。
注意事项
- 在构建随机森林时,选择合适的弱学习器和组合策略至关重要。
- 可能需要对数据进行预处理和特征选择,以提高模型的性能。