zl程序教程

您现在的位置是:首页 >  工具

当前栏目

从零开始的异世界生信学习 R语言部分 06 R应用专题

应用学习语言 世界 从零开始 部分 专题 06
2023-06-13 09:15:36 时间

一、玩转字符串

stringr包

字符串的概念

1.str_length() 检测字符串长度

x <- "The birch canoe slid on the smooth planks."
x
### 1.检测字符串长度
str_length(x) #计算字符串中有多少字符
length(x)   #计算向量中元素的个数

2. str_split 字符串拆分

x <- "The birch canoe slid on the smooth planks."
x
### 2.字符串拆分
str_split(x," ")  #函数将一个向量拆分成一个列表了
x2 = str_split(x," ")[[1]];x2  #提取拆分后的列表的元素进行后续计算
y = c("jimmy 150","nicker 140","tony 152")
str_split(y," ")
str_split(y," ",simplify = T) ##加入参数后,可以将字符串拆分成矩阵

3. str_sub 按位置提取字符串

x <- "The birch canoe slid on the smooth planks."
str_sub(x,5,9)  

4. str_detect 字符检测

x <- "The birch canoe slid on the smooth planks."
x
str_split(x," ")  
x2 = str_split(x," ")[[1]];x2  
### 4.字符检测
str_detect(x2,"h")  ##用来检测元素中的字符,生成与向量元素相等的逻辑值向量,可以用来取子集
str_starts(x2,"T")  ##检测是否以T开头
str_ends(x2,"e")  ##检测是否以e结尾

5. str_replace 字符串替换

x2
str_replace(x2,"o","A")  ##在" "中只替换一个函数
str_replace_all(x2,"o","A") ##替换所有

6. str_remove 字符串替换

### 6.字符删除
x
str_remove(x," ")
str_remove_all(x," ")

二、 玩转数据框

1.arrange( ) 排序

test <- iris[c(1:2,51:52,101:102),]
rownames(test) =NULL # 去掉行名,NULL是“什么都没有”
test
library(dplyr)
arrange(test, Sepal.Length) #按照一列的顺序将所有数据框从小到大排序,列名不带引号,
arrange(test, desc(Sepal.Length)) #从大到小 排序

2.distinct()去重复

distinct(test,Species,.keep_all = T) 
##某一个数据第一次出现视为不重复,之后出现的为重复

2.mutate()数据新增列

# mutate,数据框新增一列,新增一列是两列数值的乘积
mutate(test, new = Sepal.Length * Sepal.Width)
select筛选列;filter筛选行

select和filter 筛选出来的结果是数据框

3.连续操作,优秀的管道符号%>%

快捷键 ctrl + shift +m

# 1.多次赋值,产生多个变量

x1 = filter(iris,Sepal.Width>3)  ##按照Sepal.Width>3筛选所有行
x2 = select(x1, Sepal.Length,Sepal.Width)  ##筛选x1数据中的Sepal.Length,Sepal.Width两列
x3 = arrange(x2,Sepal.Length) ##按照Sepal.Length给x2排序

# 2.管道符号传递,简洁明了,代码易读
x = iris %>%  ##%>%表示传递,一次作为后一个函数的第一个参数
  filter(Sepal.Width>3) %>% 
  select(Sepal.Length,Sepal.Width)%>%
  arrange(Sepal.Length)

# 3. 嵌套,代码不易读
arrange(select(filter(iris,Sepal.Width>3),
               Sepal.Length,Sepal.Width),
        Sepal.Length)

三、条件和循环

1. if 条件语句

###1.if(){ }  如果...就...

#### (1)只有if没有else,那么条件是FALSE时就什么都不做

i = -1
if (i<0) print('up')
if (i>0) print('up')
#理解下面代码
if(!require(tidyr)) install.packages('tidyr')
#### (2)有else
i =1
if (i>0){
  print('+')
} else {
  print("-")
}
## ifelse函数
i = 1
ifelse(i>0,"+","-")

x = rnorm(3)
x
ifelse(x>0,"+","-")
#ifelse()+str_detect() 重点!!!可以用来进行分组,通过str_detect函数识别数据中的关键词,然后进行分组 
samples = c("tumor1","tumor2","tumor3","normal1","normal2","normal3")
k1 = str_detect(samples,"tumor");k1
ifelse(k1,"tumor","normal")
k2 = str_detect(samples,"normal");k2
ifelse(k2,"normal","tumor")

多个条件的if判断

#### (3)多个条件
i = 0
if (i>0){
  print('+')
} else if (i==0) {
  print('0')
} else if (i< 0){
  print('-')
}

ifelse(i>0,"+",ifelse(i<0,"-","0"))

2. for 循环

### 1.for循环
x <- c(5,6,0,3)
s=0
for (i in x){
  s=s+i
  print(c(i,s))
}
x <- c(5,6,0,3)
s = 0
for (i in 1:length(x)){ ##i 的循环范围是向量元素的下标
  s=s+x[[i]]  ##for循环中建议给向量取子集的时候,建议用[[ ]]
  print(c(x[[i]],s))
}
rm(list = ls())
l1 <- list(1:10,
           10:5)
