前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >十二、R语言的综合应用

十二、R语言的综合应用

原创
作者头像
叮当猫DDM
修改2023-03-20 18:20:35
3.1K0
修改2023-03-20 18:20:35
举报
文章被收录于专栏:叮当猫学生信叮当猫学生信

生信技能树学习之R语言的综合应用

一、玩转字符串

代码语言:javascript
复制
x <- "The birch canoe slid on the smooth planks."
x

[1] "The birch canoe slid on the smooth planks."

1.1.检测字符串长度

代码语言:javascript
复制
str_length(x)   ###用来数数的,数数引号中有多少字符   返回值42
length(x)       ###是用来返回向量中元素的个数     返回值1

1.2.字符串拆分

代码语言:javascript
复制
str_split(x," ")           ### 以空格为分隔符,拆分开。  
x2 = str_split(x," ")[[1]];x2

[[1]] ##第一句代码返回值,返回的是列表,不能进行下一步的计算操作

[1] "The" "birch" "canoe" "slid" "on" "the" "smooth" "planks."

需要对列表取子集后,才能进行下一步计算,取子集代码是第二句,返回结果是向量,结果如下:

[1] "The" "birch" "canoe" "slid" "on" "the" "smooth" "planks."

代码语言:javascript
复制
y = c("jimmy 150","nicker 140","tony 152")   ###有三个引号,说明是3个向量
str_split(y," ")         ###拆分后就变成了三个列表

代码语言:javascript
复制
str_split(y," ",simplify = T)    
###返回结果是矩阵。只允许一种数据类型,需要先转变成数据框以后才能修改。

1.3.按位置提取字符串

代码语言:javascript
复制
str_sub(x,5,9)    ###提取x字符串的第5位到第9位,空格也算一个。

1.4.字符检测

代码语言:javascript
复制
str_detect(x2,"h")   
### 看x2这个长度为8的向量中的每个元素是否含有h这个关键词,生成的与x2长度相等且一一对应的逻辑值向量
str_starts(x2,"T")     ### 是否以T开头
str_ends(x2,"e")       ### 是否以e结尾

1.5.字符串替换

代码语言:javascript
复制
x2
str_replace(x2,"o","A")     ###在一个引号里面,只替换第一个匹配的字符
str_replace_all(x2,"o","A")

1.6.字符删除

代码语言:javascript
复制
x
str_remove(x," ")    ###只删除了第一个空格
str_remove_all(x," ")

二、玩转数据框

2.1 arrange,数据框按照某一列排序

代码语言:javascript
复制
arrange(test, Sepal.Length)         #从小到大
arrange(test, desc(Sepal.Length))  #从大到小

2.2 distinct,数据框按照某一列去重复

代码语言:javascript
复制
distinct(test,Species,.keep_all = T)

2.3 mutate,数据框新增一列

代码语言:javascript
复制
mutate(test,new= Sepal.Length * Sepal.Width) .   ###没有赋值,所以修改后的test还是5列 

2.4 连续的步骤

select() 筛选列

filter() 筛选行

2.4.1.多次赋值,产生多个变量

代码语言:javascript
复制
x1 = filter(iris,Sepal.Width>3)
x2 = select(x1, Sepal.Length,Sepal.Width)
x3 = arrange(x2,Sepal.Length)

2.4.2.管道符号传递,简洁明了

让代码变得更加易读、简单明了,即不用反复赋值,也不用嵌套

代码语言:javascript
复制
x = iris %>%   ##快捷键 shift+ctrl+m, 表示向后传递
  filter(Sepal.Width>3) %>% 
  select(Sepal.Length,Sepal.Width)%>%
  arrange(Sepal.Length)             ###与2.4.1生成的结果一模一样,并且没有生成中间变量。

2.4.3. 嵌套,代码不易读

代码语言:javascript
复制
arrange(select(filter(iris,Sepal.Width>3),
               Sepal.Length,Sepal.Width),
        Sepal.Length)

