2017-10-16 5 views
1

Ok lässt sagen, ich habe ein Verzeichnis von Dateien und ich möchte die gleichen Befehle über jede Datei ausführen. Es gibt zum Beispiel 10 Dateien in meinem Verzeichnis wie unten, obwohl hier wird ausdrücken als eine Liste von Datenrahmen:Schleife, um nach Fehler weiter zu verarbeiten

# Create dummy files 
    file1 <- as.data.frame(runif(100, 0,100)) 
    file2 <- as.data.frame(runif(100, 0,100)) 
    file3 <- as.data.frame(runif(100, 0,100)) 
    file4 <- as.data.frame(runif(12, 0,100)) 
    file5 <- as.data.frame(runif(100, 0,100)) 
    file6 <- as.data.frame(runif(15, 0,100)) 
    file7 <- as.data.frame(runif(100, 0,100)) 
    file8 <- as.data.frame(runif(8, 0,100)) # This is the df that its intended to fail on 
    file9 <- as.data.frame(runif(100, 0,100)) 
    file10 <- as.data.frame(runif(100, 0,100)) 
    file11 <- as.data.frame(runif(100, 0,100)) 

    # Lets pretend the files are .csv files on my HDD 
    # But here will make a list of data frames 
    file.list <- list(file1,file2,file3,file4,file5,file6,file7,file8,file9,file10) 

# Rename column names for all 10 df 
Names <- function(x) { 
    names(x) <- c("Close") 
    return(x) 
} 
# Apply name change to all 10 data frames 
file.list <- lapply(file.list, Names) 

Ok, so jetzt haben wir die Daten, an die ich mag durchlaufen und für jede Datei Ich wünsche um 2 bis 12 einfachen gleitenden Durchschnitt zu berechnen.

Zuerst wird die einfache gleitende Durchschnittsprozedur in eine Funktion ausgehend von file.list [[i]] (oder Datenrahmen 1) eingefügt. In meinem wirklichen Problem sind das Dateien in meinem Verzeichnis, aber zum Beispiel ist es dasselbe!

# Create function for performing commands. 
    genSMA = function(x){ 
     nextfile <- data.frame(file.list[[i]],stringsAsFactors=FALSE) 
     new.df <- data.frame(nextfile) 
     # Load packages 
     require(TTR) 
     # Use TTR package to create rolling SMA n day moving average 
     getSMA <- function(numdays) { 
     function(new.df) { 
      SMA(new.df[,"Close"], numdays) # Calls TTR package to create SMA 
     } 
     } 
     # Create a matrix to put the SMAs in 
     sma.matrix <- matrix(nrow=nrow(new.df), ncol=0) 
     tail(sma.matrix) 
     # Loop for filling it 
     for (i in 2:12) { 
     sma.matrix <- cbind(sma.matrix, getSMA(i)(new.df)) 
     } 

     # Rename columns 
     colnames(sma.matrix) <- sapply(2:12, function(n)paste("close.sma.n", n, sep="")) 

     # Bind to existing dataframe 
     new.df <- cbind(new.df, sma.matrix) 

    } 

Nun rufe ich die for-Schleife diese Funktion über alle Datenrahmen auszuführen:

for (i in 1:length(file.list)){ 
    genSMA(file.list[[i]]) 
} 

Ok diese Einrichtung ist, um es zum Scheitern verurteilt. Es sollte auf Datenrahmen 8 fehlschlagen und diese Fehlermeldung auch drucken:

Error in runSum(x, n) : n = 9 is outside valid range: [1, 8] 

Dies ist, weil es nicht genügend Daten, um die einfache gleitende Durchschnitte von SMA 9,10,11,12 zu berechnen. Um diese zu berechnen, benötigen wir Daten länger als 9,10,11,12 Datenpunkte.

Meine Frage ist:

Wie kann ich etwas in diesem Code hinzufügen, die Schleife durch den Rest der Dateien und ignorieren Sie die Fehlermeldung weiterhin?

Ich weiß auch nicht, wie Sie die Ausgabe in einem Datenrahmen speichern? Sie werden bemerken, dass dies nur ausgeführt wird und die Ausgabe nicht irgendwo speichert, da ich nicht ganz sicher bin, wie ich das programmieren soll. Es wäre gut, das Endergebnis auch im Datenrahmen zu speichern.

jedoch oberhalb der Code nicht ausgeführt werden und zur Veranschaulichung zeigen die Fehlermeldung auf Datei 8.

Antwort

1

Sie tryCatch Blöcke in R verwenden können:

for (i in 1:length(file.list)){ 
    tryCatch({ 
     genSMA(file.list[[i]]) 
    }, error = function(e) { print(paste("i =", i, "failed:")) }) 
} 
+0

Ok, dass sagt mir, welche Iteration fehlgeschlagen ist, wird sie bei einem Fehler auch den Rest der Dateien durchlaufen? –

+0

Ja, warum testeest du es nicht? –

+0

Ja ist die Antwort - Gibt es im obigen Beispiel eine Prozedur zum Speichern der Ausgabe in einem Datenrahmen zum Anzeigen, nachdem der Prozess abgeschlossen wurde? –

2

Neben TryCatch, ist eine Option Sie sollten in Betracht ziehen, ist das foreach Paket in R. Der Grund, den ich vorschlagen, ist, weil ich bemerke, dass Sie Ihre for-Schleife verwenden, um Ihre sma.matrix zu bauen. Es ist keine gute Idee, ein Objekt auf diese Weise zu erstellen, da es sehr schnell sehr langsam werden kann, da R Speicher bei jeder Schleife neu zuweisen muss. Viele Menschen würden vorschlagen, für das eines der apply Funktionen verwenden oder Ihre leere Matrix im Voraus Zuteilung, aber ich neige das foreach Paket leichter zu finden und zu verwenden, übernehmen auch das Problem der Fehler ganz gut:

library(foreach) 

sma.matrix <- foreach(
    i = 1:12,  # This is your for loop iterator 
    .combine=cbind, # Specify how to combine the results of each loop 
    .errorhandling="remove" # When error occurs, skip to next iteration 
) %do% { # You can use %dopar% for parallel loop execution 
    getSMA(i)(new.df) 
} 
+0

Scott - danke für die Kommentare. Dies ist speziell für die Schleife, um die SMA's zu beschleunigen? Ich mache das SMA-Verfahren für jede Datei + eine ganze Reihe von Befehlen, das kann mit dem Rest meines Codes integriert werden? –

+0

Foreach kann verwendet werden, um eine beliebige for-Schleife zu ersetzen.Ich finde es am nützlichsten, wenn Sie entweder (1) die Schleife parallelisieren wollen, oder (2) eine Schleife verwenden, um ein Objekt/Matrix/Tabelle zu erstellen –

+0

Großartig - ich werde das Paket auschecken! :) –

Verwandte Themen