l2 <- list()
l2[[1]] <- 1:10
l2[[2]] <- 10:5
##生成列表的方式,直接生成以及生成一个空列表后添加元素
identical(l1,l2)  ##判断两个数据是否一致
#如何将结果存下来?
s = 0
result = list()
for(i in 1:length(x)){
  s=s+x[[i]]
  result[[i]] = c(x[[i]],s)
}
result
do.call(cbind,result)
## 通过先生成空的列表list,使用下标循环,可以将每次循环的结果都保存到列表中

## cbind 按列拼接
a = rnorm(10)
b = 1:10
cbind(a,b)

##do.call() 函数是对列表 list操作的函数,批量操作

分批次将运行结果保存为R.data格式便于管理数据

大段代码暂时不运行可以进行折叠,并加入一个if 判断或者注释掉

表达矩阵箱线图

表达矩阵

R 语言作图要求将宽数据的表达矩阵转变成长数据后昨天

# 表达矩阵
set.seed(10086)  ##固定随机数随机种子
exp = matrix(rnorm(18),ncol = 6)
exp = round(exp,2)  ##取小数点后2位
rownames(exp) = paste0("gene",1:3)
colnames(exp) = paste0("test",1:6)
exp[,1:3] = exp[,1:3]+1
exp
###创造练习数据表达矩阵exp
exp 矩阵 宽数据,易读
##表达矩阵画图
library(tidyr)
library(tibble)
library(dplyr)
dat = t(exp) %>% #转置表达矩阵,宽表变长表
  as.data.frame() %>%  #将表达矩阵转换为数据框
  rownames_to_column() %>%  #将行名变成一列
  mutate(group = rep(c("control","treat"),each = 3)) ##给数据添加一列分组列

##最终生成作图过程中间的转换的数据框dat
dat 数据框
pdat = dat%>% 
  pivot_longer(cols = starts_with("gene"),  ##选择那几列的列名合成在一起组成新的一列
               names_to = "gene",   ##新的列的名字
               values_to = "count")  ## 把原来列中的数值一一对应形成一个新的数值列'count'
pdat 转化为长数据 可以作图
library(ggplot2)
p = ggplot(pdat,aes(gene,count))+
  geom_boxplot(aes(fill = group))+
  theme_bw()
p
p + facet_wrap(~gene,scales = "free")
使用pdat 作箱线图

隐式循环

apply族函数,矩阵和数据框的隐式循环,只能用于数据框以及矩阵

apply优点在于可以应用自定义函数

### 1.apply 处理矩阵或数据框

#apply(X, MARGIN, FUN, …) 
#其中X是数据框/矩阵名;
#MARGIN为1表示行,为2表示列,FUN是函数

test<- iris[1:6,1:4]

apply(test, 2, mean)  ##对test数据框的每一行求平均值

apply(test, 1, sum)  ##对test数据框的每一行求和
apply(test, 2, mean)
apply(test, 1, sum)
### 2.lapply(list, FUN, …) 
# 对列表/向量中的每个元素(向量)实施相同的操作

test <- list(x = 36:33,y = 32:35,z = 30:27);test

#返回值是列表,对列表中的每个元素(向量)求均值(试试方差var,分位数quantile)

lapply(test,mean)
lapply(test,fivenum)
lapply(test, var)
lapply(test, sd)
lapply(test, quantile)
### 3.sapply 简化结果,返回矩阵或向量

sapply(test,mean)
sapply(test,fivenum)

class(sapply(test,fivenum))

两个数据框的连接

test1 <- data.frame(name = c('jimmy','nicker','Damon','Sophie'), 
                    blood_type = c("A","B","O","AB"))
test1
test2 <- data.frame(name = c('Damon','jimmy','nicker','tony'),
                    group = c("group1","group1","group2","group2"),
                    vision = c(4.2,4.3,4.9,4.5))
test2
library(dplyr)
inner_join(test1,test2,by="name")  ##取交集
left_join(test1,test2,by="name")  ##左连接,以左侧的表的行为准构成新的数据框(第一个写的数据框),右表中多余的数据舍去,没有的数据显示缺失值
right_join(test1,test2,by="name") ##右连接,以右侧的表的行为准构成新的数据框(第二个写的数据框),左表中多余的数据舍去
full_join(test1,test2,by="name") ##取全集
semi_join(test1,test2,by="name") ##半连接,对左边表格取在右边表格住存在的子集
anti_join(test1,test2,by="name") ##反连接
数据准备
inner_join(test1,test2,by="name") ##取交集
left_join(test1,test2,by="name") ##左连接
right_join(test1,test2,by="name") ##右连接
full_join(test1,test2,by="name") ##取全集
semi_join(test1,test2,by="name") ##半连接
anti_join(test1,test2,by="name") ##反连接