循环以在错误后继续处理

时间:2017-10-16 23:35:58

标签: r function loops

好吧,假设我有一个文件目录,我想在每个文件上运行相同的命令。例如,我的目录中有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上显示错误消息。

2 个答案:

答案 0 :(得分:2)

除了tryCatch之外,您应该考虑的一个选项是R中的4 10 0 10 包。我建议这样做的原因是因为我注意到您正在使用for循环来构建{{1} }。以这种方式构建对象不是一个好主意,因为它可以非常快地变得非常慢,因为R必须在每个循环中保持重新分配内存。很多人会建议使用其中一个foreach函数,或提前分配空矩阵,但我倾向于发现sma.matrix包更容易使用,并且还可以很好地处理错误问题:

apply

答案 1 :(得分:1)

您可以在R:

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