2010-12-09 35 views
-2

Maintenant, je le fais en bouclant par un vecteur trié, mais peut-être il y a un moyen plus rapide d'utiliser les fonctions R internes, et peut-être que je n'ai même pas besoin de trier.comment classer des valeurs dans un vecteur et leur donner des valeurs correspondantes?

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 

Le code est utilisé pour faire des graphiques avec des entiers sur l'axe X au lieu des données réelles parce que pour moi la distance entre les valeurs de X n'est pas important. Donc, dans mon cas, la plus petite valeur x est toujours 1. et la plus grande est toujours égale au nombre de valeurs X présentes. - edit: en raison d'un malentendu à propos de ma question, j'ai ajouté un code auto-suffisant avec sortie.

+1

Cette question n'est pas claire car elle est actuellement libellée. A quoi ressemblent vos données d'entrée ('csvdata')? À quoi le produit final est-il censé ressembler? Est-ce que vous essayez juste d'obtenir une tabulation des valeurs uniques dans csvdata? Si oui, regardez 'table()' – Chase

+0

mes données sont une matrice de nombres étiquetés X et Y, mais une seule colonne de csvdata m'interesse ici, c'est X, et z est un nouveau vecteur contenant des valeurs numérotées de csvdata [ , 'X'] – rsk82

+0

désolé, mais je ne vois pas comment le facteur est capable de faire ce que j'ai besoin – rsk82

Répondre

4

C'est plus clair. Par conséquent:

> 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 

Aucun tri nécessaire. Et comme on dit, voir aussi ?factor

et si vous voulez préserver l'ordre, alors:

> 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 
+0

Merci beaucoup, c'est exactement ça! – rsk82

+1

Pour information seulement: négation du classement du vecteur du plus grand au plus petit (ordre décroissant), p. Ex. 'cbind (v, as.numeric (facteur (-v)))' –

0

Il semble que vous comptez des passages dans les données, si c'est le cas, regardez la fonction rle.

+0

Non! Vous ne pouvez pas voir à partir du code fourni, c'est si simple que je devrais dire des mots à côté de lui. Si vous avez le vecteur 1,1,6,8,4,8 il donne 1,1,2,3,4,3 – rsk82

+0

@ user393087 - comment donne-t-il 1, 1, 2, 3, 4, 3? Comment le compteur diminue-t-il? Vous pouvez obtenir une meilleure réponse si vous donnez l'objectif final, au lieu d'un pas de bébé. Parfois, il y a une fonction qui enveloppe toutes les marches en un. –

+0

Ici, je dois m'excuser pour un petit malentendu. Dans le premier post, j'ai demandé une fonction peut-être construire qui est capable de faire cette entrée et sortie sans tri, ce qui, bien sûr, prend du temps. Mon code que j'ai collé N'est pas capable de faire ça, le vecteur ou la matrice doit être trié. Et puis, je crois que maintenant l'exemple n'illustre pas ce que je pensais. J'ai essayé de le faire si j'avais fait une erreur. Je vais poster une sortie réelle en une minute. – rsk82

0

Vous voulez apparemment les résultats de quelque chose comme tableau() mais alignés à côté des valeurs: Essayez d'utiliser la fonction ave():

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

L'astuce ici est que la syntaxe de ave est un peu différent de celui tapply parce que vous mettez dans un arbitrairement long jeu d'arguments et vous devez mettre dans le FUN = devant la fonction parce que les arguments après les points triples ne sont pas processus par ordre. Ils doivent être nommés.

+0

impression (ave (vect, facteur (vect), FUN = longueur)) - donne: [1] 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 - ceci est fait sur le vecteur fourni dans (édité maintenant) premier message. Donc ce n'est pas ça. – rsk82

1

solution Joris est juste, mais si vous avez un long vecteurs, il est un peu (3x) plus efficace d'utiliser correspondance et unique:

> 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 
1

vous pouvez essayer: (. Notez que vous pouvez un comportement différent pour les valeurs répétées cela donnera à chaque valeur d'un rang unique)

> 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