美文网首页编程学习
R学习笔记(16):排序的陷阱

R学习笔记(16):排序的陷阱

作者: TOP生物信息 | 来源:发表于2019-12-08 22:12 被阅读0次

    1. 先来认识三个函数:sort(), order(), rank()

    > sort(c(2,4,6,7,8,5))
    [1] 2 4 5 6 7 8
    > order(c(2,4,6,7,8,5))
    [1] 1 2 6 3 4 5
    
    > rank(c(2,4,6,7,8,5))
    [1] 1 2 4 5 6 3
    

    第一个很好理解,就是把一串数从小到大排列;
    第二个不好理解,它也是从小到大在原向量中找数,但返回数对应的索引值。即从小到大依次是:第1个数、第2个数、第6个数、第3个数...
    rank()按照原向量的顺序,给出各个元素的排名。

    给你一个数值向量,不清楚是否有重复值,现在需要返回升序的前4个数,怎么做?

    > sort(c(2,4,6,7,8,5))[1:4]
    [1] 2 4 5 6
    > c(2,4,6,7,8,5)[order(c(2,4,6,7,8,5))[1:4]]
    [1] 2 4 5 6
    
    > sort(c(2,4,6,7,8,5)[rank(c(2,4,6,7,8,5))<=4])
    [1] 2 4 5 6
    

    2. 《ggplot2图形艺术》第一版的一个例子

    求各个分组中carat最小的两个值

    ddply(diamonds,.(color),subset,order(carat)<=2)
    

    order(carat)<=2这种做法是错的,我们并不是要求索引值为1,2对应的数,而是order(carat)返回的向量的前两个索引值对应的数。
    这是返回值,待会儿可以回过头来看一下carat这一列。

    > ddply(diamonds,.(color),subset,order(carat)<=2)
       carat       cut color clarity depth table price    x    y    z
    1   0.30     Ideal     D     SI1  62.1    56   552 4.30 4.33 2.68
    2   0.24 Very Good     D    VVS1  61.5    60   553 3.97 4.00 2.45
    3   0.23 Very Good     E     VS1  59.5    58   402 4.01 4.06 2.40
    4   0.26 Very Good     E    VVS1  63.4    59   554 4.00 4.04 2.55
    5   0.23 Very Good     F     VS1  60.9    57   357 3.96 3.99 2.42
    6   0.23 Very Good     F     VS1  59.8    57   402 4.04 4.06 2.42
    7   0.23 Very Good     G    VVS2  60.4    58   354 3.97 4.01 2.41
    8   0.23     Ideal     G     VS1  61.9    54   404 3.93 3.95 2.44
    9   0.26 Very Good     H     SI1  61.9    55   337 4.07 4.11 2.53
    10  0.34     Ideal     H     VS2  60.4    57   555 4.54 4.57 2.75
    11  0.30     Ideal     I     SI2  62.0    54   348 4.31 4.34 2.68
    12  0.36     Ideal     I     VS2  61.9    56   556 4.54 4.57 2.82
    13  0.24 Very Good     J    VVS2  62.8    57   336 3.94 3.96 2.48
    14  1.01 Very Good     J     SI2  63.3    53  3088 6.35 6.31 4.01
    

    也许我们可以用rank()函数试一下:

    > ddply(diamonds,.(color),subset,rank(carat) <=2)
      carat     cut color clarity depth table price    x    y    z
    1  0.20   Ideal     D     VS2  61.5    57   367 3.81 3.77 2.33
    2  0.20 Premium     D     VS2  62.3    60   367 3.73 3.68 2.31
    3  0.20 Premium     D     VS2  61.7    60   367 3.77 3.72 2.31
    4  0.20 Premium     F     VS2  62.6    59   367 3.73 3.71 2.33
    5  0.23   Ideal     I    VVS1  63.0    56   414 3.94 3.90 2.47
    6  0.23 Premium     I    VVS1  60.5    61   414 3.98 3.95 2.40
    7  0.23   Ideal     J     VS1  62.8    56   340 3.93 3.90 2.46
    

    为什么只有7行记录,并且color为D有三行,E,G,H都没有, F,J只有一行?

    rank处理有重复的数值序列时,排名可能出现小数(重复值两个)或缺数(重复值多于两个)

    > rank(c(2,2,2,2,2,3,4))
    [1] 3 3 3 3 3 6 7 #没有1、2、4、5,并且3出现了5次
    > rank(c(1,2,2,3))
    [1] 1.0 2.5 2.5 4.0 #出现小数
    

    对应到刚才的问题,可能是如下情况,利用rank(carat) <=2分别找出3行、1行、0行记录:

    > rank(c(1,1,1,2))
    [1] 2 2 2 4
    > rank(c(1,2,2,2))
    [1] 1 3 3 3
    > rank(c(2,2,2,2,2,3))
    [1] 3 3 3 3 3 6
    

    那么问题来了,到底应该怎么修改才能求出升序的前两个数,这是我的想法:

    > ddply(diamonds,.(color),subset,carat <= sort(carat)[2])
       carat       cut color clarity depth table price    x    y    z
    1   0.20     Ideal     D     VS2  61.5    57   367 3.81 3.77 2.33
    2   0.20   Premium     D     VS2  62.3    60   367 3.73 3.68 2.31
    3   0.20   Premium     D     VS2  61.7    60   367 3.77 3.72 2.31
    4   0.20   Premium     E     SI2  60.2    62   345 3.79 3.75 2.27
    5   0.20   Premium     E     VS2  59.8    62   367 3.79 3.77 2.26
    6   0.20   Premium     E     VS2  59.0    60   367 3.81 3.78 2.24
    7   0.20   Premium     E     VS2  61.1    59   367 3.81 3.78 2.32
    8   0.20   Premium     E     VS2  59.7    62   367 3.84 3.80 2.28
    9   0.20     Ideal     E     VS2  59.7    55   367 3.86 3.84 2.30
    10  0.20 Very Good     E     VS2  63.4    59   367 3.74 3.71 2.36
    11  0.20     Ideal     E     VS2  62.2    57   367 3.76 3.73 2.33
    12  0.22   Premium     F     SI1  60.4    61   342 3.88 3.84 2.33
    13  0.20   Premium     F     VS2  62.6    59   367 3.73 3.71 2.33
    14  0.22   Premium     F     SI1  61.7    60   470 3.90 3.85 2.39
    ......
    

    有一点瑕疵,不能控制输出行数。

    如果你有更好的解决方法,欢迎留言!

    相关文章

      网友评论

        本文标题:R学习笔记(16):排序的陷阱

        本文链接:https://www.haomeiwen.com/subject/oscvgctx.html