三、条件和循环

3.1 条件语句

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

if和else都只能有一个逻辑值,不支持循环。
if和else都只能有一个逻辑值,不支持循环。

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

代码语言:javascript
复制
i = -1
if (i<0) print('up')     ###输出结果为up
if (i>0) print('up')     ###不会输出任何结果

#理解下面代码

代码语言:javascript
复制
if(!require(tidyr)) install.packages('tidyr')

#### (2)有else if返回的逻辑值是true时,执行if的函数结果,返回的逻辑值是false时,执行的是else的函数结果。

代码语言:javascript
复制
i =1
if (i>0){print('+')
} else {print("-")
}
i = 1
ifelse(i>0,"+","-")   ## [1] "+"
x = rnorm(3)
x
ifelse(x>0,"+","-")   
## 返回的结果是TRUE时就替换成第二个位置的值“+”,返回的结果是FALSE时就替换成第三个位置的值“-”

#ifelse()+str_detect(),王炸

代码语言:javascript
复制
ifelse(T,"A","B")
ifelse(F,"A","B")
ifelse(c(T,T,T),"A","B")
ifelse(c(F,F,F),"A","B")
ifelse(c(T,F,F),"A","B")
ifelse(c(T,F,F),"B","A")


ifelse(str_detect(samples,"tumor"),"tumor","normal")
ifelse(str_detect(samples,"normal"),"tumor","normal")    ###顺序不能写反

samples = c("tumor1","tumor2","tumor3","normal1","normal2","normal3")
k1 = str_detect(samples,"tumor");k1     ###[1]  TRUE  TRUE  TRUE FALSE FALSE FALSE
ifelse(k1,"tumor","normal")     ### [1] "tumor"  "tumor"  "tumor"  "normal" "normal" "normal"
###如果k1中返回的值是TRUE就替换成“tumor”,是FALSE就替换成“normal”,
####如果samples这个向量中的每个元素含有tumor就是TRUE,就会被替换成“tumor”
k2 = str_detect(samples,"normal");k2
ifelse(k2,"normal","tumor")

#### (3)多个条件

代码语言:javascript
复制
i = 0
if (i>0){
  print('+')
} else if (i==0) {
  print('0')
} else if (i< 0){
  print('-')
}

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

3.2 循环语句

对每个元素都要进行操作
对每个元素都要进行操作

### 1.for循环

代码语言:javascript
复制
###元素循环
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)){    ###length(x)=4,所以1:length(x)=1:4,循环的是第1,2,3,4个元素
  s=s+x[[i]]        ### x[[i]] 意思是x的第i个元素,第一轮是第一个元素5,第二个元素6,第三个元素0,第四个元素3
  print(c(x[[i]],s))
}

两组代码生成的结果是一样的。

#如何将结果存下来?

代码语言:javascript
复制
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)        ###cbind是按列拼接,出来的结果是
代码语言:javascript
复制
####补充知识点
rm(list = ls())
l = list(1:10,
         10:5)
l2 = list()
l2[[1]] = 1:10
l2[[2]] = 10:5
l2
identical(l,l2)      #### 判断两个数据是否完全一致,一致就返回TRUE/不一致就返回FALSE
library(ggplot2)
a = data.frame(a1 = rnorm(15),
               a2 = rnorm(15),
               a3 = rnorm(15),
               g = rep(c("a","b","c"),each = 5))
a
library(ggplot2)
for (i in 1:3) {
     p = ggplot(data = a)+
geom_boxplot(aes_string(y = a1[[i]],
            x = g))
print(p)
}
# 元素循环,不方便保存
for (i in colnames(a)[1:3]) {
p = ggplot(data = a)+
geom_boxplot(aes_string(y = i,
x = "g"))
print(p)
}
# 下标循环,可以保存数据
p = list()
for (i in 1:3) {
p[[i]] = ggplot(data = a)+
geom_boxplot(aes_string(y = colnames(a)[[i]],
x = "g"))
print(p[[i]])
}
library(patchwork)
p[[1]]+p[[2]]+p[[3]]
ifelse(deg$a < -1&deg$b < 0.05,"down",ifelse(deg$a >1& deg$b < 0.05,"up","no"))
ifelse(deg$a < -1&deg$b < 0.05,"down",ifelse(deg$a >1& deg$b < 0.05,"up","no"))

