2013-03-08 2 views
3

Si j'ai une trame de données qui ressemble à ceci:Attribution identifiant unique aux lignes dupliquées

x y 
13 a 
14 b 
15 c 
15 c 
14 b 

et je voulais que chaque groupe de lignes correspondant à un identifiant unique, comme ceci:

x y id 
13 a 1 
14 b 2 
15 c 3 
15 c 3 
14 b 2 

Y a-t-il un moyen facile de le faire?

Merci

+0

Est-ce votre exemple trop simpliste ou contient-elle une faute de frappe, comme ici id est exactement le même que x? –

+0

peut-être que mon exemple est un peu trompeur, je vais le changer! – by0

+0

Une question similaire en utilisant 'data.table': http://stackoverflow.com/questions/13018696/data-table-key-indices-or-group-counter – flodel

Répondre

2

C'est la première chose que je pensais:

Faire une nouvelle variable qui combine simplement les deux colonnes en collant leurs valeurs à cordes:

a<-paste0(z$x,z$y) #z is your data.frame 

Le faire ceci comme factoriser et le combiner à votre base de données:

cbind(z,id=factor(a,labels=1:length(unique(a)))) 

EDIT: @f Lodel est préoccupé par l'utilisation paste0, il est préférable d'utiliser paste ordinaire, ou l'interaction:

a<-interaction(z,drop=TRUE) 
cbind(z,id=factor(a,labels=1:length(unique(a)))) 

Cela suppose que vous voulez séparer x=ab, y=c et x=a, y=bc. Si ce n'est pas le cas, utilisez paste0.

+2

(+1) Je changerais 'a' en' do.call (paste0, z) '. Et '1: length (unique (a))' à 'seq_along (unique (a))' – Arun

+0

Bon point, je ne me souviens jamais du 'seq_along' et' do.call' était nouveau pour moi. Merci. –

4

Je suis un peu préoccupé par l'approche paste0. Si vos colonnes contenaient des données plus complexes, vous pourriez obtenir des résultats surprenants, par ex. Imaginez:

x y 
ab c 
a bc 

Une solution consiste à remplacer paste0(...) avec paste(..., sep = "@"). Même ainsi, vous ne pouvez pas trouver un sep assez général pour qu'il fonctionne avec n'importe quel type de données car il y a toujours une probabilité non nulle que sep sera contenue dans un type de données.

Une approche plus robuste consiste à utiliser une approche de division/transformation/combinaison. Vous pouvez certainement le faire avec le paquet base mais plyr rend un peu plus facile:

library(plyr) 
.idx <- 0L 
ddply(df, colnames(df), transform, id = (.idx <<- .idx + 1L))  

Si cela est trop lent, je recommande une approche data.table, tel que proposé ici: data.table "key indices" or "group counter"

+0

Bon point sur 'paste0', j'ai ajouté une meilleure solution qui est en fait plus propre que la réponse originale. –

+0

@Hemmo. Je pense que l'utilisation de 'interaction' équivaut à utiliser' paste (..., sep = '.') '; théoriquement, il subit le même problème (improbable) dont je parlais. – flodel

+0

Oh oui, vous avez raison de dire qu'ils produisent la même chose, mais ils fonctionnent tous les deux correctement dans la situation dont vous avez parlé, car vous obtenez 'ab.c' et' a.bc' qui sont distincts. Et je suppose que c'est ce que l'on veut. 'paste0' ne fonctionne pas correctement (cela fonctionne si la séparation n'est pas voulue). –