как ранжировать значения в векторе и дать им соответствующие значения? - PullRequest
0 голосов
/ 09 декабря 2010

Теперь я делаю это, зацикливаясь на отсортированном векторе, но, возможно, есть более быстрый способ использования внутренних функций 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 ]

4 голосов
/ 10 декабря 2010

Это более понятно.Следовательно:

> 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

, и если вы хотите сохранить заказ, то:

1 голос
/ 24 января 2014

Вы можете попробовать это: (Обратите внимание, что вам может потребоваться другое поведение для повторяющихся значений. Это даст каждому значению уникальный ранг)

> 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
1 голос
/ 30 марта 2011

Решение Joris подходит, но если у вас длинные векторы, использование соответствия и уникальности немного (в 3 раза):

> 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
0 голосов
/ 09 декабря 2010

Вы, очевидно, хотите получить результаты чего-то вроде table (), но выстроены рядом со значениями: попробуйте использовать функцию ave():

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

Хитрость здесь в том, что синтаксис ave немного отличается от tapply, потому что вы вводите произвольно длинный набор аргументов фактора и вам нужно поместить FUN = перед функцией, потому что аргументы после тройных точек не обрабатывать по заказу. Они должны быть названы.

0 голосов
/ 09 декабря 2010

Похоже, вы рассчитываете прогоны в данных, если это так, посмотрите на функцию rle.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...