第10章 常用函数
10.1 seq()函数
seq()
函数用于生成一组数字序列,seq
代表sequence
。参数包括:
from
数字序列起点,默认为1。
to
数字序列终点。
by
步长,可以为正数、负数或者小数。
length.out
生成数字序列的长度。
along.with
生成与目标序列相同长度的数字序列。
## [1] 0 3 6
## [1] 1 4
## [1] 0 3 6 9
## [1] 1 3 5 7 9 11 13 15 17 19 21 23
10.2 rep()函数
rep()
函数用于生成重复序列,rep
代表repeat
。参数包括:
x
想要进行复制的对象,可以是一个数字,字符或者向量。
times
对整个目标对象复制的次数,只能为正整数。
each
对目标对象内元素复制的次数,只能为正整数。
length.out
生成序列的长度。
## [1] 1 2 3 1 2 3 1 2 3
## [1] 1 1 1 2 2 3
## [1] 1 1 2 2 3 3
## [1] "abc" "bbb" "abc"
## [1] "abc" "bbb" "abc" "bbb" "abc" "bbb" "abc" "bbb" "abc"
10.5 floor()、ceiling()、round()函数
有时我们需要对小数进行处理。floor()
函数返回不大于当前数字的最大整数,实际操作为提取数字的整数部分。
ceiling()
函数返回不小于于当前数字的最小整数,实际操作为提取数字的整数部分再加1。
round()
函数用于四舍五入至特定小数位。
## [1] 3
## [1] 4
## [1] 3.142
10.6 sample()函数
sample()
函数用于随机抽样。参数包括:
x
想要进行抽样的向量。
size
想要进行抽样的向量。
replace
默认为FALSE
,即不重复抽样,此时size
不能大于x
。若为TRUE
,则为重复抽样,此时size
可以大于x
。
prob
向量中各元素被抽到的概率,默认为NULL
,即概率相同。
注意:在进行随机抽样前,使用 set.seed()
函数设置随机种子可以保证抽样结果的复现。随机种子的赋值只需初始化一次。
## [1] 5 3 6 2 3 3 1 5 5 2
10.7 combn()函数
combn()
函数用于获得目标向量中指定长度的所有组合,常用于需要遍历变量组合的情况。参数包括:
x
目标向量。
m
指定组合长度。
simplify
默认为TRUE
,即返回矩阵。若为FALSE
,则返回列表。
# 创建向量
var_list <- c("bmi", "age", "sex", "education")
# 将var_list内的三个元素随机组合,返回为矩阵
combn(var_list, 3)
## [,1] [,2] [,3] [,4]
## [1,] "bmi" "bmi" "bmi" "age"
## [2,] "age" "age" "sex" "sex"
## [3,] "sex" "education" "education" "education"
## [1] "bmi" "age" "sex"
## [[1]]
## [1] "bmi" "age" "sex"
##
## [[2]]
## [1] "bmi" "age" "education"
##
## [[3]]
## [1] "bmi" "sex" "education"
##
## [[4]]
## [1] "age" "sex" "education"
## [1] "bmi" "age" "sex"
10.8 paste()函数
paste()
函数用于将向量、数字或字符合并成字符串,常用于特定语句的生成。
sep
参数用于定义将不同向量或字符合并成字符串所用的连接符。
collapse
参数用于定义将单一向量内元素合并成字符串所用的连接符。
## [1] "are you OK"
## [1] "areyouOK"
## [1] "bmi-cn" "age-cn" "sex-cn" "education-cn"
## [1] "bmi+age+sex+education"
10.9 ifelse()函数
ifelse()
函数为条件函数,包含三个参数:
test
条件。
yes
条件为TRUE时的返回值。
no
条件为FALSE时的返回值。
此函数在条件判断中可以得到多个逻辑结果,返回对应数目的逻辑值并根据逻辑值赋值(注意与if(){}else{}
函数[小节10.10]的区别)。此函数可以嵌套。
## [1] "N" "Y" "N" "Y"
## [1] "age1" "age2" "age2" "age3"
10.10 if(){}else{}函数
()
内为判断条件,如果为真,则运行第一个{}
的指令,否则运行第二个{}
的指令。此判断条件中只接受一个逻辑结果。如果输入多个逻辑结果,将会报错,此时需要用any()
或者all()
函数对多个逻辑结果进行处理。使用多个else if(){}
进行嵌套。
注意与ifelse()
函数[小节10.9]的区别。
## [1] "Y"
## [1] "中年"
10.11 循环
10.11.1 for循环
for循环是R语言中最常用的迭代函数之一,形式为for(){}
:
()
内为迭代器,即需要迭代的向量。
{}
内为想要运行的指令。
## [1] "现在的数字是:1"
## [1] "现在的数字是:2"
## [1] "现在的数字是:3"
## [1] "现在的数字是:4"
ini_num <- 5 # 设定初始值
sum_container <- c() # 创建空向量
for(i in seq(1,5,by=2)){
ini_num = ini_num + i # 迭代求和
sum_container <- append(sum_container, ini_num) # 将求和值添加入向量
}
sum_container
## [1] 6 9 14
10.11.2 while循环
while(){}
循环将重复执行{}
中的指令直至不能满足()
中的条件。
init_num <- 0 # 设定初始值
while(init_num<4){
init_num = init_num + 1 # 每次计数+1
print(paste0("已完成", init_num, "次运算。"))
}
## [1] "已完成1次运算。"
## [1] "已完成2次运算。"
## [1] "已完成3次运算。"
## [1] "已完成4次运算。"
10.11.3 apply()函数
当需要对矩阵或者数据框进行统一的特定处理时,为避免重复使用循环,可以选择apply()
函数,返回类型为向量或矩阵。此函数中三个主要的参数为:
X
输入数据。
MARGIN
指令执行方向。
FUN
执行指令。
FUN | MARGIN | 指令执行说明 |
---|---|---|
当指令需要作用于多个元素 | MARGIN=1 | 逐行运行指令,返回向量 |
当指令需要作用于多个元素 | MARGIN=2 | 逐列运行指令,返回向量 |
当指令只作用于单个元素 | MARGIN=1 | 逐个运行指令,返回矩阵。可以理解为将数据转置后对单个元素进行处理。 |
当指令只作用于单个元素 | MARGIN=2 | 逐个运行指令,返回矩阵。可以理解为在原有数据上直接对单个元素进行处理。 |
## [1] 35 56
## [1] 5 25 61
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
## [3,] 5 6
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
## Sepal.Length Petal.Length
## 876.5 563.7
当需要对列表或数据框进行统一的特定处理时,可以使用lapply()
函数,返回类型为列表。主要参数为X
即输入数据和FUN
执行指令。当FUN
作用于X
内的单个元素时,X
的结构不会发生改变。
## [[1]]
## [1] 14
##
## [[2]]
## [1] 77
## [[1]]
## [1] 1 2 3
##
## [[2]]
## [1] 4 5 6
var_matrix_list <- list(matrix(c(1,4,9,16,25,36),nrow=2),matrix(c(1,4,9,16,25,36),nrow=2))
lapply(var_matrix_list, sum)
## [[1]]
## [1] 91
##
## [[2]]
## [1] 91
## [[1]]
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
##
## [[2]]
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
当需要对列表、向量或数据框进行统一的特定处理且希望返回最简单的数据结构时,可以使用sapply()
函数。
## [1] 1 4 9 16 25 36
## [1] 1 2 3 4 5 6
## [1] 14 77
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
var_matrix_list <- list(matrix(c(1,4,9,16,25,36),nrow=2),matrix(c(1,4,9,16,25,36),nrow=2))
sapply(var_vector_list, sum) # 返回向量
## [1] 14 77
## [,1] [,2]
## [1,] 1 1
## [2,] 2 2
## [3,] 3 3
## [4,] 4 4
## [5,] 5 5
## [6,] 6 6
当需要对向量按类别进行统一的特定处理时,可以使用tapply()
函数,返回数组。
## setosa versicolor virginica
## 5.006 5.936 6.588
小结
函数 | 主要参数 | 输入数据类型 | 输出数据类型 |
---|---|---|---|
apply | apply(X,MARGIN,FUN) | 矩阵、数据框 | 向量、矩阵 |
lapply | lapply(X,FUN) | 列表、数据框 | 列表 |
sapply | sapply(X,FUN) | 列表、矩阵、数据框 | 向量、矩阵 |
tapply | tapply(X,INDEX,FUN) | 向量 | 数组 |
10.12 自定义函数
function(){}
用于自定义函数,其中()
用于定义函数的参数,{}
用于定义函数的指令并以return()
定义要返回的数据。
# 定义一个函数,用于报告向量长度
length_report <- function(x){
print(paste0("此向量的长度是:", length(x)))
}
length_report(c("bmi", "grip", "sex", "age"))
## [1] "此向量的长度是:4"
# 定义一个x+2y的函数,返回运算结果
multiply_function <- function(x,y){
return(x+2*y)
}
result_multiply <- multiply_function(2,3) # 传入参数位置与函数参数位置对应
result_multiply
## [1] 8
# 定义默认变量
multiply_function2 <- function(x,y,z="运算完成!"){
print(z)
return(x+2*y)
}
multiply_function2(2,3)
## [1] "运算完成!"
## [1] 8
## [1] "哈哈,运算完成~"
## [1] 8
函数只能返回一个结果,所以,如果有多个结果需要返回时,可以将结果整合为向量、列表或者数据框的形式之后再返回。
# 定义一个函数,获取向量内个元素累计叠加的值
accumulation <- function(x){
init_num <- x[1] # 获取第1个元素
result <- c(init_num) # 建立result向量收集结果
if (length(x)>=2){
for(i in seq(2,length(x))) {
init_num <- init_num + x[i]
result <- append(result, init_num)
}
}
return(result) # 返回向量
}
accumulation(seq(1:4))
## [1] 1 3 6 10
# 方法2:使用while循环
accumulation2 <- function(x){
init_num <- x[1]
vec_length <- length(x)
result <- c(init_num)
while(vec_length>1){
vec_length <- vec_length - 1
init_num <- init_num + x[length(x)-vec_length+1]
result <- append(result, init_num)
}
return(result)
}
accumulation2(seq(1:4))
## [1] 1 3 6 10