2017-06-02 1 views
1

Ich habe einen Datenrahmen (df), der 2,5 Millionen Zeilen hat. Beispieldatenrahmen sieht so aus:Wie bestimmte Zeilen in R extrahiert werden, ohne die gesamten Daten immer wieder durchlaufen zu müssen

PERMNO <- c(10000,10000,10001,10001,10001,10001, 10002,10002,10002) 

TICKER <- c('OMFGA','OMFGA', 'GFGC', 'GFGC', 'GFGC', 'GFGC', 'MBNC', 'MBNC', 'MBNC') 

date <- as.Date(c('1986-03-31','1986-04-30','1986-01-31', '1986-01-31', '1986-03-31', '1986-04-30', '1986-04-30','1986-05-30', '1986-05-30')) 

df = data.frame(PERMNO, date, TICKER) 

In diesem Beispiel gibt es 3 einzigartige PERMNO. Jetzt muss ich alle Daten für die gegebene PERMNO extrahieren und prüfen, ob es doppelte Daten gibt. Meine Absicht ist, Zeilen mit doppelten Daten für eine bestimmte PERMNO zu entfernen. Diese Vorgehensweise mache ich für alle einzigartigen PERMNO

Mein Ansatz: Ich verwende Subset-Funktion, um Daten für eine bestimmte PERMNO zu extrahieren und dann nach Dubletten in Daten zu überprüfen. Bei diesem Ansatz durchläuft mein Code jedes Mal die gesamten Daten (2,5 Millionen Zeilen im ursprünglichen Dataset), um Daten für eine bestimmte PERMNO zu extrahieren. Gibt es einen kürzeren Weg, dies zu tun? Da ich 22000 einzigartige PERMNO habe, dauert der Code in der For-Schleife ewig. Hier

ist der Code Ich verwende:

uniqueperm = unique(df$PERMNO) 

lenperm = length(uniqueperm) 

data_final = df[FALSE,] 

for(i in 1:lenperm){ 

     perm = uniqueperm[i] 
     df1 = filter(df, PERMNO == perm) 
     df1 = subset(df1,!duplicated(df1$date)) 
     data_final = rbind(data_final,df1) 
     df1 = df1[FALSE,] 
} 

data_final 
+1

Ist das nicht ein Duplikat auf 'PERMNO' und' Datum', wenn Sie nach Duplikaten in jeder 'PERMNO'-Untermenge suchen? I.e. 'dupliziert (df [c (" PERMNO "," date ")]' Oder fehlt mir etwas Subtilität? – thelatemail

+0

Können Sie Ihren Code hinzufügen (For-Schleife), damit wir etwas Referenz haben? –

+0

Es würde helfen, wenn Sie den Code, den Sie ausführen, gepostet habe, bekomme ich, was Sie beschreiben, aber es wäre viel einfacher, es genau zu sehen. – jamzsabb

Antwort

1

Dies sollte für eine große Datensatz schneller als eine for-Schleife:

dates <- lapply(split(df, df$PERMNO), '[[', "date") 
df2 <-mapply(function(x,y)x[!y,], 
      split(df,df$PERMNO), 
      lapply(dates, duplicated), 
      SIMPLIFY = FALSE) 

do.call(rbind, df2) 

#   PERMNO  date TICKER 
# 10000.1 10000 1986-03-31 OMFGA 
# 10000.2 10000 1986-04-30 OMFGA 
# 10001.3 10001 1986-01-31 GFGC 
# 10001.5 10001 1986-03-31 GFGC 
# 10001.6 10001 1986-04-30 GFGC 
# 10002.7 10002 1986-04-30 MBNC 
# 10002.8 10002 1986-05-30 MBNC 
+0

Ich habe diesen Code ausprobiert. Es dauert sehr lange. Auf der Suche nach etwas, das schneller läuft. – DenaG

3

Dies sollte ziemlich schnell sein für alle , aber massiver Datensätze:

df[!duplicated(df[c("PERMNO","date")]),] 
# PERMNO  date TICKER 
#1 10000 1986-03-31 OMFGA 
#2 10000 1986-04-30 OMFGA 
#3 10001 1986-01-31 GFGC 
#5 10001 1986-03-31 GFGC 
#6 10001 1986-04-30 GFGC 
#7 10002 1986-04-30 MBNC 
#8 10002 1986-05-30 MBNC 

Ein grundlegendes Timing auf ähnliche Daten zu dem, was Sie haben:

df2 <- data.frame(PERMNO=sample(1:22000,2.5e6,replace=TRUE), date=1:2.5e6) 
nrow(df2) 
#[1] 2500000 
length(unique(df2$PERMNO)) 
#[1] 22000 
system.time(df2[!duplicated(df2[c("PERMNO","date")]),]) 
# user system elapsed 
# 3.48 0.08 3.56 
Verwandte Themen