You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

股票代码分析脚本循环执行报错及无数据写入问题排查

问题描述

脚本目标是从维基百科获取标普500成分股基础信息,通过getSymbols提取历史价格数据,计算对数收益率(log.return),汇总均值、标准差及数据量后写入output表。单只股票代码单独执行正常,但使用for循环或analyze_stocks函数时,output表要么报错要么无数据写入。

报错信息

Error in `filter()`:
ℹ In argument: `sp_500$Symbol == stocks(i)`.
Caused by error in `stocks()`:
! could not find function "stocks"

原脚本代码

library(quantmod)   
library(xts)        
library(rvest)      
library(tidyverse)  
library(stringr)    
library(forcats)    
library(lubridate) 

# 从维基百科获取标普500数据
sp_500 <- read_html("https://en.wikipedia.org/wiki/List_of_S%26P_500_companies") %>%
  html_node("table.wikitable") %>%
  html_table() %>%
  select(`Symbol`, Security, `GICS Sector`, `GICS Sub-Industry`) %>%
  as_tibble()

# 创建空结果表
tbl_colnames <- c("ticker.symbol","security","gics.sector",
                  "gics.sub.industry", "mean_return", "sd_return", "days")
output <- tibble::tibble(!!!tbl_colnames, .rows = 0, .name_repair = ~ tbl_colnames)

# 样本股票代码列表
symbol_list = c("TSLA", "AKAM","ACN")

# 股票分析函数
analyze_stocks = function(stocks){
  for (i in stocks){ 
    stock_prices_xts <- getSymbols(i, auto.assign = FALSE)
    names(stock_prices_xts) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
    stock_prices <- stock_prices_xts %>%
      as_tibble() %>%
      rownames_to_column(var = "Date") %>%
      mutate(Date = index(stock_prices_xts))
    
    if (!is.xts(stock_prices)) {
      x <- xts(stock_prices[,-1], order.by = stock_prices$Date)
    }
    log_returns_xts <- periodReturn(x$Adjusted, type = 'log', period = 'daily')
    names(log_returns_xts) <- "Log.Returns"
    log_returns <- log_returns_xts %>%
      as_tibble() %>%
      rownames_to_column(var = "Date") %>%
      mutate(Date = index(log_returns_xts))
    
    stock_prices_xts = merge.xts(stock_prices_xts, log_returns_xts)
    
    output = rbind(output, sp_500 %>% as_tibble() %>%
                     filter(sp_500$Symbol == stocks(i)) %>% 
                     mutate(mean_return = mean(log_returns_xts), sd_return = sd(log_returns_xts), days = nrow(log_returns_xts)))
  }
  return(output)
}
analyze_stocks(symbol_list)

问题分析与修复

1. 核心报错原因

stocks(i)是错误写法:stocks是函数的参数名,并非可调用函数,当前循环中代表单只股票代码的变量是i,直接替换即可。

2. 其他潜在问题及修复

  • 变量作用域冲突:原代码依赖全局output变量,函数内赋值易引发作用域问题,建议在函数内初始化空表。
  • 冗余类型转换:sp_500已是tibble,无需重复转换;stock_prices转xts的逻辑完全冗余,直接使用原始stock_prices_xts即可。
  • 列名不匹配:原output列名与sp_500列名未对齐,需重命名统一。
  • 缺失值处理:计算统计量时未处理缺失值,可能导致结果为NA。

修复后的完整代码

library(quantmod)   
library(xts)        
library(rvest)      
library(tidyverse)  
library(stringr)    
library(forcats)    
library(lubridate) 

# 从维基百科获取标普500成分股数据
sp_500 <- read_html("https://en.wikipedia.org/wiki/List_of_S%26P_500_companies") %>%
  html_node("table.wikitable") %>%
  html_table() %>%
  select(Symbol, Security, `GICS Sector`, `GICS Sub-Industry`) %>%
  as_tibble()

# 样本股票代码列表
symbol_list <- c("TSLA", "AKAM","ACN")

# 股票分析函数
analyze_stocks <- function(stocks){
  # 初始化空结果表,列名与目标输出对齐
  output <- tibble(
    ticker.symbol = character(),
    security = character(),
    gics.sector = character(),
    gics.sub.industry = character(),
    mean_return = numeric(),
    sd_return = numeric(),
    days = integer()
  )
  
  for (i in stocks){ 
    # 获取股票价格数据
    stock_prices_xts <- getSymbols(i, auto.assign = FALSE)
    names(stock_prices_xts) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
    
    # 计算对数收益率
    log_returns_xts <- periodReturn(stock_prices_xts$Adjusted, type = 'log', period = 'daily')
    
    # 提取当前股票基础信息并合并统计数据
    stock_info <- sp_500 %>%
      filter(Symbol == i) %>%
      rename(
        ticker.symbol = Symbol,
        security = Security,
        gics.sector = `GICS Sector`,
        gics.sub.industry = `GICS Sub-Industry`
      ) %>%
      mutate(
        mean_return = mean(log_returns_xts, na.rm = TRUE),
        sd_return = sd(log_returns_xts, na.rm = TRUE),
        days = nrow(log_returns_xts)
      )
    
    # 合并到结果表
    output <- bind_rows(output, stock_info)
  }
  return(output)
}

# 执行函数并查看结果
result <- analyze_stocks(symbol_list)
print(result)

关键修复点说明

  • 将filter(sp_500$Symbol == stocks(i))改为filter(Symbol == i),简化dplyr管道内的列引用。
  • 函数内独立初始化output,避免全局变量依赖。
  • 直接使用stock_prices_xts$Adjusted计算收益率,省去不必要的类型转换。
  • 用bind_rows替代rbind,更适配tibble的合并逻辑。
  • 添加na.rm = TRUE处理缺失值,保证统计量计算有效。

内容的提问来源于stack exchange,提问作者Tbiz Adeniyi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:55:03