四、表达矩阵画箱线图

1.转置t 2.把原来的行名变成第一列 3.宽变长 4.画图

# 表达矩阵

代码语言:javascript
复制
set.seed(10086)     ###目的是为了使后边rnorm的值变得固定
exp = matrix(rnorm(18),ncol = 6)
exp = round(exp,2)    ### round是取小数点后几位的函数
rownames(exp) = paste0("gene",1:3)
colnames(exp) = paste0("test",1:6)
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))  
  ###给数据生成一个分组,前三个是"control",后三个是"treat"

### 宽变长代码
pdat = dat%>% 
  pivot_longer(cols = starts_with("gene"),   ### 把gene1、gene2、gene3这几列合并,starts_with("gene"),以gene开头的列。
               names_to = "gene",     ### 给合并后的列命名为gene
               values_to = "count")   ### 这几列的数值也要合并为一列,并且命名为count。就可以用ggplot画图了。
library(ggplot2)
p = ggplot(pdat,aes(gene,count))+
  geom_boxplot(aes(fill = group))+
  theme_bw()
p
p + facet_wrap(~gene,scales = "free")

五、隐式循环

## apply()族函数

5.1 apply 处理矩阵或数据框

#apply(X, MARGIN, FUN, …)

#其中X是数据框/矩阵名;

#MARGIN为1表示行,为2表示列,FUN是函数

代码语言:javascript
复制
test<- iris[1:6,1:4]
apply(test, 2, mean)   ### 对test的这个矩阵的每一列求平均值
apply(test, 1, sum)    ### 对test的这个矩阵的每一行求和

# 如何挑出100个数字中最大的10个?

代码语言:javascript
复制
sort(a)
tail(a,3)         ### 取a的最后3个元素 
tail(sort(a),10)  ### 取排序后的a的最后10个元素
head(sort(a,decreasing = T),10)
load("test2.Rdata")
a = apply(test,1,var)
names(tail(a,1000))   ###把提取出来的1000个基因的基因名字提取出来
a = names(tail(apply(test,1,var),1000))
pheatmap::pheatmap(test[a,],show_rownames = F,scale = "row")   # scale = "row" 按行归一化

### show_rownames =F 隐藏行名,

5.2 lapply(list, FUN, …) 列表的隐式循环

# 对列表/向量中的每个元素(向量)实施相同的操作

代码语言:javascript
复制
test <- list(x = 36:33,y = 32:35,z = 30:27);test

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

代码语言:javascript
复制
lapply(test,mean)
lapply(test,fivenum)

5.3 sapply 简化结果,返回矩阵或向量

代码语言:javascript
复制
sapply(test,mean)
sapply(test,fivenum)
class(sapply(test,fivenum))

六、两个数据框的连接

代码语言:javascript
复制
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")  ###取交集
right_join(test1,test2,by="name")  ### 右连接,以右边的表为标准进行连接。left_join左连接
full_join(test1,test2,by="name")   ###全连接
semi_join(test1,test2,by="name")  ###半连接(实际上并没有连接)对左边的表取子集,取右边表中存在的子集
anti_join(test1,test2,by="name") ###反连接,左边表里在右边表里没有的会被留下来。

七、一些顶呱呱的函数

代码语言:javascript
复制
# 1.match-----
load("matchtest.Rdata")
x
y
## 如何把y的列名正确替换为x里面的ID?

## (1)分步解法
a = colnames(y)
b = x$file_name
k = match(a,b);k
#match(a,b)的意思是a里的每个元素在b的第几个位置上。
#是b的下标,可以给b取子集,也可以给与b对应的其他向量取子集。
colnames(y) = x$ID[k]

## (2)一步解法
load("matchtest.Rdata")
colnames(y) = x$ID[match(colnames(y),x$file_name)]

## (3)放弃match的解法
load("matchtest.Rdata")
rownames(x) = x$file_name
x = x[colnames(y),]
colnames(y) = x$ID

# 2.一些搞文件的函数----
dir() # 列出工作目录下的文件
dir(pattern = ".R$") #列出工作目录下以.R结尾的文件

file.create("douhua.txt") #用代码创建文件
file.exists("douhua.txt") #某文件在工作目录下是否存在
file.remove("douhua.txt") #用代码删除文件
file.exists("douhua.txt") #删掉了就不存在啦

## 可以批量的新建和删除
f = paste0("douhua",1:100,".txt")
file.create(f)
file.remove(f)

八、练习题:

# 1.加载test1.Rdata,将dat数据框按照logFC从小到大排序

代码语言:javascript
复制
##第一种
load("test1.Rdata")
library(dplyr)
arrange(dat, logFC)
###第二种
load('test1.Rdata')
library(dplyr)
x=arrange(dat,logFC);head(x)

# 2.将test1.Rdata中存放的两个数据框连接在一起,按共同的列取交集

代码语言:javascript
复制
x=merge(dat,ids,by = "probe_id")
x2=inner_join(dat,ids,by = "probe_id")

# 1.读取group.csv,从第二列中提取圈出来的信息

代码语言:javascript
复制
x= read.csv("group.csv")
library(stringr)
z=str_split(x$title," ",simplify = T)
z[,4]

# 2.如何把上一题结果中的Control和Vemurafenib改成全部小写?搜索一下

代码语言:javascript
复制
m=str_replace_all(z[,4],"C","c")
str_replace_all(m,"V","v")
代码语言:javascript
复制
tolower(g[,4])
str_to_lower(g[,4])

# 3.加载deg.Rdata,根据a、b两列的值,按照以下条件生成向量x:

# a< -1 且b<0.05,则x对应的值为down;

# a>1 且b<0.05,则x对应的值为up;

# 其他情况,x对应的值为no

# 统计up、down、no各重复了多少次

代码语言:javascript
复制
load("deg.Rdata")
x=ifelse(deg$a< -1 & deg$b< 0.05,"down",ifelse(deg$a> 1 & deg$b< 0.05,"up","no"))
table(x)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、玩转字符串
    • 1.1.检测字符串长度
      • 1.2.字符串拆分
        • 1.3.按位置提取字符串
          • 1.4.字符检测
            • 1.5.字符串替换
              • 1.6.字符删除
              • 二、玩转数据框
                • 2.1 arrange,数据框按照某一列排序
                  • 2.2 distinct,数据框按照某一列去重复
                    • 2.3 mutate,数据框新增一列
                      • 2.4 连续的步骤
                        • 2.4.1.多次赋值,产生多个变量
                        • 2.4.2.管道符号传递,简洁明了
                        • 2.4.3. 嵌套,代码不易读
                    • 三、条件和循环
                      • 3.1 条件语句
                        • #### (1)只有if没有else,那么条件是FALSE时就什么都不做
                        • #### (2)有else if返回的逻辑值是true时,执行if的函数结果,返回的逻辑值是false时,执行的是else的函数结果。
                        • #### (3)多个条件
                      • 3.2 循环语句
                        • ### 1.for循环
                    • 四、表达矩阵画箱线图
                    • 五、隐式循环
                      • 5.1 apply 处理矩阵或数据框
                        • 5.2 lapply(list, FUN, …) 列表的隐式循环
                          • 5.3 sapply 简化结果,返回矩阵或向量
                          • 六、两个数据框的连接
                          • 七、一些顶呱呱的函数
                          • 八、练习题:
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档