[1] 1 2 3
# 匹配包含任意一个元音 (a, e, i, o, u) 的元素
grep("[aeiou]", c("apple", "banana", "cherry", "grape"), ignore.case = TRUE)
[1] 1 2 3 4
[1] 1 2 3 4
[1] 1 2 3
[1] 1 2 4
[1] 3
Lecture04 : R程序编写与数据处理-02
2024-09-20
函数是编程中的一个基本概念,它是一种封装了一段代码的实体,这段代码可以执行一个特定的任务。函数通常接受输入参数(也称为“参数”或“变量”),可以返回一个或多个值,
内置函数是指编程语言或库中预先定义好的函数,它们可以直接被开发者调用,无需手动编写实现代码。这些函数通常是为了执行常见的任务,如数学计算、字符串处理、文件操作等。
用来生成一定特征分布的模拟数据的函数。这些函数的名称都遵守一定的特点:[dpqr]<概率函数缩写>()
常用的概率函数有norm(正态分布)
、unif(均匀分布)
等
R语言中提供了多种字符处理函数,用于对字符串和文本进行操作
函数作用 | 代表函数 |
---|---|
查找 | grep |
替换 | sub ,gsub |
分割、截取 | substr ,strsplit |
连接 | paste ,paste0 |
工具 | tolower ,toupper ,nchar |
grep(pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE,
fixed = FALSE, useBytes = FALSE, invert = FALSE):
在字符串向量 x 中搜索匹配正则表达式 pattern 的子串,返回匹配位置的下标
sub 和 gsub 都是R语言中用于替换字符串中匹配正则表达式的函数。sub 只替换第一个匹配的子串,而 gsub 替换所有匹配的子串。
[1] "I have an cat, and my friend has a dog."
[1] "I have an cat, and my friend has an dog."
[1] "Today is 03-15/2024."
[1] "Today is 03-15-2024."
substr(string, start, stop)
函数用于提取字符串的子串,它需要起始位置和长度作为参数。
strsplit
函数用于根据分隔符分割字符串,它返回一个列表。
paste 函数用于将两个或多个字符向量或字符串连接成一个字符串,基本形式为paste(..., sep = " ", collapse = NULL, recycle0 = FALSE)
paste的用法灵活多样,应熟练掌握:
[1] "a b c"
[1] "a=b"
[1] "a1" "a2" "a3" "a4" "a5"
[1] "a1.pdf" "a2.pdf" "a3.pdf" "a4.pdf" "a5.pdf"
collapse参数表示元素间的折叠坍缩
length(x)
计算对象的长度
[1] 6
seq(from,to,by)
生成一个序列
rep(x,n)
将x重复n次
cut(x,breaks,labels=NULL)
将数值型向量x分割为具有n个水平的因子
# 创建一个数值向量
ages <- 1:100
# 使用cut函数将年龄分组,注意:如果指定labels参数,labels参数的数量必须和区间数量一致
age_groups <- cut(ages, breaks = c(18, 25, 35, 55, 100), labels = c("Youth", "Young Adult", "Adult", "Senior"))
print(age_groups)
[1] <NA> <NA> <NA> <NA> <NA> <NA>
[7] <NA> <NA> <NA> <NA> <NA> <NA>
[13] <NA> <NA> <NA> <NA> <NA> <NA>
[19] Youth Youth Youth Youth Youth Youth
[25] Youth Young Adult Young Adult Young Adult Young Adult Young Adult
[31] Young Adult Young Adult Young Adult Young Adult Young Adult Adult
[37] Adult Adult Adult Adult Adult Adult
[43] Adult Adult Adult Adult Adult Adult
[49] Adult Adult Adult Adult Adult Adult
[55] Adult Senior Senior Senior Senior Senior
[61] Senior Senior Senior Senior Senior Senior
[67] Senior Senior Senior Senior Senior Senior
[73] Senior Senior Senior Senior Senior Senior
[79] Senior Senior Senior Senior Senior Senior
[85] Senior Senior Senior Senior Senior Senior
[91] Senior Senior Senior Senior Senior Senior
[97] Senior Senior Senior Senior
Levels: Youth Young Adult Adult Senior
在R语言中,自定义函数可以让你编写一段可重复使用的代码块,这些代码块可以接受参数并返回结果。创建自定义函数可以使用 function
关键字。
定义自定义函数的基本语法:
示例:定义一个简单的自定义函数
add_numbers <- function(a, b) {
result <- a + b
return(result)
}
# 使用自定义函数
sum <- add_numbers(5, 3)
print(sum)
[1] 8
若自定义函数不含return语句,那么函数将默认返回最后一个表达式的结果。
R中共有4种形式的分支结构
if(条件) 表达式1
:最基本的条件判断结构。如果条件为TRUE,则执行表达式1if(条件) 表达式1 else 表达式2
:条件为真时执行表达式1,如果条件为FALSE,则执行表达式2。ifelse(条件,表达式1,表达式2)
:if-else结构的简化写法1switch(条件,表达式1,表达式2)
:基于条件的不同值执行不同的代码块当代码块只包含一条语句时,可以省略大括号,写在一行里
x大于5
x大于5
x大于5
x大于5
[1] "x大于5"
注意:ifelse用于生成结果,而不是执行操作。上面的最后一个例子中,cat函数是用来打印输出的,它不返回任何值,所以不能直接用在ifelse中。
R是一个向量语言,一般很少对单个标量进行操作,下面是分支结构用在向量上的例子:
也可以用在数据框和矩阵上:
mpg cyl disp hp drat wt qsec vs am gear
Mazda RX4 TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Mazda RX4 Wag TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Datsun 710 TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Hornet 4 Drive TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Hornet Sportabout FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Valiant FALSE FALSE TRUE TRUE FALSE FALSE TRUE FALSE FALSE FALSE
Duster 360 FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Merc 240D TRUE FALSE TRUE TRUE FALSE FALSE TRUE FALSE FALSE FALSE
Merc 230 TRUE FALSE TRUE TRUE FALSE FALSE TRUE FALSE FALSE FALSE
Merc 280 FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Merc 280C FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Merc 450SE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Merc 450SL FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Merc 450SLC FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Cadillac Fleetwood FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Lincoln Continental FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Chrysler Imperial FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Fiat 128 TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Honda Civic TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Toyota Corolla TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Toyota Corona TRUE FALSE TRUE TRUE FALSE FALSE TRUE FALSE FALSE FALSE
Dodge Challenger FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
AMC Javelin FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Camaro Z28 FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Pontiac Firebird FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Fiat X1-9 TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Porsche 914-2 TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Lotus Europa TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Ford Pantera L FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Ferrari Dino FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Maserati Bora FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
Volvo 142E TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
carb
Mazda RX4 FALSE
Mazda RX4 Wag FALSE
Datsun 710 FALSE
Hornet 4 Drive FALSE
Hornet Sportabout FALSE
Valiant FALSE
Duster 360 FALSE
Merc 240D FALSE
Merc 230 FALSE
Merc 280 FALSE
Merc 280C FALSE
Merc 450SE FALSE
Merc 450SL FALSE
Merc 450SLC FALSE
Cadillac Fleetwood FALSE
Lincoln Continental FALSE
Chrysler Imperial FALSE
Fiat 128 FALSE
Honda Civic FALSE
Toyota Corolla FALSE
Toyota Corona FALSE
Dodge Challenger FALSE
AMC Javelin FALSE
Camaro Z28 FALSE
Pontiac Firebird FALSE
Fiat X1-9 FALSE
Porsche 914-2 FALSE
Lotus Europa FALSE
Ford Pantera L FALSE
Ferrari Dino FALSE
Maserati Bora FALSE
Volvo 142E FALSE
R没有提供其它语言中常见的elseif
关键字,但我们可以通过嵌套多个if语句来进行模拟:
[1] 5
if (num < 30) {
print("level0")
} else if (num >= 30 & num < 60) {
print("level1")
} else if (num >= 60 & num < 80) {
print("level2")
} else {
print("level3")
}
[1] "level0"
[1] "level0"
在面对多个分支的情况时,多个if-else结构有点力不从心,这时可以使用switch结构
在R语言中,switch语句用于基于表达式的值选择执行不同的代码块。switch语句的基本语法如下:
[1] "P"
[1] "答案不是A, B或C"
注意:switch (expr, value1 = expr1,...)
函数根据第一个参数是字符串还是数字,工作方式有两种不同的表现。
下面的代码将会报错:
num <- sample(1:3, 1)
result <- switch(num,
1 = "num等于1",
2 = "num等于2",
3 = "num等于3",
"num不是1, 2, 或3")
正确的写法应该是:
R提供了几种类型的循环结构,包括for循环、while循环和repeat循环。
对向量每个元素、数据框和矩阵每行、每列循环处理,语法为for(循环变量 in 序列) 语句
,其中的语句一般是复合语句。
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 4
[1] 8
[1] 12
[1] 16
[1] 20
#带有条件判断的for循环
vec <- c(3, 7, 10, 15, 20)
for (i in vec) {
if (i > 10) {
print(paste(i, "大于10"))
} else {
print(paste(i, "小于等于10"))
}
}
[1] "3 小于等于10"
[1] "7 小于等于10"
[1] "10 小于等于10"
[1] "15 大于10"
[1] "20 大于10"
#嵌套for循环:生成矩阵
matrix_data <- matrix(0, nrow=3, ncol=3) # 创建一个3x3的0矩阵
for (i in 1:3) {
for (j in 1:3) {
matrix_data[i, j] <- i * j
}
}
print(matrix_data)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 2 4 6
[3,] 3 6 9
for循环中也可以结合break和next:
while循环在条件为真时重复执行代码块。
repeat循环会无限循环,直到内部的break语句被执行。
在处理大型数据框和矩阵、列表等数据集时,for循环操作麻烦且效率比较低下,显得力不从心。
apply族函数是一组强大的函数,它们可以对数组和矩阵进行操作,实现高效的循环和映射。这些函数包括:
apply
:对矩阵的行或列应用函数lapply、sapply、vapply
:对列表或向量的每个元素应用函数mapply
:lapply的多参数版本,可以同时处理多个列表或向量tapply
:对因子的每个级别应用函数apply(X, MARGIN, FUN, ..., simplify = TRUE)
[,1] [,2] [,3]
[1,] 1 11 21
[2,] 2 12 22
[3,] 3 13 23
[4,] 4 14 24
[5,] 5 15 25
[6,] 6 16 26
[7,] 7 17 27
[8,] 8 18 28
[9,] 9 19 29
[10,] 10 20 30
[1] 33 36 39 42 45 48 51 54 57 60
[1] 10 10 10
[,1] [,2] [,3]
[1,] 2 22 42
[2,] 4 24 44
[3,] 6 26 46
[4,] 8 28 48
[5,] 10 30 50
[6,] 12 32 52
[7,] 14 34 54
[8,] 16 36 56
[9,] 18 38 58
[10,] 20 40 60
注意:无法在维度小于2维的数据(如向量)上使用apply,以下代码将报错:
apply传参:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 6 7 8 9 10 11 12 13 14 15
[2,] 16 17 18 19 20 21 22 23 24 25
[3,] 26 27 28 29 30 31 32 33 34 35
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 14 15 16 17 18 19 20 21 22 23
[2,] 24 25 26 27 28 29 30 31 32 33
[3,] 34 35 36 37 38 39 40 41 42 43
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 14 15 16 17 18 19 20 21 22 23
[2,] 24 25 26 27 28 29 30 31 32 33
[3,] 34 35 36 37 38 39 40 41 42 43
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
[[4]]
[1] 4
[[5]]
[1] 5
[[6]]
[1] 6
[[7]]
[1] 7
[[8]]
[1] 8
[[9]]
[1] 9
[[10]]
[1] 10
这个函数并没有像我们预期的那样将值相加。这是因为 lapply将向量视为列表,并将函数应用于向量中的每个点。
sapply
与 lapply
类似,但如果可能的话会简化输出。它将返回一个向量,而不是像 lapply 那样返回列表。
[1] 1 2 3 4 5 6 7 8 9 10
[1] 45 78 209
mapply将函数运用于多个向量:mapply(FUN, …, MoreArgs = NULL, SIMPLIFY = TRUE
,注意函数写在前面
tapply用于对数据进行分组并应用函数。它通常用于将数据集分成由因子定义的组,并对每组数据应用一个函数,比如求和、平均、最大值等。
tapply(X, INDEX, FUN, ...)
我们将使用MASS包中的state.77数据集演示apply函数的使用,它包含了美国各个州的犯罪率等数据,首先进行安装
Population Income Illiteracy Life Exp Murder HS Grad Frost Area
Alabama 3615 3624 2.1 69.05 15.1 41.3 20 50708
Alaska 365 6315 1.5 69.31 11.3 66.7 152 566432
Arizona 2212 4530 1.8 70.55 7.8 58.1 15 113417
Arkansas 2110 3378 1.9 70.66 10.1 39.9 65 51945
California 21198 5114 1.1 71.71 10.3 62.6 20 156361
Colorado 2541 4884 0.7 72.06 6.8 63.9 166 103766
1:使用apply获取汇总数据
Population Income Illiteracy Life Exp Murder HS Grad Frost
4246.4200 4435.8000 1.1700 70.8786 7.3780 53.1080 104.4600
Area
70735.8800
Population Income Illiteracy Life Exp Murder HS Grad Frost
2838.500 4519.000 0.950 70.675 6.850 53.250 114.500
Area
54277.000
Population Income Illiteracy Life Exp Murder HS Grad
4.464491e+03 6.144699e+02 6.095331e-01 1.342394e+00 3.691540e+00 8.076998e+00
Frost Area
5.198085e+01 8.532730e+04
Population Income Illiteracy Life Exp Murder HS Grad Frost
[1,] 4246.420 4435.8000 1.1700000 70.878600 7.37800 53.108000 104.46000
[2,] 4464.491 614.4699 0.6095331 1.342394 3.69154 8.076998 51.98085
Area
[1,] 70735.88
[2,] 85327.30
Population Income Illiteracy Life Exp Murder HS Grad Frost Area
[1,] 365.0 3098 0.50 67.960 1.40 37.80 0.0 1049
[2,] 2838.5 4519 0.95 70.675 6.85 53.25 114.5 54277
[3,] 21198.0 6315 2.80 73.600 15.10 67.30 188.0 566432
population <- state.x77[1:50]
area <- state.area
pop.dens <- mapply(function(x, y) x/y, population, area)
pop.dens
[1] 0.070045922 0.000618899 0.019419010 0.039733353 0.133578671 0.024374802
[7] 0.618886005 0.281477880 0.141342213 0.083752293 0.134573643 0.009729885
[13] 0.198528369 0.146399934 0.050826079 0.027715647 0.083847011 0.078437030
[19] 0.031853078 0.389713529 0.704129829 0.156503367 0.046640815 0.049061112
[25] 0.068406854 0.005070070 0.019993008 0.005337434 0.087274291 0.935809086
[31] 0.009402791 0.364611909 0.103468604 0.009014364 0.260419194 0.038830647
[37] 0.023551005 0.261619571 0.766886326 0.090677830 0.008838761 0.098783259
[43] 0.045773344 0.014166941 0.049120616 0.122038466 0.052190873 0.074397254
[49] 0.081721694 0.003840105
region.info <- tapply(population, state.region, function(x) c(min(x), median(x), max(x)))
region.info
$Northeast
[1] 472 3100 18076
$South
[1] 579.0 3710.5 12237.0
$`North Central`
[1] 637 4255 11197
$West
[1] 365 1144 21198
R程序编写与数据处理-02