学习order函数的记录

2022-06-08 20:36:36 浏览数 (1)

下面是学习order函数的记录

(生信技能树学员luka)

写下这篇笔记的初衷是有小伙伴在群里提出问题,我在寻找答案过程中参与了学习群内的互动,借此机会写下个人浅薄的理解,希望帮助您更好理解order( )函数逻辑,如有错误,请指正!

最初问题来源:如何理解order(x,y)的结果 ?

看到这个问题的时候,我是不知所云的,因为课堂上只讲过order(x),没有出现order(x,y),不理解其运算逻辑,就不能理解函数的结果。因此我整合了order( )函数从基础到上述问题解决的学习过程,仅供参考!

一、order( )函数的介绍

排序在R语言处理数据的重要过程,有多种内置的基本函数进行排序。

  1. order( ) 函数:将元素按数值、字母顺序、逻辑值等从小到大排序后,返回元素的原始次序(位置);
  2. sort( ) 函数:将元素按数值、字母顺序、逻辑值等从小到大排序后,返回已排序的元素;
  3. rank( ) 函数:返回元素在向量中的秩(排名);
代码语言:javascript复制
> x1 <- c(3, 1, 4, 15, 92)
> order(x1) #排序后返回原始次序(位置)
[1] 2 1 3 4 5
> sort(x1) #返回已排序的元素
[1]  1  3  4 15 92
> rank(x1) #返回元素在向量中的秩(排名)
[1] 2 1 3 4 5

order( )的参数和默认值

代码语言:javascript复制
order(..., na.last = TRUE, decreasing = FALSE,
      method = c("auto", "shell", "radix"))

# na.last 是否将缺失值放在最后,TRUE放在最后,FALSE放在最前
# decreasing 是否按降序进行排列,TRUE为降序排列,FALSE为升序排列

二、order( )函数应用于单个向量

代码语言:javascript复制
# 构建几个向量
> x <- c(1,1,3:1,1:4,3);x
 [1] 1 1 3 2 1 1 2 3 4 3
> y <- c(9,9:1);y
 [1] 9 9 8 7 6 5 4 3 2 1

# order()对各向量进行排序,返回排序后的原始次序
> order(x) #当遇到相等值时,按原始顺序排列
 [1]  1  2  5  6  4  7  3  8 10  9
> order(y)
 [1] 10  9  8  7  6  5  4  3  1  2

# order()函数默认为升序排序,通过decreasing = TRUE 改为降序排序
> order(x,decreasing = T)
 [1]  9  3  8 10  4  7  1  2  5  6
# 也可以通过在向量前加上"-",进行反向排序
> order(-x)
 [1]  9  3  8 10  4  7  1  2  5  6

三、order( )应用于多个向量

当order( )中包含两个向量时

代码语言:javascript复制
# order()对2个向量进行排序
> order(x,y)
 [1]  6  5  1  2  7  4 10  8  3  9

似乎突然不知所云,我们将x,y组成数据框,尝试解读一下

代码语言:javascript复制
> xy <- data.frame(x=x,y=y) #行名相当于原始次序
> xy[order(xy$x),]  #只看x这一列这里相当于order(x)的结果,行名为原始次序
> xy[order(xy$x,xy$y),] 

一开始,我心里是有疑惑的:

x和y是单独向量,他们之间没有关联,为什么order(x,y)跟组成数据框之后分析结果是一样的?是否因为我们利用order函数把x, y放在一起,导致函数默认他们之间是对应的关系?

为了验证这一点,我们可以把order( )处理过后,x和y对应的值输出来对比图中的数据。

代码语言:javascript复制
> order(x)
 [1]  1  2  5  6  4  7  3  8 10  9
> x[order(x)]  #与上图 xy[order(xy$x),] 的x列一致
 [1] 1 1 1 1 2 2 3 3 3 4
> order(x,y)
 [1]  6  5  1  2  7  4 10  8  3  9
> x[order(x,y)] #与上图 xy[order(xy$x,xy$y),] 的x列一致
 [1] 1 1 1 1 2 2 3 3 3 4
> y[order(x,y)] #与上图 xy[order(xy$x,xy$y),] 的y列一致
 [1] 5 6 9 9 4 7 1 3 8 2

结果发现确实一致,但是我忽略了一个问题。

小洁老师:事实上,单独的向量和数据框里单独取出来了一列,没有任何区别。他们的对应关系是只能自己把握,无法指定也不必指定的。

xy$x 与 x 本质上都只是一个向量,其对应关系只有使用函数者自己理解和把握。当两个向量长度相等时,只要符合函数运算规律,放在order( )中(也许其他函数也类似)就可以形成运算,并不需要特意指定也无法指定。当然,这并不妨碍我们使用函数。需要注意的是,如果两个向量长度不等,是无法进行运算的。

代码语言:javascript复制
> x <- 1:3
> y <- 5:1
> order(x,y)
Error in order(x, y) : argument lengths differ

如果你还没有理解上述函数运算逻辑,我们换一个更贴近生活的例子。

生信学习班里的几位同学最近进行了R语言和Linux的测试,现在我们要根据他们的成绩进行排序。排序要求如下,首先按R语言成绩排名,如果R语言成绩一致,则再按Linux成绩排名。

  1. 构建成绩表
代码语言:javascript复制
> name <- c('James','John','Luka','Green','Lisa','Curry','Jimmy','Xiaojie')
> R_scores <- c(88,68,76,76,93,76,98,98)
> Linux_scores <- c(78,63,76,82,81,63,92,95)
> scores <- data.frame(name=name,R_scores=R_scores,Linux_scores=Linux_scores)
> print(scores)
     name R_scores Linux_scores
1   James       88           78
2    John       68           63
3    Luka       76           76
4   Green       76           82
5    Lisa       93           81
6   Curry       76           63
7   Jimmy       98           92
8 Xiaojie       98           95
  1. 按R语言成绩(R_scores)进行排序,此时行名相当于order(x)
代码语言:javascript复制
rank_R <- scores[order(scores$R_scores),]
print(rank_R)
     name R_scores Linux_scores
2    John       68           63
3    Luka       76           76
4   Green       76           82
6   Curry       76           63
1   James       88           78
5    Lisa       93           81
7   Jimmy       98           92
8 Xiaojie       98           95
  1. 在R语言成绩排名的基础上,进行Linux(Linux_scores)成绩排名
代码语言:javascript复制
> rank_R_Linux <- scores[order(scores$R_scores,scores$Linux_scores),]
> print(rank_R_Linux)
     name R_scores Linux_scores
2    John       68           63
6   Curry       76           63
3    Luka       76           76
4   Green       76           82
1   James       88           78
5    Lisa       93           81
7   Jimmy       98           92
8 Xiaojie       98           95

四、最初的问题如何解决

我们回到最初问题来源:如何理解order(x,y)的结果 ?

答案已经显而易见:

首先x和y要有一对一的对应关系,这句代码才有意义!否则虽然代码不报错,逻辑也是错的。order(x,y) 的运算过程分为两个部分:

  1. 先按照x从小到大排序
  2. x有相同数值时,按照y从小到大排列;如果x里没有相同数值,y就用不上啦。

最后输出x对应的原始次序(位置)

同理,我们可以尝试理解 order(y,x) 的运算逻辑。

0 人点赞