2016-06-02 6 views
1

Ich würde eine Funktion benötigen, die mein Datenframe für eine ansonsten identische Zeile, aber mit Datum minus 1 überprüft und true zurückgibt, wenn es existiert. Es ist ein großer Datenrahmen, also würde ich es gerne so effizient wie möglich machen.Funktion, um zu prüfen, ob identische Zeile, Datum minus 1 existiert

Nehmen wir zum Beispiel die folgende Datenrahmen:

name |date  
Timmy |01/Jan/2016 
Timmy |02/Jan/2016 
Timmy |03/Jan/2016 
Sally |04/Jan/2016 
Johnny|13/Feb/2016 
Johnny|29/Mar/2016 

Die Funktion Timmy|02/Jan/2016 sehen sollte, prüfen Sie, ob Timmy|01/Jan/2016 vorhanden ist, und das Rück true. Die sich ergebende Datenrahmen würde wie folgt aussehen:

name |date  |hasDateMinusOne 
Timmy |01/Jan/2016|false 
Timmy |02/Jan/2016|true 
Timmy |03/Jan/2016|true 
Sally |04/Jan/2016|false 
Johnny|13/Feb/2016|false 
Johnny|29/Mar/2016|false 

This is the closest answer I've found. Obwohl es von Hadley beantwortet wurde, ist es 5 Jahre alt oder älter dplyr. Ich frage mich, ob es immer noch der effizienteste Weg ist, um 1.000.000+ Zeilen zu bearbeiten.

Danke!

Sean

Antwort

2

Wenn Sie Format date als Datum, können Sie nur eine subtrahieren:

library(dplyr) 

df %>% group_by(name) %>% 
    mutate(date = as.Date(date, '%d/%b/%Y'), 
      hasDateMinusOne = (date - 1) %in% date) 

# Source: local data frame [6 x 3] 
# Groups: name [3] 
# 
#  name  date hasDateMinusOne 
# (fctr)  (date)   (lgl) 
# 1 Timmy 2016-01-01   FALSE 
# 2 Timmy 2016-01-02   TRUE 
# 3 Timmy 2016-01-03   TRUE 
# 4 Sally 2016-01-04   FALSE 
# 5 Johnny 2016-02-13   FALSE 
# 6 Johnny 2016-03-29   FALSE 
+0

Vielen Dank! Das hat es getan. –

1

Wir können dies nur base R mit tun. Konvertieren Sie das 'Datum' in 'Datum' Klasse mit transform, dann mit ave wir gruppieren nach 'Name' und finden, ob der Tag davor gefunden wird %in% die 'Datum' Spalte.

df <- transform(df, date = as.Date(date, "%d/%b/%Y")) 
df$hasDateMinusOne <- with(df, !!ave(as.integer(date), name, 
      FUN = function(x) (x-1) %in% x)) 

Wenn Effizienz Angelegenheiten, ist eine weitere Option data.table. Konvertieren Sie den 'data.frame' in 'data.table' (setDT(df)), ändern Sie 'date' in 'date' Klasse, gruppiert nach 'name' finden wir, ob der vorherige Tag %in% die Spalte 'Datum' gefunden wird.

setDT(df)[, date := as.Date(date, '%d/%b/%Y') 
    ][, hasDateMinusOne := (date-1) %in% date, by = name] 
df 
#  name  date hasDateMinusOne 
#1: Timmy 2016-01-01   FALSE 
#2: Timmy 2016-01-02   TRUE 
#3: Timmy 2016-01-03   TRUE 
#4: Sally 2016-01-04   FALSE 
#5: Johnny 2016-02-13   FALSE 
#6: Johnny 2016-03-29   FALSE