如何在向量中对值进行排名并给出相应的值?

时间:2010-12-09 17:59:45

标签: r vector

现在我通过循环运行一个已排序的向量来实现它,但是使用内部R函数可能有更快的方法,也许我甚至不需要排序。

vect = c(41,42,5,6,3,12,10,15,2,3,4,13,2,33,4,1,1)
vect = sort(vect)
print(vect)
outvect = mat.or.vec(length(vect),1)
outvect[1] = counter = 1
for(i in 2:length(vect)) {
    if (vect[i] != vect[i-1]) { counter = counter + 1 }
    outvect[i] = counter
}

    print(cbind(vect,outvect))

 vect outvect
 [1,]    1       1
 [2,]    1       1
 [3,]    2       2
 [4,]    2       2
 [5,]    3       3
 [6,]    3       3
 [7,]    4       4
 [8,]    4       4
 [9,]    5       5
[10,]    6       6
[11,]   10       7
[12,]   12       8
[13,]   13       9
[14,]   15      10
[15,]   33      11
[16,]   41      12
[17,]   42      13

代码用于在X轴上制作带有整数的图表而不是真实数据,因为对于我来说,X值之间的距离并不重要。 因此,在我的情况下,最小的x值始终为1.并且最大值始终等于有多少X值。

- 编辑:由于对我的问题的一些误解,我添加了自给自足的代码和输出。

5 个答案:

答案 0 :(得分:4)

更清楚。因此:

> vect = c(41,42,5,6,3,12,10,15,2,3,4,13,2,33,4,1,1)
> cbind(vect,as.numeric(factor(vect)))
 [1,]   41 12
 [2,]   42 13
 [3,]    5  5
 [4,]    6  6
 [5,]    3  3
 [6,]   12  8
 [7,]   10  7
 [8,]   15 10
 [9,]    2  2
[10,]    3  3
[11,]    4  4
[12,]   13  9
[13,]    2  2
[14,]   33 11
[15,]    4  4
[16,]    1  1
[17,]    1  1

不需要排序。如上所述,另见?factor

如果您想保留订单,那么:

> cbind(vect,as.numeric(factor(vect,levels=unique(vect))))
      vect   
 [1,]   41  1
 [2,]   42  2
 [3,]    5  3
 [4,]    6  4
 [5,]    3  5
 [6,]   12  6
 [7,]   10  7
 [8,]   15  8
 [9,]    2  9
[10,]    3  5
[11,]    4 10
[12,]   13 11
[13,]    2  9
[14,]   33 12
[15,]    4 10
[16,]    1 13
[17,]    1 13

答案 1 :(得分:1)

Joris解决方案是正确的,但是如果你有一个很长的向量,那么使用匹配和唯一的效率会有点(3x):

> x=sample(1e5, 1e6, replace=TRUE)
> # preserve order:
> system.time( a<-cbind(x, match(x, unique(x))) )
   user  system elapsed 
   0.20    0.00    0.22 
> system.time( b<-cbind(x, as.numeric(factor(x,levels=unique(x)))) )
   user  system elapsed 
   0.70    0.00    0.72 
> all.equal(a,b)
[1] TRUE
> 
> # sorted solution:
> system.time( a<-cbind(x, match(x, sort(unique(x)))) )
   user  system elapsed 
   0.25    0.00    0.25 
> system.time( b<-cbind(x, as.numeric(factor(x))) )
   user  system elapsed 
   0.72    0.00    0.72 
> all.equal(a,b)
[1] TRUE

答案 2 :(得分:1)

你可以试试这个: (请注意,对于重复值,您可能需要不同的行为。这将为每个值提供唯一的排名)

> x <- sample(size=10, replace=T, x=1:100)
> x1 <- vector(length=length(x))
> x1[order(x)] <- 1:length(x)
> cbind(x, x1)
       x x1
 [1,] 40  1
 [2,] 46  4
 [3,] 43  3
 [4,] 41  2
 [5,] 47  5
 [6,] 84 10
 [7,] 75  8
 [8,] 60  7
 [9,] 59  6
[10,] 80  9

答案 3 :(得分:0)

看起来您正在计算数据中的运行,如果是这种情况,请查看rle函数。

答案 4 :(得分:0)

您显然希望像table()这样的结果,但在值旁边排列:尝试使用ave()函数:

csvdata$counts <- ave(csvdata[, "X"], factor(csvdata[["X"]]), FUN=length)

这里的诀窍是ave的语法与tapply有点不同,因为你输入了一组任意长的因子arrguments并且你需要在函数前放入FUN =因为三点之后的参数是不按订单处理。他们需要被命名。