2016-12-18 9 views
0

Ich versuche mit loops.table für mehrere Zeit mit mehreren Schleifen umzugehen und wurde frustriert. Mit sql ist es ziemlich intuitiv, aber mit R habe ich einige Probleme.Mehrere Schleifen mit data.table in R

Zum Beispiel würde ich eine txt-Datei (wie ich Hunderte von Dateien, jeweils etwa 1 GB haben), die Berechnungen (Summe Preis und Quant, wenn Zeit> my.time und für einige ausgewählte Isins, gruppiert von my.time, isin und price), schreibe die Ergebnisse in eine CSV-Datei, entferne die ursprüngliche TXT-Datei aus dem R-Speicher; Wiederholen Sie diese Berechnungen dann nacheinander für alle TXT-Dateien und hängen Sie die Ausgabe-CSV-Datei an.

Fangen wir mit den Beispieldaten (ziemlich klein, nur zwei identische Dateien für Illustration) beginnen:

 time<-format(seq.POSIXt(as.POSIXct(Sys.Date()), as.POSIXct(Sys.Date()+1), by = "1 sec"),"%H:%M:%S") 
     n<-length(time) 
     isin<-paste("US",1:n,sep="") 
     price<-rnorm(n,101,1) 
     quant<-rnorm(n,5,1) 
     dt<-data.table(time,isin,price,quant) 
     write.table(dt,"raw.txt",append = FALSE,sep = ",",col.names = TRUE, row.names = FALSE) 
     write.table(dt,"raw2.txt",append = FALSE,sep = ",",col.names = TRUE, row.names = FALSE) 

    my.files <- list.files(pattern = "raw*.txt") 
    my.time<-format(seq.POSIXt(as.POSIXct(Sys.Date()), as.POSIXct(Sys.Date()+1), by = "5 min"),"%H:%M:%S") 
    my.isin<-c("US100","US150","US225","US250","US1050") 

Dann versuche ich diese 2 einfache Schleifen:

 for (i in my.files){ 
       for (j in my.time){ 
       dt<-fread(i) 
     write.table(dt[which(isin %in% my.isin & time>j), 
      .(sprice=sum(price),squant=sum(quant),**time.my=j**), by = .(isin,price)], 
      "output.csv",append = TRUE,sep = ",",col.names = TRUE) 
     rm(dt) 
     }} 

Zweite edit: Die Schleife mit j fing schließlich an, für mich zu arbeiten (wegen des fettgedruckten Teils). Vielleicht wäre es möglich, ohne for-Schleifen zu arbeiten und die gleichen Ergebnisse zu erhalten?

Vielen Dank für Ihre Hilfe!

+0

an welchem ​​Punkt funktioniert es nicht für Sie? Hast du Warnung und Fehler gelesen, die du in deinem Code bekommst? – jangorecki

+0

Ja, zuerst bekomme ich diese Meldung: 'Fehler in' [.data.table' (dt, was (isin% in% my.isin & time> meine Zeit),: Die Elemente in der 'von' oder "keyby" -Liste ist length (86401,1,86401). Jede muss dieselbe Länge wie Zeilen in x oder Anzahl der Zeilen haben, die von i (0) zurückgegeben werden. " – Linas

+0

Ok, also beschweren Sie sich über Ihre Verwendung von' j' in "by". Vielleicht musst du zurückgehen und überlegen, was du damit machen wolltest ...? (Der meiste Code ist sehr verschieden von dem, was ich normalerweise sehe, also verstehe ich es nicht wirklich.) – Frank

Antwort

2

Das Problem, das Sie haben, ist die Ausgabe Ihrer which Anweisung gibt null Zeilen zurück. Zuerst würde ich Ihre Zeit in time Art umwandeln. Ich habe dann eine 5-Minuten-Gruppierungsvariable erstellt.

Dies würde zuerst Ihre Tabellen aggregieren.

dt[,`:=`(time= as.ITime(strptime(time, format="%H:%M:%S")))] 
dt[,`:=`(time5 = format(strptime("1970-01-01", "%Y-%m-%d", tz="UTC") + 
          round(as.numeric(time)/300)*300,"%H:%M"))] 

dt[, list(sprice = sum(price),squant= sum(quant)),by = c("time5","price","isin")][isin %in% my.isin] 


# time5  price isin sprice squant 
# 1: 00:00 102.46668  US1 102.46668 3.002960 
# 2: 00:00 99.02186  US2 99.02186 5.253252 
# 3: 00:00 100.23665  US3 100.23665 6.153950 
# 4: 00:00 102.21466  US4 102.21466 3.461051 
# 5: 00:00 100.97890  US5 100.97890 5.893336 

Sie können dann filtern, indem Sie Ihre my.isn oder time5 größer als benutzerdefinierte Zeiten?

+0

Danke theArun! Aber was bedeutet t1 in Deinem Beispiel? – Linas

+0

ah, sorry. Das ist 'time' – theArun

+0

Danke nochmal.Aber ich muss die Zeit mit einem "externen" Vektor vergleichen, der nicht in der Datentabelle ist (da ich so mit meinen Originaldaten arbeiten muss), d. H. Ohne den zweiten Schritt auszuführen (creating time5). So etwas (wir können isin einfachheitshalber entfernen): 'my.time <-format (seq.POSIXt (as.POSIXct (Sys.Date()), as.POSIXct (Sys.Date() + 1), von = "5 min"), "% H:% M:% S") ' und dann' dt [, liste (sprice = summe (preis), squant = summe (quant)), by = c ("mein. time "," price ")] [time> my.time]' Aber ich bekomme diesen Fehler erneut: 'Die Elemente in der 'by' oder 'keyby' Liste sind Länge (289,86401). Jeder muss die gleiche Länge haben ... ' – Linas