目录
5. str_replace() 和str_replace_all()----字符替换
6. str_remove()和str_remove_all()----指定字符的删除
一、字符串的综合应用
①str_length()----字符串长度
②str_split()----字符串拆分
③str_sub()----按位置提取字符
④str_detect()----字符检测
⑤str_replace()----指定字符替换第一个
⑥str_replace_all()----指定字符全部替换
⑦str_remove()----指定字符的删除(第一个)
⑧str_remove_all()----指定字符的删除(全部)
1.str_length()----字符串长度
在使用这个函数时,需要检查一下这个R包是否存在
library(stringr)
x <- "The birch canoe slid on the smooth planks."
x
#因为x是字符串
### 1.检测字符串长度
str_length(x)
length(x)
输出结果如下:
> str_length(x)
[1] 42
# 42包括了字符、空格、标点符号,但不包括引号
> length(x)
[1] 1
>
(1)str_length()与length() 的区别:
①length()函数用于获取向量、列表、因子等对象中的元素数量。在这个例子中,length(x) 为 1
②str_length()包括了字符、空格、标点符号,但不包括引号
(在这个时候,我有些好奇,如果把这个字符串分成两半,那它还会是42吗?于是我就尝试运行了一下)
y <- c("The birch canoe slid","on the smooth planks.")
y
str_length(y)
length(y)
运行结果如下:
> str_length(y)
[1] 20 21
> length(y)
[1] 2
>
(2)字符型向量概念
> y = c("jimmy 150","nicker 140","tony 152")
> y
[1] "jimmy 150" "nicker 140" "tony 152"
>
y----字符型向量,由3个字符串组成的向量
“Jimmy 150”----字符串,一个引号内的所有东西
引号内的单个字母/数字/符号----字符
2.str_split()----字符串拆分
y = c("jimmy 150","nicker 140","tony 152")
str_split(y," ")
#输出是列表形式
str_split(y," ",simplify = T)
#矩阵不可以一列一列的修改数据类型,数据框可以修改
x2=str_split(x," ")[[1]];x2
#运行结果为列表形式,用[[]]提取列表中元素
simplify=T----可以使输出是一个向量。
输出结果如下:
> y = c("jimmy 150","nicker 140","tony 152")
> str_split(y," ")
[[1]]
[1] "jimmy" "150"
[[2]]
[1] "nicker" "140"
[[3]]
[1] "tony" "152"
> str_split(y," ",simplify = T)
[,1] [,2]
[1,] "jimmy" "150"
[2,] "nicker" "140"
[3,] "tony" "152"
> x2=str_split(x," ")[[1]];x2
[1] "The" "birch" "canoe" "slid" "on" "the" "smooth"
[8] "planks."
>
3.str_sub()----按位置提取字符
#3.按位置提取字符串
x <- c("The birch canoe slid","on the smooth planks.")
str_sub(x,5,9)
【提取字符串x中第5-9个字符 】
输出结果如下:
> x <- c("The birch canoe slid","on the smooth planks.")
> str_sub(x,5,9)
[1] "birch" "he sm"
4.str_detect()----字符检测
### 4.字符检测
x1 <- c("The birch canoe slid on the smooth planks.")
x2 = str_split(x1," ")[[1]]
x2
str_detect(x2,"h") #含有h的就返回true
str_starts(x2,"T") #检测是否以t开头的
str_ends(x2,"e") #是否以e结尾
输出结果如下:
> x2
[1] "The" "birch" "canoe" "slid" "on" "the" "smooth"
[8] "planks."
> str_detect(x2,"h") #含有h的就返回true
[1] TRUE TRUE FALSE FALSE FALSE TRUE TRUE FALSE
> str_starts(x2,"T") #检测是否以t开头的
[1] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
> str_ends(x2,"e") #是否以e结尾
[1] TRUE FALSE TRUE FALSE FALSE TRUE FALSE FALSE
str_detect(x2,"h") :
5. str_replace() 和str_replace_all()----字符替换
### 5.字符串替换
x2
str_replace(x2,"o","A") #把字符串里的o换成A,如果有两个o,只替换第一个o
str_replace_all(x2,"o","A") # 把全部的o换成A
str_replace(x2,"o|e","A") #把字符串里的o或e换成A
输出结果如下:
> x2
[1] "The" "birch" "canoe" "slid" "on" "the" "smooth"
[8] "planks."
> str_replace(x2,"o","A") #把字符串里的o换成A,如果有两个o,只替换第一个o
[1] "The" "birch" "canAe" "slid" "An" "the" "smAoth"
[8] "planks."
> str_replace_all(x2,"o","A") # 把全部的o换成A
[1] "The" "birch" "canAe" "slid" "An" "the" "smAAth"
[8] "planks."
> str_replace(x2,"o|e","A") #把字符串里的o或e换成A
[1] "ThA" "birch" "canAe" "slid" "An" "thA" "smAoth"
[8] "planks.
6. str_remove()和str_remove_all()----指定字符的删除
# 6.字符删除
x
str_remove(x," ") #删掉第一个空格
str_remove_all(x," ") #删掉全部空格
输出结果如下:
x
[1] "The birch canoe slid" "on the smooth planks."
> str_remove(x," ") #删掉第一个空格
[1] "Thebirch canoe slid" "onthe smooth planks."
> str_remove_all(x," ") #删掉全部空格
[1] "Thebirchcanoeslid" "onthesmoothplanks."
>
二、数据框的综合应用
1.排序:arrange()
arrange()函数是dplyr包中的一个功能,用于对数据框中的观测行进行排序。首先,确保你已经安装并加载了dplyr包:
【从内置数据iris中获取一个数据框作为演示:】
library(dplyr)
test <- iris[c(1:2,51:52,101:102),]
rownames(test) =NULL # 去掉行名,NULL是“什么都没有”
test
arrange(test, Sepal.Length) #从小到大(根据这一列给整个数据框的排序)
arrange(test, desc(Sepal.Length)) #从大到小
【默认排序为从小到大,反过来从大到小则可以用desc()】
输出结果如下:
【仅对Sepal.Length这一列排序】
> arrange(test, Sepal.Length) #从小到大(根据这一列给整个数据框的排序)
Sepal.Length Sepal.Width Petal.Length Petal.Width
1 4.6 3.1 1.5 0.2
2 4.7 3.2 1.3 0.2
3 4.9 3.0 1.4 0.2
4 5.0 3.6 1.4 0.2
5 5.1 3.5 1.4 0.2
6 5.4 3.9 1.7 0.4
> arrange(test, desc(Sepal.Length)) #从大到小
Sepal.Length Sepal.Width Petal.Length Petal.Width
1 5.4 3.9 1.7 0.4
2 5.1 3.5 1.4 0.2
3 5.0 3.6 1.4 0.2
4 4.9 3.0 1.4 0.2
5 4.7 3.2 1.3 0.2
6 4.6 3.1 1.5 0.2
>
2.去重复:distinct()
keep_all = T: 这是distinct()函数的一个参数,用于控制是否保留原始行的所有列。当设置为TRUE时,将保留所有列;当设置为FALSE时,只保留用于判断唯一性的列(在本例中就是Species列)。
【注意:keep_all前面需要有个点哦!】
# distinct,数据框按照某一列去重复
distinct(test,Species,.keep_all = T)
未操作之前:
test
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 7.0 3.2 4.7 1.4 versicolor
4 6.4 3.2 4.5 1.5 versicolor
5 6.3 3.3 6.0 2.5 virginica
6 5.8 2.7 5.1 1.9 virginica
操作之后:
> distinct(test,Species,.keep_all = T)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 7.0 3.2 4.7 1.4 versicolor
3 6.3 3.3 6.0 2.5 virginica
>
3.数据框新增列:mutate()
添加一个名为new的新列,该列的值为每行中Sepal.Length列和Sepal.Width列相乘的结果。
# mutate,数据框新增一列
mutate(test, new = Sepal.Length * Sepal.Width)
输出结果如下:
> mutate(test, new = Sepal.Length * Sepal.Width)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species new
1 5.1 3.5 1.4 0.2 setosa 17.85
2 4.9 3.0 1.4 0.2 setosa 14.70
3 7.0 3.2 4.7 1.4 versicolor 22.40
4 6.4 3.2 4.5 1.5 versicolor 20.48
5 6.3 3.3 6.0 2.5 virginica 20.79
6 5.8 2.7 5.1 1.9 virginica 15.66
4.两个数据框的连接
(1)交集----inner_join
# 创建两个数据框
df1 <- data.frame(ID = c(1, 2, 3, 4),
Name = c("John", "Mary", "Tom", "Sarah"))
df2 <- data.frame(ID = c(2, 4, 5),
Age = c(25, 30, 35))
# 使用inner_join合并数据框
inner_join(df1, df2, by = "ID")
- by: 指定连接条件的列名。如果连接条件的列名在两个数据框中不同,则需要使用by.x和by.y参数分别指定两个数据框中的列名。
输出结果如下:
> inner_join(df1, df2, by="ID")
ID Name Age
1 2 Mary 25
2 4 Sarah 30
(2)全连接----full_join()
full_join()函数用于将两个数据框按照指定的列进行全外连接。full_join()函数的用法如下:full_join(x, y, by = "common_column")
- x:第一个数据框。
- y:第二个数据框。
- by:连接的列名,可以是单个列名或者多个列名的向量。
# 创建两个数据框
df4 <- data.frame(ID = c(1, 2, 3), Name = c("Alice", "Bob", "Charlie"))
df5 <- data.frame(ID = c(2, 3, 4), Age = c(25, 30, 35))
# 使用full_join进行全外连接
result <- full_join(df4, df5, by = "ID")
result
输出结果如下:
> result
ID Name Age
1 1 Alice NA
2 2 Bob 25
3 3 Charlie 30
4 4 <NA> 35
可以看到,full_join函数将两个数据框按照ID列进行全外连接,将两个数据框中的所有行都保留下来,如果某个数据框中没有对应的匹配项,则用NA填充。
(3)左连接----left_join()
left_join()
函数用于将两个数据框按照指定的列进行连接,并保留左侧数据框的所有行。
left_join(x, y, by = NULL, ...)
参数x
和y
分别是需要连接的两个数据框。
参数by
表示用于连接的列名或列名的向量。
df6 <- data.frame(ID = c(1, 2, 3),
Name = c("Alice", "Bob", "Charlie"))
df7<- data.frame(ID = c(1, 3, 4),
Age = c(25, 30, 35))
# 使用left_join函数连接数据框
df8 <- left_join(df6, df7, by = "ID")
print(df8)
输出结果如下:
> print(df8)
ID Name Age
1 1 Alice 25
2 2 Bob NA
3 3 Charlie 30
可以看到,连接后的数据框df8
保留了df6
中的所有行,并根据ID
列进行了连接。连接时,如果在df7
中找不到匹配的行,则对应的列值为NA。
(4)右连接----right_join()
right_join()函数用于按照右侧数据框的键连接两个数据框。
right_join(x, y, by = NULL, copy = FALSE, ...)
语法结构与左连接差不多,这里就不重复介绍了。
三、条件与循环
1.初步认识条件语句if()
条件语句:条件语句用于根据特定的条件来执行不同的操作。常用的条件语句包括if语句、else语句和else if语句。以下是这些条件语句的示例:
if语句:if语句用于在满足条件时执行一些操作。如果条件为真(TRUE),则执行特定的代码块。
【if(){ } 如果代码只有一行,可以不用大括号】
【只有if没有else,那么条件是FALSE时就什么都不做】
i = -1
if (i<0) print('up')
if (i>0) print('up')
输出结果如下:
> i = -1
> if (i<0) print('up')
[1] "up"
> if (i>0) print('up')
有else时:
i =1
if (i>0){
print('+')
} else {
print("-")
}
输出结果如下:
[1] "+"
2.ifelse()函数
(1)基本结构:
ifelse(test, yes, no)
text:逻辑值或者逻辑值向量,用于判断条件的部分。
yes:一个与test长度相同的向量或标量,如果对应位置的test为TRUE,则返回yes向量中对应位置的值。
no:一个与test长度相同的向量或标量,如果对应位置的test为FALSE,则返回no向量中对应位置的值。
注意:if-else语句只支持单个逻辑值,ifelse函数支持多个逻辑值组成的向量。
如:
x = rnorm(3)
x
ifelse(x>0,"+","-")
输出结果如下:
> x = rnorm(3)
> x
[1] 1.6457794 -0.7716354 0.9996297
> ifelse(x>0,"+","-")
[1] "+" "-" "+"
3.case_when()函数
case_when() 是dplyr 包中的一个非常有用的函数,它允许你根据一系列条件对数据进行分类或转换。这个函数基本上是一个向量化版本的 switch
或 if-else
语句,对于处理多个条件特别有用。
i = 1
case_when(i>0~"+",
i<0~"-",
T~"0")
输出结果如下:
[1] "+"
4.for循环
for循环是一种常用的迭代语句,用于在一定范围内多次执行相同的代码块。for循环通常由三个部分组成:初始化、循环条件和迭代器。
(1)基本语法
for (i in seq) {
# 执行的代码块
}
i是迭代器,用于依次遍历seq序列中的每一个元素,并执行相同的代码块。
seq序列可以是任何可以遍历的对象,例如数字序列、字符向量或数据框的行。
例1 :
for( i in 1:4){
print(i)
}
输出结果如下:
> for( i in 1:4){
+ print(i)
+ }
[1] 1
[1] 2
[1] 3
[1] 4
例2:
# 创建一个向量
v <- c(1, 2, 3, 4, 5)
# 创建一个空向量,用于存储处理后的结果
v_square <- c()
# 使用for循环遍历v中的每一个元素
for (i in v) {
square <- i^2 # 计算i的平方
v_square <- c(v_square, square) # 将结果添加到v_square中
}
# 输出处理后的结果
print(v_square) # [1] 1 4 9 16 25
(2)利用for循环批量画图
par(mfrow = c(2,2))
for(i in 1:4){
plot(iris[,i],col = iris[,5])
}
输出结果如下:
四、隐式循环
1.矩阵/数据框的隐式循环----apply
(1)语法结构:
apply(X,MARGING,FUN,...)
其中X是数据框/矩阵名;
MARGING为1表示行,为2表示列,
FUN是函数
对X的每一行/列进行FUN这个函数
test<- iris[1:6,1:4]
apply(test, 2, mean) #对test的每一列求平均,1,代表行,2代表列
apply(test, 1, sum) #对test的每一行求总和
输出结果为:
> apply(test, 2, mean) #对test的每一列求平均,1,代表行,2代表列
Sepal.Length Sepal.Width Petal.Length Petal.Width
4.9500000 3.3833333 1.4500000 0.2333333
> apply(test, 1, sum)
1 2 3 4 5 6
10.2 9.5 9.4 9.4 10.2 11.4
2.向量/列表的隐式循环----lapply
(1)语法结构
lapply(list,FUN,...)
对向量/列表中的每个元素实施相同的操作
lapply(1:4,rnorm)
【代码的意思是:生成1个随机数,生成2个随机数,生成3个随机数,生成4个随机数】
【输出的数据类型是列表】
结果如下:
> lapply(1:4,rnorm)
[[1]]
[1] 1.636353
[[2]]
[1] -0.8001952 -1.0980465
[[3]]
[1] -0.5473901 1.0036701 -0.1091149
[[4]]
[1] -0.96212854 -0.81425947 0.02058848 0.98277004
五、表达矩阵画箱线图(浅)
# 表达矩阵
set.seed(10086) #随机种子
exp = matrix(rnorm(18),ncol = 6) #形成18个随机数,共6列
exp = round(exp,2) #留下小数点后两位
rownames(exp) = paste0("gene",1:3) #设计行名,分别是gene1,gene2,gene3
colnames(exp) = paste0("test",1:6) #设计列名,分别是test1,test2,test3...
exp[,1:3] = exp[,1:3]+1 #对1到3列里的数据都+1
exp
完整代码如下:
# 表达矩阵
set.seed(10086)
exp = matrix(rnorm(18),ncol = 6)
exp = round(exp,2) #留下小数点后两位
rownames(exp) = paste0("gene",1:3)
colnames(exp) = paste0("test",1:6)
exp
exp[,1:3] = exp[,1:3]+1
exp
library(tidyr)
library(tibble)
library(dplyr)
dat = t(exp) %>%
as.data.frame() %>%
rownames_to_column() %>%
mutate(group = rep(c("control","treat"),each = 3))
pdat = dat%>%
pivot_longer(cols = starts_with("gene"),
names_to = "gene",
values_to = "count")
library(ggplot2)
p = ggplot(pdat,aes(gene,count))+
geom_boxplot(aes(fill = group))+
theme_bw()
p