【问题标题】:How to Error Handle within a For-Loop that retrieves Yahoo Finance data from a list of ticker symbols如何在从股票代码列表中检索 Yahoo Finance 数据的 For 循环中进行错误处理
【发布时间】:2013-07-13 19:09:04
【问题描述】:

所以我编写了一些代码,使用一维数组中包含的 Ticker 符号“列表”从 yahoo Finance 中提取 csv 文件。我面临的挑战是其中一个股票代码可能没有任何数据(或者可能输入错误)。所以我构建了一个 tryCatch 命令,但它运行得不是很好。下面是我的代码(我使用 source("Name of the code") 访问它,然后是它生成的错误:

#URL Builder for Yahoo Finance
 #Requests Input from User, Builds URL, downloads csv.file from site
 #Requests are for:
      #Ticker (2-4 letter - character string)
      #Start Month (00 - 11 integer)
      #Start Day (1 - 31 integer)
      #Start Year (Four digit integer)
      #End Month (00 - 11 integer)
      #End Day (1 - 31 integer)
      #End Year (Four digit integer)

      #Retrieve Ticker File
       setwd(personal_directory)
      #tickers            <- read.csv("Tickers.csv")

      #Here are some example tickers, since you will not have the Ticker.csv file (the S ticker generates the error to be handled
       tickers            <- data.frame(Ticker = c("XOM", "DVN", "S")) 
       tickers            <- tickers[order(tickers[,1]),]
       setwd("Ticker Data")

      #Functions
       Get_Month_Begin    <- function(){as.numeric(readline("Enter the start month 00 - 11(MM):>>> "))}
       Get_Day_Begin      <- function(){as.numeric(readline("Enter the start day (1-31) :>>> "))}
       Get_Year_Begin     <- function(){as.numeric(readline("Enter the start year (YYYY) :>>> "))}
       Get_Month_End      <- function(){as.numeric(readline("Enter the end month (MM) :>>> "))}
       Get_Day_End        <- function(){as.numeric(readline("Enter the end day (1-31) :>>> "))}
       Get_Year_End       <- function(){as.numeric(readline("Enter the end year :>>> "))}

      #Function Calls
       Month_Begin        <- Get_Month_Begin()
       Day_Begin          <- Get_Day_Begin()
       Year_Begin         <- Get_Year_Begin()
       Month_End          <- Get_Month_End()
       Day_End            <- Get_Day_End()
       Year_End           <- Get_Year_End()

      #Build URL
      #Example URL: http://ichart.finance.yahoo.com/table.csvs=DVN&a=00&b=1&c=1992&d=11&e=31&f=2013&g=d&ignore=.csv
       CSV_Base_URL       <- "http://ichart.finance.yahoo.com/table.csv?s="
       yahoo_data_date_format <- "%Y-%m-%d"

       for(i in 1:nrow(tickers)){
           Ticker             <- tickers[i, 1]
           CSV_URL_Complete   <- paste(CSV_Base_URL,Ticker,"&a=",Month_Begin,"&b=",Day_Begin,"&c=",Year_Begin,"&d=",Month_End,"&e=",Day_End,"&f=",Year_End,"&g=d&ignore=.csv",sep="")

            #Download CSV
             options(warn=2)
             potential_error   <- tryCatch(Yahoo_Finance_TBL <- read.csv(CSV_URL_Complete), error = function(e) e)

            if(!inherits(potential_error, "error")){
                Yahoo_Finance_TBL              <- Yahoo_Finance_TBL[,c(1,7)]
                colnames(Yahoo_Finance_TBL)    <- gsub(" ", ".", colnames(Yahoo_Finance_TBL))
                Yahoo_Finance_TBL[, 1]         <- as.Date(Yahoo_Finance_TBL[, 1], yahoo_data_date_format)

                #Write CSV File
                 write.csv(Yahoo_Finance_TBL, file=paste(Ticker,"_Yahoo_Finance_File.csv", sep=""), row.names=FALSE)
             }
       }

此代码生成以下错误:

Error in if (file == "") file <- stdin() else { : 
 missing value where TRUE/FALSE needed

我知道这是 if 条件中的一个问题,我想知道是否需要在某处放置“==TRUE”语句。

感谢您的帮助!

注意: 我已经在没有 for 循环的情况下运行了代码,只需设置 Ticker

options(warn = 2)

这会使所有警告出错,但仍然没有乐趣。

【问题讨论】:

  • 不是提供需要用户输入值的函数,而是为我们硬编码这些值,以便我们都可以重现相同的东西。例如而不是Month_Begin &lt;- Get_Month_Begin(),只是为了示例的缘故向我们展示Month_Begin &lt;- 1。此外,我们无法重现 setwd(personal_directory)setwd("Ticker Data") 之类的内容。
  • 如果您还没有听说过quantmod 包:它有一个函数getSymbols,可以处理从雅虎和其他来源下载的数据。顺便说一句:另一个提供数据和R 接口的有趣网站是quandl.com(最近才发现并有时间测试它)。
  • 谢谢!我真的很感激。

标签: r for-loop error-handling


【解决方案1】:

您显示的错误可能来自write.csv 调用的write.table。该错误告诉您缺少file (NA)。但是,我遇到了其他错误,其中一个是 Error in 1:nrow(tickers) : argument of length 0,我将在下面详细解释。

我会将代码存储为字符向量,而不是将它们存储在 data.frame 中,但如果您要将它们存储在 data.frame 中,则必须注意两件事:stringsAsFactorsdrop

tickers &lt;- data.frame(Ticker = c("XOM", "DVN", "S")) 将您的代码存储为因子

> str(tickers)
'data.frame':   3 obs. of  1 variable:
 $ Ticker: Factor w/ 3 levels "DVN","S","XOM": 3 1 2

tickers &lt;- tickers[order(tickers[,1]),]data.frame 替换为Factor 向量,因为默认情况下drop=TRUE[.data.frame 中。

> tickers[order(tickers[,1]),]
[1] DVN S   XOM
Levels: DVN S XOM

但是,稍后您将其视为仍然是 1 列 data.framenrow(tickers) 为 NULL,tickers[1, 1] 为错误。

您可以更改向量子集的代码,或使用drop=FALSE 将其保留为data.frame

> tickers[order(tickers[,1]),,drop=FALSE]
  Ticker
2    DVN
3      S
1    XOM

如果您要为此使用data.frame,我建议您使用stringsAsFactors=FALSE,这样您的代码将存储为character

> tickers <- data.frame(Ticker = c("XOM", "DVN", "S"), stringsAsFactors=FALSE)
> str(tickers)
'data.frame':   3 obs. of  1 variable:
 $ Ticker: chr  "XOM" "DVN" "S"

最后,你应该使用seq_len(tickers),而不是1:nrow(tickers)。否则,如果 `nrow(tickers) 为 0,你会得到意想不到的结果

>for(i in 1:0) print(i)
[1] 1
[1] 0

【讨论】:

  • 感谢您提供的所有有用建议。关于您对我的错误处理程序的建议只有一个问题;我使用的是 tryCatch 而不是 try。然后我应该仍然使用“try-error”还是应该在使用 tryCatch 时坚持使用“error”?
  • 您的帮助 = 太棒了!非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 2011-01-17
  • 2015-12-30
  • 1970-01-01
相关资源
最近更新 更多