quantmod 在 getSymbols 中省略代码
quantmod omitting tickers in getSymbols
我是 R 的完全初学者。我想使用 getSymbols 下载有关标准普尔 500 中当前公司的历史数据几个时期。显然,一些公司在给定时期内不存在,R 停止下载下一个代码的数据。如果数据不存在,是否有任何方法可以让 getSymbols 简单地省略代码?获得那个时期的标准普尔 500 指数列表会容易得多,但不幸的是它不是免费的。
您可以像这样在 sapply
中使用 try
:
library(quantmod)
WoW <- new.env()
##
sapply(SiP, function(x){
try(
getSymbols(
x,
from=as.Date("2001-01-01"),
to=as.Date("2007-01-01"),
env=WoW),
silent=TRUE)
})
错误将打印到控制台(如果需要,您可能可以减轻这种情况),但不产生错误的代码仍会产生数据:
R> ls(WoW)
[1] "AA" "AEE" "AEP" "AES" "AP" "ARG" "ATI" "AVY" "BLL" "CF" "CMS" "CNP" "CTL" "D" "DOW" "DTE" "DUK" "ECL" "ED" "EIX"
[21] "EMN" "ETR" "EXC" "FCX" "FE" "FMC" "FTR" "GAS" "IFF" "IP" "LVLT" "MON" "MOS" "MWV" "NEE" "NEM" "NI" "NRG" "NU" "NUE"
[41] "OI" "PCG" "PEG" "PNW" "POM" "PPG" "PPL" "SCG" "SO" "SRE" "T" "TE" "TEG" "VZ" "WEC" "WIN" "XEL"
##
R> length(ls(WoW))
[1] 57
R> length(SiP)
[1] 59
看起来有 2 只股票有问题,因为 sapply(...)
成功返回了另外 57 只股票的数据。
从这里开始,可以通过您喜欢的方法在 WoW
内访问对象,例如
R> with(WoW, chartSeries(ARG))
数据:
SiP=c('AES','GAS','AEE','AEP','CNP', 'CMS','ED','D',
'DTE','DUK','EIX', 'ETR','EXC','FE','TEG',
'NEE','NI', 'NU','NRG','PCG','POM','PNW','PPL',
'PEG','SCG','SRE','SO','TE','WEC', 'XEL','T',
'CTL','FTR','LVLT','VZ', 'WIN','AP','ARG',
'AA','ATI','AVY', 'BLL','CF','DOW','D',
'EMN','ECL', 'FMC','FCX','IP','IFF','LYB',
'MWV', 'MON','MOS','NEM','NUE','OI','PPG')
问题是代码列表中的标点符号 stockSymbols()
生成,尽管来自雅虎,使用 getSymbols()
会产生 404,因为雅虎不使用 [=32= 中的那些标点符号]sgetSymbols()
尝试抓取。
示例:
stockSymbols()
检索符号 "AA-P",您尝试将其传递到 getSymbols()
并且您得到 404,因为 Yahoo!对于该股票,在 URL 中使用 "AA",而不是 "AA-P",尽管从 stockSymbols()
检索它的任何资源中将代码指定为 "AA-P"。
我编写了一些代码来清理 stockSymbols()
生成的代码列表,这样 getSymbols()
就不会生成错误。这会删除包含标点符号的首选和符号,因此结果来自普通股问题。
library(quantmod)
symbols = stockSymbols()
symbols = symbols[,1]
for (i in seq_along(symbols)) {
hyph = gregexpr(pattern = "-", symbols[i])
per = gregexpr(pattern = "[.]", symbols[i])
if (hyph[[1]][1] > 0 ) {
symbols[i] = substr(symbols[i], 1, hyph[[1]][1] - 1)
} else if (per[[1]][1] > 0 ) {
symbols[i] = substr(symbols[i], 1, per[[1]][1] - 1)
}
}
symbols = unique(symbols)
这里是一些使用 getSymbol() 获取所有股票数据并跳过 404s 的代码
for (i in seq_along(symbols)){
tryit <- try(getSymbols(symbols[i],from="2016-01-01", src='yahoo'))
if(inherits(tryit, "try-error")){
i <- i+1
}
else {
stock = getSymbols(symbols[i], from="2016-01-01", src = "yahoo", auto.assign = FALSE)
stocks[[i]] = as.data.frame(stock)
}
}
您可以尝试 tidyquant
包,它负责内部错误处理。它还不需要 for 循环或 tryCatch
语句,因此它将为您节省大量代码。 tq_get()
函数负责获取股票价格。您可以使用 complete_cases
参数来调整错误的处理方式。
complete_cases = TRUE
示例:自动删除 "bad apples"
library(tidyquant)
# get data with complete_cases = TRUE automatically removes bad apples
c("AAPL", "GOOG", "BAD APPLE", "NFLX") %>%
tq_get(get = "stock.prices", complete_cases = TRUE)
#> Warning in value[[3L]](cond): Error at BAD APPLE during call to get =
#> 'stock.prices'. Removing BAD APPLE.
#> # A tibble: 7,680 × 8
#> symbol date open high low close volume adjusted
#> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 AAPL 2007-01-03 86.29 86.58 81.90 83.80 309579900 10.85709
#> 2 AAPL 2007-01-04 84.05 85.95 83.82 85.66 211815100 11.09807
#> 3 AAPL 2007-01-05 85.77 86.20 84.40 85.05 208685400 11.01904
#> 4 AAPL 2007-01-08 85.96 86.53 85.28 85.47 199276700 11.07345
#> 5 AAPL 2007-01-09 86.45 92.98 85.15 92.57 837324600 11.99333
#> 6 AAPL 2007-01-10 94.75 97.80 93.45 97.00 738220000 12.56728
#> 7 AAPL 2007-01-11 95.94 96.78 95.10 95.80 360063200 12.41180
#> 8 AAPL 2007-01-12 94.59 95.06 93.23 94.62 328172600 12.25892
#> 9 AAPL 2007-01-16 95.68 97.25 95.45 97.10 311019100 12.58023
#> 10 AAPL 2007-01-17 97.56 97.60 94.82 94.95 411565000 12.30168
#> # ... with 7,670 more rows
带有 complete_cases = FALSE
的示例:Returns 嵌套数据框。
library(tidyquant)
# get data with complete_cases = FALSE returns a nested data frame
c("AAPL", "GOOG", "BAD APPLE", "NFLX") %>%
tq_get(get = "stock.prices", complete_cases = FALSE)
#> Warning in value[[3L]](cond): Error at BAD APPLE during call to get =
#> 'stock.prices'.
#> Warning in value[[3L]](cond): Returning as nested data frame.
#> # A tibble: 4 × 2
#> symbol stock.prices
#> <chr> <list>
#> 1 AAPL <tibble [2,560 × 7]>
#> 2 GOOG <tibble [2,560 × 7]>
#> 3 BAD APPLE <lgl [1]>
#> 4 NFLX <tibble [2,560 × 7]>
在这两种情况下,用户都会收到警告消息。谨慎的用户会阅读它们并尝试确定问题所在。最重要的是,长 运行 脚本不会失败。
我是 R 的完全初学者。我想使用 getSymbols 下载有关标准普尔 500 中当前公司的历史数据几个时期。显然,一些公司在给定时期内不存在,R 停止下载下一个代码的数据。如果数据不存在,是否有任何方法可以让 getSymbols 简单地省略代码?获得那个时期的标准普尔 500 指数列表会容易得多,但不幸的是它不是免费的。
您可以像这样在 sapply
中使用 try
:
library(quantmod)
WoW <- new.env()
##
sapply(SiP, function(x){
try(
getSymbols(
x,
from=as.Date("2001-01-01"),
to=as.Date("2007-01-01"),
env=WoW),
silent=TRUE)
})
错误将打印到控制台(如果需要,您可能可以减轻这种情况),但不产生错误的代码仍会产生数据:
R> ls(WoW)
[1] "AA" "AEE" "AEP" "AES" "AP" "ARG" "ATI" "AVY" "BLL" "CF" "CMS" "CNP" "CTL" "D" "DOW" "DTE" "DUK" "ECL" "ED" "EIX"
[21] "EMN" "ETR" "EXC" "FCX" "FE" "FMC" "FTR" "GAS" "IFF" "IP" "LVLT" "MON" "MOS" "MWV" "NEE" "NEM" "NI" "NRG" "NU" "NUE"
[41] "OI" "PCG" "PEG" "PNW" "POM" "PPG" "PPL" "SCG" "SO" "SRE" "T" "TE" "TEG" "VZ" "WEC" "WIN" "XEL"
##
R> length(ls(WoW))
[1] 57
R> length(SiP)
[1] 59
看起来有 2 只股票有问题,因为 sapply(...)
成功返回了另外 57 只股票的数据。
从这里开始,可以通过您喜欢的方法在 WoW
内访问对象,例如
R> with(WoW, chartSeries(ARG))
数据:
SiP=c('AES','GAS','AEE','AEP','CNP', 'CMS','ED','D',
'DTE','DUK','EIX', 'ETR','EXC','FE','TEG',
'NEE','NI', 'NU','NRG','PCG','POM','PNW','PPL',
'PEG','SCG','SRE','SO','TE','WEC', 'XEL','T',
'CTL','FTR','LVLT','VZ', 'WIN','AP','ARG',
'AA','ATI','AVY', 'BLL','CF','DOW','D',
'EMN','ECL', 'FMC','FCX','IP','IFF','LYB',
'MWV', 'MON','MOS','NEM','NUE','OI','PPG')
问题是代码列表中的标点符号 stockSymbols()
生成,尽管来自雅虎,使用 getSymbols()
会产生 404,因为雅虎不使用 [=32= 中的那些标点符号]sgetSymbols()
尝试抓取。
示例:
stockSymbols()
检索符号 "AA-P",您尝试将其传递到 getSymbols()
并且您得到 404,因为 Yahoo!对于该股票,在 URL 中使用 "AA",而不是 "AA-P",尽管从 stockSymbols()
检索它的任何资源中将代码指定为 "AA-P"。
我编写了一些代码来清理 stockSymbols()
生成的代码列表,这样 getSymbols()
就不会生成错误。这会删除包含标点符号的首选和符号,因此结果来自普通股问题。
library(quantmod)
symbols = stockSymbols()
symbols = symbols[,1]
for (i in seq_along(symbols)) {
hyph = gregexpr(pattern = "-", symbols[i])
per = gregexpr(pattern = "[.]", symbols[i])
if (hyph[[1]][1] > 0 ) {
symbols[i] = substr(symbols[i], 1, hyph[[1]][1] - 1)
} else if (per[[1]][1] > 0 ) {
symbols[i] = substr(symbols[i], 1, per[[1]][1] - 1)
}
}
symbols = unique(symbols)
这里是一些使用 getSymbol() 获取所有股票数据并跳过 404s 的代码
for (i in seq_along(symbols)){
tryit <- try(getSymbols(symbols[i],from="2016-01-01", src='yahoo'))
if(inherits(tryit, "try-error")){
i <- i+1
}
else {
stock = getSymbols(symbols[i], from="2016-01-01", src = "yahoo", auto.assign = FALSE)
stocks[[i]] = as.data.frame(stock)
}
}
您可以尝试 tidyquant
包,它负责内部错误处理。它还不需要 for 循环或 tryCatch
语句,因此它将为您节省大量代码。 tq_get()
函数负责获取股票价格。您可以使用 complete_cases
参数来调整错误的处理方式。
complete_cases = TRUE
示例:自动删除 "bad apples"
library(tidyquant)
# get data with complete_cases = TRUE automatically removes bad apples
c("AAPL", "GOOG", "BAD APPLE", "NFLX") %>%
tq_get(get = "stock.prices", complete_cases = TRUE)
#> Warning in value[[3L]](cond): Error at BAD APPLE during call to get =
#> 'stock.prices'. Removing BAD APPLE.
#> # A tibble: 7,680 × 8
#> symbol date open high low close volume adjusted
#> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 AAPL 2007-01-03 86.29 86.58 81.90 83.80 309579900 10.85709
#> 2 AAPL 2007-01-04 84.05 85.95 83.82 85.66 211815100 11.09807
#> 3 AAPL 2007-01-05 85.77 86.20 84.40 85.05 208685400 11.01904
#> 4 AAPL 2007-01-08 85.96 86.53 85.28 85.47 199276700 11.07345
#> 5 AAPL 2007-01-09 86.45 92.98 85.15 92.57 837324600 11.99333
#> 6 AAPL 2007-01-10 94.75 97.80 93.45 97.00 738220000 12.56728
#> 7 AAPL 2007-01-11 95.94 96.78 95.10 95.80 360063200 12.41180
#> 8 AAPL 2007-01-12 94.59 95.06 93.23 94.62 328172600 12.25892
#> 9 AAPL 2007-01-16 95.68 97.25 95.45 97.10 311019100 12.58023
#> 10 AAPL 2007-01-17 97.56 97.60 94.82 94.95 411565000 12.30168
#> # ... with 7,670 more rows
带有 complete_cases = FALSE
的示例:Returns 嵌套数据框。
library(tidyquant)
# get data with complete_cases = FALSE returns a nested data frame
c("AAPL", "GOOG", "BAD APPLE", "NFLX") %>%
tq_get(get = "stock.prices", complete_cases = FALSE)
#> Warning in value[[3L]](cond): Error at BAD APPLE during call to get =
#> 'stock.prices'.
#> Warning in value[[3L]](cond): Returning as nested data frame.
#> # A tibble: 4 × 2
#> symbol stock.prices
#> <chr> <list>
#> 1 AAPL <tibble [2,560 × 7]>
#> 2 GOOG <tibble [2,560 × 7]>
#> 3 BAD APPLE <lgl [1]>
#> 4 NFLX <tibble [2,560 × 7]>
在这两种情况下,用户都会收到警告消息。谨慎的用户会阅读它们并尝试确定问题所在。最重要的是,长 运行 脚本不会失败。