前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >学习R语言里的排序函数

学习R语言里的排序函数

作者头像
生信技能树
发布于 2022-06-08 12:34:43
发布于 2022-06-08 12:34:43
1.1K00
代码可运行
举报
文章被收录于专栏:生信技能树生信技能树
运行总次数:0
代码可运行

我们的生信入门班和数据挖掘线上直播课程已经有了三年多的历史,培养了一波又一波优秀的生信人才。新一期的生信入门班学员热情高涨,他们富有探索精神,又乐于助人,这是一个在帮助别人的过程中自己也获得进步的例子,令我们非常开心。

学习R语言里的排序函数

(生信技能树学员徐谦)

正在上5月生信入门课程的小伙伴们应该初步掌握了一些R语言的基本函数,其中有一类函数可以称为排序函数,例如周二细讲的sort,order函数,以及不常使用的rank函数,这里说的只是R基础包中的排序函数,另外还有其他包中的一些更方便的函数,例如dplyr包中的arrange,这些后续我们再共同学习。先总结一下这几个函数的使用:

1.sort、order、rank

都是接受一个对象,通常为向量,运行之后根据这个向量中的元素位置,返回不同的值:

例如我们将x赋值如下,分别运行三个函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> x <- c(3,6,4,8,2)
> order(x)
[1] 5 1 3 2 4
> sort(x)
[1] 2 3 4 6 8
> rank(x)
[1] 2 4 3 5 1

这里很容易理解,order返回的是x当中元素的位置即下标,默认从小到大。这里可以补充一点,在R语言当中,我们看到的向量实际上是有两组信息的,一组是向量当中的元素,我们可以理解为萝卜,另外一组就是他的下标,我们可以理解为萝卜对应的坑。这里即x当中最小的萝卜是2,对应第5个坑。所以结果是51324。

sort呢,sort即将萝卜都拔出来,重新排序,默认从小到大,所以返回了23468。

那rank呢,rank是挨个比萝卜,返回值是它应该种的坑,默认还是从小到大,比如x里面第一个萝卜是3,它在x所有萝卜中排老2,所以先返回2,第二个萝卜6排老4,所以返回4。

总结:order对萝卜进行排序,但返回的是坑的位置;sort是将萝卜拔出来重新排,直接了当;rank是按现有顺序挨个比萝卜大小,返回它该种的坑的位置。

这里说的都是数字,那么其他类型的向量呢?

2. 其他类型向量的排序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> x <- c("B","A","D","F","C")
> order(x)
[1] 2 1 5 3 4
> sort(x
[1] "A" "B" "C" "D" "F"
> rank(x)
[1] 2 1 4 5 3
> x <- c("张三","李四","王五","赵六","朱七")
> order(x)
[1] 2 3 1 4 5
> sort(x)
[1] "李四" "王五" "张三" "赵六" "朱七"
> rank(x)
[1] 3 1 2 4 5

同样是可以排序的,只不过字符串会按照字母或者汉字拼音首字母进行排序,三个函数返回的值就不需要再赘述了。这里需要强调一点,如果一个数字向量,排序的时候会按数字大小排序,但是当数字和字母在一起组成一起,就不一定会按照数字大小排序了。举个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> x <- c("chr1","chr3","chr2","chr23","chr21")
> order(x)
[1] 1 3 5 4 2
> sort(x)
[1] "chr1"  "chr2"  "chr21" "chr23" "chr3" 
> rank(x)
[1] 1 5 2 4 3

可以理解了,字符排序,是有优先级的,不同染色体的名称,chr2后面不管有没有其他东西,有多少,它一定是在chr3前面的。

3. 参数的更改

R语言里所有的函数都是有参数的,我们可以根据函数作者的设定,赋予不同的参数,例如查阅帮助文档,可以看到sort,order都可以设定decreasing = T或者F来控制顺序,这个大家都知道了,就不重复了。

4. 元素重复了怎么排

如果向量x当中有重复元素呢?再举个例子试一下就可以了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> x <- c(3,6,2,4,8,2);x
[1] 3 6 2 4 8 2
> order(x,decreasing = F)
[1] 3 6 1 4 2 5
> order(x,decreasing = T)
[1] 5 2 4 1 3 6

两个一样的萝卜,如果是从小到大,先返回先出现的萝卜的坑,如果从大到小,就先返回后出现萝卜的坑。sort返回的是萝卜,两个一样的萝卜谁先谁后没区别。那rank呢,严格来说rank返回的是秩次,这个学过秩和检验的都知道,一样的元素,实际上秩次也是一样的,具体算法大家一看便知:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> x <- c(3,6,2,4,8,2);x
[1] 3 6 2 4 8 2
> rank(x)
[1] 3.0 5.0 1.5 4.0 6.0 1.5
> x <- c(3,6,2,4,8,2,2);x
[1] 3 6 2 4 8 2 2
> rank(x)
[1] 4 6 2 5 7 2 2

对了,返回的是坑的平均值。前两个元素2占坑1和2,平均1.5。如果前三个元素都是2,占坑123,平均还是2。

事情到这里应该就结束了,直到有个小伙伴在群里发了个截图:

我的第一反应是order只会接受一个向量,如果给他2个向量,他会选择性忽略第二个(我把order(x)order(x,y)的结果看成一样的了)。但是后来一想不太对,R语言中几乎所有的函数都是有严格的对象和参数要求的,如果给了它函数里没写的东西,那大部分时候就会报错,如果没报错,那就是函数接受了,当然也有其他特殊例外的情况。随后我就查了一下帮助文档,来了这么一段示例:

突然有点懵逼,试着自己运行了一下,才恍然大悟,实际上它是可以种好几排萝卜的,理论上可以无限种,但是有一个前提,那就是——坑得一样多,也就是说不管种几排,坑的顺序是不变的。order(x,y)会返回啥呢???我们赋值试一下,只种两排萝卜:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> x <- c(1,3:1);x
[1] 1 3 2 1
> y <- c(9:6);y
[1] 9 8 7 6
> order(x)
[1] 1 4 3 2
> order(x,y)
[1] 4 1 3 2

x里有两个1,为什么把order(x)把坑1排坑4的前面,而order(x,y),把坑4排的坑1前面,聪明的你应该已经看出来了,刚才我们说过order(x)中如果有一样的萝卜,默认是先出现的萝卜对应的坑排前面,所以1在4前面。而有了另外一排萝卜y后,如果x中有一样的萝卜,它会比y里萝卜的大小,x里有两个萝卜1,对应的y里的萝卜是9和6,6比9小,所以坑4排在坑1前面了。

5. 排序有什么用?

以上是R语言中基础函数中几个排序函数的用法,那排序到底有什么用呢?实际上在R语言中我个人觉得ordersort用的多,原因就是他会返回坑的位置。我们用坑的位置可以做很多事情,因为我们经常操作的数据框中,每一列都是一个向量,每一列都有一样顺序的坑,有了坑的位置我们就可以按行来提取数据框了,就可以按照某一列萝卜的顺序对行进行排序,类似于Excel中按列排序或者筛选扩展到其他列。同样道理,我们也可以用TRUE或者FALSE对坑进行标记,从而扩展到行。基础函数是可以实现数据的筛选的,但是很多时候会有更好的替代方法,等我们再往后接触到dplyr包,apply家族以及正则表达式的时候,就会发现熟练的数据处理是一件能提高效率提高产出的事情。这里可以举一个很简单的例子,就不举数据框的处理了,我们直接举向量的例子。R语言中向量是可以命名的,例如如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> x <- c(3,6,4,8,2);x
[1] 3 6 4 8 2
> y <- c("张三","李四","王五","赵六","朱七");y
[1] "张三" "李四" "王五" "赵六" "朱七"
> names(x) <- y;x
  张三 李四 王五 赵六 朱七 
   3    6    4    8    2 

好了现在向量x有了三组信息,萝卜,坑的顺序和萝卜的名字,我们继续运行排序函数试试:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> order(x)
[1] 5 1 3 2 4
> sort(x)
朱七 张三 王五 李四 赵六 
   2    3    4    6    8 
> rank(x)
 张三 李四 王五 赵六 朱七 
   2    4    3    5    1 

可以看到orderrank之后把萝卜的名字也给出了,是不是很方便知道同学的名次了。后面还会学到一种富集分析叫GSEA,这是更具体的应用。如果用Y叔的神包clusterProfiler做GSEA的话,需要输入的对象很简单,就是一组排过序的数字向量,这里可以是logFC或者相关系数(具体后面会知道)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> geneList <- gene_df$logFC
> geneList
   [1] -0.3885455532  0.2467344071  0.0903026505  0.1419874626  0.1666925658
   [6] -0.0332339569 -0.1111574881  0.1920079524  0.2683369453  0.1834692777
  [11]  0.1413467028  0.0139812991  0.2666602717  0.0672510451  0.1784876312
  [16] -0.4048927912  0.0491033960 -0.0391377292 -0.1960619184  0.0295863678
  [21]  0.0668118973 -0.4134487165 -0.0695667235  0.1275862624  0.1677585023
  [26] -0.0628605909  0.0342075099 -0.0218328844 -0.6710892754 -0.1621723730
#后面还有很多

如果我们直接提取logFC,可以看到logFC有高有低有正有负,这时候如果直接做GSEA是不行的,GSEA要求输入对象是排过序的向量,我们就可以用到向量的命名和sort

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> names(geneList) = gene_df$SYMBOL
> geneList = sort(geneList, decreasing = TRUE)
> geneList
         A4GALT            AAAS            AACS           AADAT           AAGAB 
      1.4274086       1.2361003       1.0576695       1.0375003       1.0256938 
           AAK1           AAMDC            AAMP            AAR2           AARS2 
      0.9780116       0.9759169       0.9236183       0.9226613       0.9015509 
         AARSD1           AASDH        AASDHPPT            AASS            AATF 
      0.8799943       0.8419719       0.8249711       0.8224399       0.8160568 
          ABCA1          ABCA10           ABCA2           ABCA5           ABCA7 
      0.8154475       0.8109042       0.8024702       0.7867225       0.7807610
#后面还有很多

向量的名字是基因名,向量的按logFC大小排序,这时候做把geneList这个向量传进去就可以做GESA分析,分析完就可以直接出图了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
> hallmarks <- read.gmt("resource/h.all.v7.5.1.symbols.gmt")
> y <- GSEA(geneList,TERM2GENE =hallmarks)
preparing geneSet collections...
GSEA analysis...
leading edge analysis...
done...
There were 11 warnings (use warnings() to see them)
> yd <- as.data.frame(y)
> library(ggplot2)
> dotplot(y,showCategory=6,split=".sign")+facet_grid(~.sign)

是不是挺有用了,这只是一个简单的小例子,在此是想说明对大部分人来说,做生信数据挖掘的过程中,出图从来不是最重要的事,不是GSEA怎么做,dotplot怎么画。最重要的是数据的清洗、想法的获得,是geneList这个向量或者其他要给的对象它怎么来的。我现在就是卡在这才回来补课。tidyverse那些包,apply函数家族的运用,正则表达式这些,都很考验R基础。有了一个好的想法,数据整理好了,出图就是像上面那样分分钟的事儿。

最后,希望各位小伙伴在生信技能树团队的带领下,打好基础,熟练运用各种数据处理函数,早日看到自己的学习成果,完成属于自己的生信分析。与君共勉!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信技能树 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
学习order函数的记录
看到这个问题的时候,我是不知所云的,因为课堂上只讲过order(x),没有出现order(x,y),不理解其运算逻辑,就不能理解函数的结果。因此我整合了order( )函数从基础到上述问题解决的学习过程,仅供参考!
生信技能树
2022/06/08
1.1K0
学习order函数的记录
转录组分析—再谈GSEA
Gene Set Enrichment Analysis (GSEA) 是一种生物信息学方法,用于确定基因集合(gene sets)在基因表达数据中的显著性变化。它广泛应用于基因表达数据的功能解释,帮助研究者理解在特定实验条件下哪些生物学通路或功能类别是活跃的。以下是GSEA的相关知识点:
sheldor没耳朵
2024/08/05
1630
转录组分析—再谈GSEA
左手用R右手Python系列7——排序
排序可能是日常数据清洗过程中比较高频的应用了,今天这一篇给大家介绍R语言和Python中最为常见的排序函数应用。 R语言: sort order rank arrange 排序根据对向量排序和数据框的排序要使用不同的函数,以上四个函数中,前三个是针对向量的,最后一个是针对数据框的。 sort x<-c(97,93,85,74,32,100,99,67) sort(x,decreasing=F) #默认是生序排列,其中decreasing参数默认为FALSE。 sort(x,decreasing=T) #降序
数据小磨坊
2018/04/11
1.5K0
左手用R右手Python系列7——排序
四句话代码GSEA
需要3个包,分别是:'clusterProfiler','enrichplot','patchwork',然后是DOSE包里面有一个geneList的向量,它是排序好的基因列表,而且是entrezID形式,使用 gseKEGG 函数即可做gsea分析啦 :
生信技能树
2024/11/27
1670
四句话代码GSEA
基因集富集分析(GSEA)及其可视化
基因集富集分析(Gene Set Enrichment Analysis, GSEA)是是一种计算方法,用于确定事先定义的一组基因是否在不同的样品中差异表达。
青青青山
2022/07/04
5.6K0
基因集富集分析(GSEA)及其可视化
新TCGA+文献复现里的几种算法
reads计数数据(测序的短片段),会匹配到基因。若匹配到,则匹配到的基因会count+1。(一个基因对应4个read,即count为4)
用户10758803
2024/03/10
2970
GseaVis富集分析可视化
今天要介绍的老俊俊的R包:GseaVis,专门用于GSEA富集分析可视化,相比于enrichplot,增加了很多好用的功能,很多功能让我直呼 泰裤辣!!
医学和生信笔记
2023/08/30
1.1K0
GseaVis富集分析可视化
R包基础实操—tidyverse包
核心软件包是ggplot2、dplyr、tidyr、readr、purrr、tibble、stringr和forcats,它们提供了建模、转换和可视化数据的功能。
生信技能树jimmy
2021/10/11
3.4K0
R包基础实操—tidyverse包
GSEA富集分析可视化
今天给大家介绍GSEA,基因集富集分析,的可视化!主要是带你详细了解如何自定义GSEA的经典图形。
医学和生信笔记
2023/08/30
2K0
GSEA富集分析可视化
转录组GSE105789_小鼠数据下游分析注意事项
简单记录下GSE105789小鼠数据的下游分析的主要事项,与human的数据分析的主要区别是在进行id转换、kegg、go、gsea时,需要注意数据库和物种信息,应该选择小鼠。
sheldor没耳朵
2024/08/21
2070
转录组GSE105789_小鼠数据下游分析注意事项
三阴性乳腺癌表达矩阵探索笔记之GSEA
基于超几何分布检验的富集分析做KEGG数据库的时候,它总共只有七千多个基因,人类总的背景基因有两万多个,被KEGG记住的只有6500个(一直在增加),假设一条通路有117个基因参与,我们的差异基因中有10个与之重合,这已经是很多了,超几何分布检验会判定是统计学显著。
生信技能树
2020/10/26
1K0
三阴性乳腺癌表达矩阵探索笔记之GSEA
TNBC数据分析-GSE27447-GPL6244
五月份的学徒专注于GEO数据库里面的表达量芯片数据处理,主要的难点是表达量矩阵获取和探针的基因名字转换,合理的分组后就是标准的差异分析,富集分析。主要是参考我八年前的笔记:
生信技能树
2021/08/25
2.6K0
TNBC数据分析-GSE27447-GPL6244
十二、R语言的综合应用
[1] "The birch canoe slid on the smooth planks."
叮当猫DDM
2023/03/01
3.1K0
R语言学习day2
paste里的数据之间默认是空格连接,也可以特别指定为其他符号,用sep = “”
VOHOKO
2024/03/06
2620
批量的GSEA及基因表达热图可视化
差异基因的生物学功能富集分析,除GO和KEGG外,另一种较为稳妥的生物学功能数据库注释是GSEA方法,研究者可以针对特定的通路基因进行研究,再加上基因的表达热图更为直观!(下面演示一个批量运行的示例)
生信菜鸟团
2023/09/26
1.3K0
批量的GSEA及基因表达热图可视化
simplifyEnrichment的使用示例
simplifyEnrichment主要针对富集分析的结果进行简化,并提供了一些强大的可视化函数。
医学和生信笔记
2023/08/30
7650
simplifyEnrichment的使用示例
TNBC数据分析-GSE76275-GPL570
五月份的学徒专注于GEO数据库里面的表达量芯片数据处理,主要的难点是表达量矩阵获取和探针的基因名字转换,合理的分组后就是标准的差异分析,富集分析。主要是参考我八年前的笔记:
生信技能树
2021/08/25
2.4K0
TNBC数据分析-GSE76275-GPL570
生信入门马拉松之R语言基础-脚本项目管理、条件循环、表达矩阵和一丢丢数据挖掘(Day 7)
数据框函数- 排序arrange()和desc参数、distinct()去重复、mutate()数据框新增列
Crazy_George
2024/04/17
2051
R语言基础函数没有排序后取前面几个的功能函数top
以上只是R语言中一些简单的基础函数例子,R语言提供了丰富的函数和包,涵盖了数据处理、统计分析、图形绘制等各个方面。这些简单的函数是R语言中的基础,对于数据处理和分析非常重要,可以方便地完成许多常见的任务。
生信技能树
2023/09/04
2860
R语言基础函数没有排序后取前面几个的功能函数top
单细胞功能注释和富集分析(GO、KEGG、GSEA)(2021公开课配套笔记)
在前面几节我们已经知道各个细胞亚群的maerker基因,接下来我们对这些marker基因进行功能注释和富集分析。
生信技能树
2021/07/06
17.8K1
相关推荐
学习order函数的记录
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文