```
#bibliography: [../References/BILab.bib, packages.bib]
```
# R语言基础
利用R软件做分析的基本方式是在R中编写R代码。那么R代码的编写方式有几种:
1. 双击R程序图标之后,打开Rgui图形界面。然后就可以直接在R console的>后边编写R代码。
2. 然后单击File->New script,就可以打开R代码的编辑器,撰写代码。同时,该编辑器的一个功能是可以用Ctrl+R快捷键,把光标所在行的代码发送到R console中。
3. 用IDE,比如Rstudio。
## 重要的快捷键
上下方向键: 可以调取历史命令
Esc键: 取消当前运算
## 基本数据类型
R语言中,最常用的三种数据类型是**字符**、**数字**和**逻辑量**,对应的英文分别是**character**, **numeric**和**logical**。下面我们一种种来介绍。
在具体介绍基本数据类型之前,我们先了解一下为什么要分数据类型。之前我们讲过一个重要原则,计算机时很笨的,因此,我们需要给他一些明确的规则,这样它才能正确的执行
### 字符
R里面的字符类型是用两个单引号或双引号包括起来内容。
```{r}
'4' #字符,character
"5"
class('50') #class函数可以判断某个值的类型
```
两个引号必须要相互对应。不能出现开始的引号是单引号,结束的引号为双引号。
```{r, eval=FALSE}
'hee" #这个是错误的
```
R其实有一些内置的字符
```{r}
letters #26个小写英文字母
LETTERS #26个大写英文字母
```
### 数字
```{r}
3 #整数
3.1415 #实数
1e+10 #科学计数法
1e-10
class(3)
```
R内置常数
```{r}
pi #圆周率
exp(1) #自然对数
Inf #正无穷
-Inf #负无穷
NA #not available or missing value
NaN #not a number
```
### 逻辑值
```{r}
TRUE #True,真
T
FALSE #False, 假
F
class(T)
```
### 类型转换
不同的数据类型之间可以相互转换。比如将逻辑性转化为数字型
```{r}
as.numeric(TRUE)
as.numeric(FALSE)
```
反之也可以将数字型转化为逻辑性。
```{r}
as.logical(0)
as.logical(1)
as.logical(2)
```
除了0之外,其他数字转换为逻辑变量类型的值都为TRUE。
由于数据类型很多,因此有很多的数据类型准换函数,但基本的结构是:as.[数据类型],方括号中的就是要转换为的数据类型。例如as.character等。当然,也存在is.[数据类型]来判断该值是什么数据类型。例如is.numeric(); is.logical(); is.character()等等。
当然,在R语言当中,除了上述三种常见的数据类型之外,还有许多其他的数据类型。有些是内置的,有些则是用户自定义的。为了简单起见,我们先不谈其他,用到时在解释也不迟。
## 数据运算
### 数字运算
针对R中的数值,可以进行基本的算数预算
```{r}
1+4+5
```
```{r}
6+7
2-1
```
```{r}
6+7; 2-1
```
乘除预算
```{r}
4*6
1/3
round(1/3,3) #round 就是一个R函数
```
取整取余
```{r}
#取余数
10%%3
10%/%3 #取整
```
幂运算
```{r}
2^3
2^(1/3)
```
#### 运算优先级
R语言中,各种运算其实是有先后顺序,即运算优先级。默认的运算优先级为:^, * /, + -。如果要打破这种优先级,那么就需要用小括号,来告诉R哪几步是一起预算的。
```{r}
3+1^2*2
(3+1)^2*2
3+1^(2*2)
```
### 逻辑和关系运算
除了上述算数运算之外,还可以进行逻辑运算
```{r}
TRUE & TRUE #与
TRUE | FALSE #或
!TRUE #反
```
对数字也可以进行关系预算,比如大小判断
```{r}
5>2 #大于
4>=4 #大于等于
4==4 #等于
4<6 #小于
4<=3 #小于等于
6!=0 #不等于
```
### 字符运算
R中有很多针对字符进行预算的操作,多以函数形式体现。例如
```{r}
nchar('abcd') #数多少个字符
substr("abcd", 2, 3) #提取其中的部分
strsplit('9qa49qw87eatqwae8ladj',split = "a") #依据某些字符分割字符
paste('a','b','c',sep = "-") #将多个字符合并
```
如果你对上述命令的具体用法有任何疑问,可以采用?+具体命令名称的方式来查看其帮助文档。
## 常见运算函数
为了方便运算,R语言中内置了很多常用的运算函数。需要时只要调用相应的函数名称就行,而不需要重复造车。
以下是一些常用函数,如果需要知道具体用法,请用?调出其帮助文档查看。
```{r}
exp(1) #以自然对数为底的幂函数
3^(5)
2^(1/2) #square root
sqrt(2)
log(2,2) #对数函数,第二个参数时base
log(1,879)
log(exp(1))
factorial(5) #阶乘
sin(pi/6) #三角函数
tan(pi/4)
abs(-5) #绝对值
choose(100,30) #组合函数
runif(10) #产生随机数的函数
all.equal(3.1, 3.2) #比较两个实数
is.infinite(10) #判断是否是无穷数
is.na(NA) #判断值是否为NA
```
保留小数位数
```{r}
round(pi,2)
ceiling(pi)
floor(pi)
```
## 变量
### 变量构造
变量是一个值会变,但名字不变的量。例如
```{r}
a=1 #a是一个变量,其中‘a’是名字,1是变量值,等号是赋值运算
```
变量名通常由字母、数字和下划线组成,且不能以数字开头。此外,R语言中的变量名是大小写敏感的,且中间不能包含空格。
当仅输入变量名时,就可以查看变量值。
```{r}
a
```
### 赋值
变量的值可以通过赋值运算来改变。正如上面的例子中的等号。但R语言中赋值运算不仅可以用等号,还可以用其他符号。例如
```{r}
bc #->这也是一种赋值运算
```
由于变量值可变,因此即便变量已经赋值了,还可以再次赋值,这样就会覆盖原来的值。
```{r}
a=10
```
由于R的数据类型本身有很多中,因此变量包含值,因此其也具有相应的数据类型的变量。
```{r}
a=1; class(a)
b=TRUE; class(b)
c='a'; class(c)
```
## 逻辑控制
### 条件
单行条件语句ifelse
```{r}
ifelse(5>3, 'yes', 'no')
```
多行的条件语句
```{r}
if(4>6)
print("Y")
print("N")
```
```{r}
if(4>6){ #花括号表示当条件为真时的作用域
print("Y")
print("N")
}
```
```{r}
if(5>3){
print("Yes")
4+6
}else{
print('No')
}
```
### 循环
```{r}
for(i in 1:10) #
print(i)
print(i)
```
```{r}
for(i in 1:10){ #
print(i)
print(i)
}
```
```{r}
i=1
while(i<10){
print(i)
i=i+1
}
```
## 容器
目前我们依据讲过具有单个值的变量。这虽然有用,但还不够用。因为很多现实情况是,我们有很多个数据值。比如上千上万。在这种情况下,我们总不能构建一千个变量,用来保存一千个值吧?
因此,我们需要一个类似容器的变量,它可以保存多个值。这种变量我们形象的称为容器,因为它同时保存了多个值。
在R中,容器有很多类型,最常见的有向量(vector)、矩阵(matrix)、数据框(data.frame)、列表(list)等。下面我就一一介绍每种容器的定义、特征和操作方法。
### 向量
#### 定义向量
向量是R中最简单的一种容器。可以用c函数来定义。例如:
```{r}
a=c(1,3)
a
```
上面的代码就用c(意为combine)构建了一个向量。其中a为向量名,而向量中的1或3为向量的元素。
除了这种构建方式之外,还有其他很多中方式构建。例如可以用:号来构建步长为1的连续整数向量:
```{r}
b=1:3
b
```
这就构建了名称为b,包含1,2,3三个元素的向量。
当然,冒号前后的数字大小可以调换,如果用下面命令构建向量:
```{r}
c=3:1
c
```
则可以得到一个包含3,2,1三个元素的向量。注意,这个c向量与b向量的元素值的集合虽然都只包含1、2、3,但这些元素在向量中出现的顺序不一样。因此,向量中元素的顺序也是向量的一个特征。当元素顺序不同时,也就得到了一个新的向量。
如果要改变这些等差数列的步长,我们可以采用seq函数。
```{r}
d=seq(1,10,2)
d
```
这样,我们就构建了一个起始值为1,步长为2,最大值小于等于10的一个向量。
#### 向量的特征
针对向量,我们可以用lenght函数计算向量的长度。
```{r}
length(a);length(b)
```
向量内部可以放任何数据类型。
```{r}
c=c(1,3)
class(c)
c=c(TRUE, FALSE)
class(c)
c=c('adg','ad0')
class(c)
```
但是针对一个向量,它内部的所有元素数据类型必须一致。
```{r}
d=c(1,"a")
class(d[1])
```
```{r}
d=c(3,TRUE,FALSE)
d
d=c(TRUE,3)
d
```
#### 取向量的元素
我们可以通过下标的方式来取向量的元素
```{r}
a[1]
```
其中,方括号中的数字代表下标,即第几个元素。但是如果下标为0或超过向量长度呢?会出现什么结果?请你们自己用R尝试一下回答。
我们可以给向量的每个元素一个名字,之后,就可以通过名字来取出对应的元素。
```{r}
names(a)=c("zhang","wang")
a['zhang']
```
#### 修改向量长度
当需要在向量内增加一个元素时,只需要通过下标的方式就可以完成。
```{r}
a[4]=0
```
如果我要将长度为4的向量a的第10个值赋为10,那么a将会变为什么?
```{r}
a[10]=10
a
```
如果要把向量中的某个元素删除,则仅需要通过带符号(-)的下标就可以实现。
```{r}
a[-10]
a[-(5:9)]
```
#### 向量元素的修改
向量的元素值修改很简单,只要两个步骤。第一,用下标或名字的方法取到这个值,然后用赋值预算来修改这个元素对应的值。
```{r}
a
```
### 矩阵
#### 矩阵定义
矩阵与之前将的向量很相似,唯一的区别时向量是一维的,而矩阵是二维的。
```{r}
a=matrix(1:30,nrow=5,ncol=6)
a
```
矩阵的赋值默认是以列为优先,但如果要改变这种默认的规则,这需要设置其byrow的参数为TRUE。
```{r}
b=matrix(1:30,nrow=5,ncol=6, byrow=TRUE)
b
```
#### 矩阵的特征
矩阵的维度
```{r}
dim(a)
nrow(a); ncol(a)
```
#### 给矩阵的行列名字
```{r}
colnames(a)=letters[1:6]
a
```
#### 提取矩阵的元素
用两个小标,中间带逗号。第一个小标表示行,第二个下标表示列。
```{r}
a[2,3] #第二行,第三列的元素。
```
由于矩阵是二维的,我也可以取某一行或列。在这种情况下,只需要写一个下标就行。
```{r}
a[3,] #第三行
a[,2] #第二列
```
如果想提取多行或多列,那么只需要给一个相应的向量下标就行。
按列或行名字提取
```{r}
colnames(a)=letters[1:6]
a
```
一旦有名字之后,就可以通过名字来访问列或行
```{r}
a[,'d']
```
#### 修改矩阵元素
```{r}
a[2,6]=100
a
```
```{r}
b=a[-2,]
b
```
### 数据框
数据框是一种特殊的容器,它与向量类似,但也存在这几个不同点。第一,向量是一维的,而数据框是二维的。第二,向量内部的任何元素数据类型必须一样,而数据框可以包含不同的数据类型。不过,这种不同数据类型仅可以在不同列之间。在同一列内部,不同元素的数据类型必须一致。
```{r}
#创建数据框
da=data.frame(a=1:3,b=c("a","b","c"),c=c(F,T,F))
```
通过data.frame函数,我们就可以定义一个类型为数据框的变量。其中每个参数是每一列的值。
### 列表
```{r}
```
## 函数
### 函数的判别
R语言中已经存在着很多的函数,这让我们日常计算变得非常方便。
但我们怎么区分一个字符是函数名还是变量名?
```{r}
sum
sum()
```
一般来讲,在小括号前面的字符串就是函数名。
### 函数的定义
函数可以简化编程,如果依据实现的功能,就只要直接调用已有的函数就行了。避免重复写同样的代码。
```{r}
myfun