2013-06-27 12 views
5

Dies ist mein erster Beitrag und ich bin neu in der Programmierung und R.Mit R, Wie kann ich sequentielle doppelte Werte in einer einzigen Spalte einer Datenrahmen Flagge

Ich versuche, eine neue Spalte zu erstellen markiere oder sequenziell duplizierte Werte in einer separaten Spalte kennzeichnen.

df < - c (2,2,2,2,3,4,3,4,3,4,2,3,7,7,7))

die doppelte Funktion verwenden gibt die folgende:

data.frame (Wert = df, flag = dupliziert (df))

value flag 
1  2 FALSE 
2  2 TRUE 
3  2 TRUE 
4  2 TRUE 
5  3 FALSE 
6  4 FALSE 
7  3 TRUE 
8  4 TRUE 
9  3 TRUE 
10  4 TRUE 
11  2 TRUE 
12  3 TRUE 
13  7 FALSE 
14  7 TRUE 
15  7 TRUE 

Was würde Ich mag ist:

value flag 
1  2 TRUE 
2  2 TRUE 
3  2 TRUE 
4  2 TRUE 
5  3 FALSE 
6  4 FALSE 
7  3 FALSE 
8  4 FALSE 
9  3 FALSE 
10  4 FALSE 
11  2 FALSE 
12  3 FALSE 
13  7 TRUE  
14  7 TRUE  
15  7 TRUE  

Meine Datensatz hat ove r 2 Millionen Beobachtungen, also wäre die Lösung im Idealfall effizient.

Danke, John

+0

Da Sie hier relativ neu sind, möchten Sie vielleicht die [** über **] (http://stackoverflow.com/about) und die [** faq **] lesen (http: // stackoverflow.com/faq) darüber, wie SO funktioniert. StackOverflow ist für alle viel wertvoller, wenn Sie eine Antwort erhalten, die Ihr Problem löst, indem Sie auf das kleine Häkchen klicken oder eine nützliche Antwort hinzufügen. Sie sind absolut nicht verpflichtet, beides zu tun, aber es ist ein großartiger Weg, der Seite "zurückzugeben", wenn eine Antwort tatsächlich Ihr Problem löst und dazu beiträgt, dass die Seite frei von unbeantworteten Fragen bleibt, die beantwortet wurden. Vielen Dank! –

Antwort

7

rle erhalten Sie, was Sie nach dem mit rep

rl <- rle(df) 
rep(rl$lengths != 1 , times = rl$lengths) 
# [1] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE 
# [15] TRUE 

in Kombination sind Und ich glaube rle ziemlich effizient ist.

Timing (MBP Ende 2008) auf einem 2E6 Länge Vektor:

system.time({ rl <- rle(df) 
res <- rep(rl$lengths != 1 , times = rl$lengths) 
}) 
# user system elapsed 
# 0.449 0.106 0.559 
+0

Hah! Ich hatte angefangen, über dieses Problem mit 'rle' nachzudenken und dann sah ich deine Antwort und wechselte. Und jetzt bist du zu 'rle' gewechselt. :) – asb

+0

Ich denke, du hast vor mir erkannt, dass der ältere Ansatz nirgendwohin ging. Upvote. – asb

+0

@asb lol, das passiert mir oft !! Danke für die Aufwertung :-) –

2

Da Sie mehr als 2 Millionen habe ich empfehlen Sie wirklich data.table zu wechseln. Hier meine Lösung mit rle ähnlich wie @Simon One, schreibe ich einfach seine data.table Version. Ich glaube das ist nicht immer offensichtlich, besonders für Anfänger (wie ich unter data.table).

library(data.table) 
set.seed(1234) 
dd <- sample(1:20, 2e+06, rep = TRUE) 
DT <- data.table(dd) 
system.time(DT[, `:=`(grp2, { 
          dd.rle = rle(dd) ## store rle to not call it twice 
          rep(dd.rle$lengths > 1, times = dd.rle$lengths) 
      })]) 
## user system elapsed 
## 1.17 0.06 1.28 
## user system elapsed <- rle twice 
## 1.69 0.11 1.86 

##  dd grp2 
## 1e+00: 3 FALSE 
## 2e+00: 13 TRUE 
## 3e+00: 13 TRUE 
## 4e+00: 13 TRUE 
## 5e+00: 18 FALSE 
## ---   
## 2e+06: 6 FALSE 
## 2e+06: 5 FALSE 
## 2e+06: 4 FALSE 
## 2e+06: 10 FALSE 
## 2e+06: 13 FALSE 
+0

+1 Ich wollte das machen, ehrlich! Ich habe gerade entschieden, dass es zu lange dauern würde, bis ich herausfinde - ich sitze immer noch bei 'data.table' Nette Arbeit. –

+0

@ SimonO101 danke. – agstudy

+2

Sie könnten vielleicht noch schneller sein, wenn Sie 'rle' nicht zweimal benutzen? –

Verwandte Themen