R语言while循环支持多ticker输入并实现本地与Yahoo校验的代码修正问题
R语言多股票代码批量校验下载实现
基础方案参考
单股票代码校验下载实现
原有可正常运行的单股票代码输入逻辑,会先后校验本地是否已加载、Yahoo平台是否有对应数据,校验通过后才下载数据:
# 加载依赖包 library(svDialogs) library(quantmod) # 开启循环,符合退出条件后自动终止 while (TRUE) { # 获取用户输入的股票代码 ticker <- toupper(dlgInput("请输入尚未加载的股票代码:")$res) # 代码已在全局环境存在则重新要求输入 if (exists(ticker)) next # 校验Yahoo平台是否有对应数据,校验通过则下载 yahooSymbol <- getSymbols.yahoo(ticker, env = globalenv()) # Yahoo返回有效数据则退出循环 if (!identical(yahooSymbol, character(0))) break }
该方案仅支持单个股票代码输入,用户输入多个代码时运行失败。
独立多股票代码下载实现
脱离循环校验的多代码处理逻辑可正常运行:
# 加载依赖包 library(svDialogs) library(quantmod) library(stringr) # 获取用户输入的多个股票代码 ticker <- toupper(dlgInput("请输入一个或多个股票代码,用逗号分隔:")$res) # 拆分处理输入的代码 tickers <- unlist(strsplit(gsub(" ", "", ticker, fixed = TRUE), ",")) # 从Yahoo下载数据 yahooSymbol <- getSymbols.yahoo(tickers, env = globalenv()) # 关闭所有网络连接作为防护 closeAllConnections()
该方案缺少本地加载校验、无效代码重输的循环逻辑。
整合时的报错问题
将多代码逻辑整合进循环时的代码如下:
# 加载依赖包 library(svDialogs) library(quantmod) library(stringr) while (TRUE) { # 获取用户输入的多个股票代码 ticker <- toupper(str_trim(dlgInput("请输入一个或多个未加载的股票代码,用逗号分隔:")$res)) # 拆分处理输入的代码 tickers <- unlist(strsplit(gsub(" ", "", ticker, fixed = TRUE), ",")) # 校验本地是否已加载 if (exists(tickers)) next # 从Yahoo下载数据 yahooSymbol <- getSymbols.yahoo(tickers, env = globalenv()) # Yahoo返回有效数据则退出循环 if (!identical(yahooSymbol, character(0))) break }
运行时报错:Error in exists(tickers) : first argument has length > 1,原因是exists()仅支持传入单个字符参数,无法直接处理长度大于1的代码向量。注释该校验语句后可正常下载数据,但缺失本地已加载校验逻辑。
修正后完整代码
满足以下要求:1. 所有输入的股票代码均未在本地环境加载才进入下一步;2. 所有代码在Yahoo端均有效时完成数据下载,否则重新要求用户输入:
# 加载依赖包 library(svDialogs) library(quantmod) library(stringr) while (TRUE) { # 获取用户输入的多个股票代码,逗号分隔 ticker_input <- toupper(str_trim(dlgInput("请输入一个或多个未加载的股票代码,用逗号分隔:")$res)) # 处理输入,去除空格、拆分代码 tickers <- unlist(strsplit(gsub(" ", "", ticker_input, fixed = TRUE), ",")) # 过滤空输入 tickers <- tickers[tickers != ""] if (length(tickers) == 0) next # 校验所有代码均未在本地加载 if (any(sapply(tickers, exists, envir = globalenv()))) next # 从Yahoo下载数据 yahooSymbol <- getSymbols.yahoo(tickers, env = globalenv()) # 校验所有代码均有效,全部下载成功则退出循环 if (length(yahooSymbol) == length(tickers)) break } # 关闭所有网络连接 closeAllConnections()
修正逻辑说明
- 本地存在校验:通过
sapply()遍历所有输入代码,逐一判断是否已加载,只要有一个代码已存在就触发重新输入 - 有效性校验:比对Yahoo返回的有效代码数量和输入的代码数量,只有全部代码有效时才退出循环
- 新增空输入过滤逻辑,避免用户无输入时程序报错
- 兼容原有空格处理逻辑,允许用户输入时带空格
兼容环境
- R版本:4.1.1 (2021-08-10)
- RStudio版本:1.4.1717
- 操作系统:macOS Catalina 10.15.7、macOS Big Sur 11.6
内容的提问来源于stack exchange,提问作者pdeli
相关产品推荐
相关产品推荐

