繁体   English   中英

循环以在错误后继续处理

[英]Loop to continue to process after error

好吧,假设我有一个文件目录,我想在每个文件上运行相同的命令。 我的目录中有10个文件,如下所示,尽管这里将表示为数据框列表:

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

好的,现在我们有数据,我想迭代并在每个文件上我希望计算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]])
}

好的,这是为了让它失败而设置的。 它应该在数据帧8上失败并且还打印此错误消息:

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

这是因为没有足够的数据来计算SMA 9,10,11,12的简单移动平均值。 要计算那些我们需要的数据超过9,10,11,12个数据点。

我的问题是:

如何在此代码中添加一些将继续循环其余文件并忽略错误消息的内容?

我也不知道如何将输出保存到一个数据帧? 您会注意到这只会运行而不是将输出存储在任何地方,因为我不太确定如何编码。 将最终结果也存储在数据框中也是一件好事。

但是,上面的代码确实运行,并且为了说明的目的,在文件8上显示错误消息。

除了tryCatch之外,你应该考虑的一个选项是R中的foreach包。我建议这样做的原因是因为我注意到你正在使用你的for循环来构建你的sma.matrix 以这种方式构建对象不是一个好主意,因为它可以非常快地变得非常慢,因为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)
}

您可以在R中使用tryCatch块:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM