2017-10-16 16 views
1

私はファイルのディレクトリを持っていて、それぞれのファイルに対して同じコマンドを実行したいとします。エラーが発生しても処理を続けるループ

# 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]をので、今、私たちは、私は私が望む各ファイルを通って、上の反復したい時にデータを持っている:例えばものの、ここで以下のように私のディレクトリ内の10個のファイルは、データフレームのリストとして表現されますがあります2〜12単純移動平均を計算します。

まず、file.list [[i]](またはデータフレーム1)から始まる関数で単純移動平均プロシージャをラップします。私の実際の問題では、これらは私のディレクトリ上のファイルですが、例えば同じことです。

# 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) 

    } 

は今、私はすべてのデータフレーム上でこの機能を実行するために、forループを呼び出します。

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

[OK]を、これは、それが失敗するためにセットアップされます。これは、データフレーム8に失敗しても、このエラーメッセージを印刷する必要があります:SMA 9,10,11,12の単純移動平均を計算するための十分なデータがないため

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

です。それらを計算するには、9,10,11,12データポイントより長いデータが必要です。

私の質問は:

私は残りのファイルをループし続けると、エラーメッセージを無視します。このコードで何かを追加するにはどうすればよいですか?

出力を1つのデータフレームに保存する方法もわかりません。これはちょうど実行され、出力をどこにも格納しないことに気づくでしょう。最終結果をデータフレームに格納することも良いでしょう。

しかしながら、上記のコードを実行して、RでtryCatchブロックを使用することができ8

答えて

1

ファイルにエラーメッセージを表示する例示の目的のためにない:

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

[OK]を反復が失敗した場合、どの反復が失敗したかを教えてくれます。残りのファイルもループし続けますか? –

+0

はい、どうしてテストしないのですか? –

+0

はい答えです - 上記の例では、プロセスが完了した後に表示するために出力をデータフレームに保存する手順はありますか? –

2

、一つの選択肢Rのforeachパッケージを検討する必要があります。これは私があなたのsma.matrixをビルドするためにあなたのforループを使用していることに気付いたためです。これは、Rが各ループでメモリを再割り当てし続ける必要があるため、非常に遅くなる可能性があるため、この方法でオブジェクトを作成することはお勧めできません。多くの人々は、このためにapply関数のいずれかを使用して、または事前に空行列を割り当てることをお勧めしますが、私は使いforeachパッケージをより簡単に見つけることが多いとも非常にうまくエラーの問題を処理します。その

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 - コメントありがとう。これは、ループがSMAにスピードアップさせるためのものですか?私はすべてのファイル+コマンドの他の束のSMA手順を行う、これは私のコードの残りの部分と統合することができますか? –

+0

Foreachを使用してforループを置き換えることができます。私はあなたが(1)ループを並列化したいいずれかのときに最も有用見つける、または(2)対象/行列/テーブル –

+0

グレートを構築するためにループを使用して - 私は、パッケージをチェックアウトします! :) –

関連する問題