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

在R语言中绘制双时间序列图时遇到问题求助

解决双时间序列同图对比问题

你的代码核心问题

  1. 变量覆盖错误:计算完portfolioReturns <- ROC(...)后,立刻用portfolioReturns <- as.timeSeries(portfolioPrices)覆盖了收益数据,实际用的是原始价格而非收益,这是关键错误。
  2. 语法错误:最后一行axis语句缺少闭合括号,导致代码无法正常运行。
  3. 数值尺度不匹配:TSN股价和标普500指数数值差距极大,直接叠加会导致其中一个序列被压缩到几乎看不见,需要用双Y轴或归一化处理。

修正方案1:基础绘图(双Y轴)

先修正变量逻辑,再实现双Y轴对比:

# 加载包
lapply(c("quantmod", "timeSeries"), require, character.only = TRUE)

tickers <- c("TSN", "^GSPC")
start_date <- "2022-02-20"

# 下载数据并合并
portfolioPrices <- NULL
for (Ticker in tickers) {
  portfolioPrices <- cbind(portfolioPrices,
                           getSymbols(Ticker, from = start_date, src = "yahoo", auto.assign=FALSE)[,4])
}
# 去除含NA的行
portfolioPrices <- portfolioPrices[apply(portfolioPrices,1,function(x) all(!is.na(x))),]
colnames(portfolioPrices) <- tickers

# 计算离散收益(可选,如果你要对比收益;如果对比价格就用portfolioPrices)
portfolioReturns <- ROC(portfolioPrices, type = "discrete")
# 转换为timeSeries
portfolioReturns <- as.timeSeries(portfolioReturns)

# 双Y轴绘图
# 先画第一个序列(TSN)
plot(portfolioReturns$TSN, col = "blue", ylab = "TSN 收益率", main = "TSN vs 标普500 收益率对比")
# 允许在同图绘制第二个序列
par(new = TRUE)
# 画第二个序列,隐藏原有轴标签
plot(portfolioReturns$`^GSPC`, col = "red", axes = FALSE, xlab = "", ylab = "")
# 添加右侧Y轴
axis(side = 4, at = pretty(portfolioReturns$`^GSPC`), col = "red", col.axis = "red")
mtext("标普500 收益率", side = 4, line = 3, col = "red")
# 添加图例
legend("topleft", legend = c("TSN", "^GSPC"), col = c("blue", "red"), lty = 1)

如果要对比原始价格,把代码里的portfolioReturns替换为portfolioPrices即可,逻辑一致。


修正方案2:ggplot2绘图(更灵活美观)

ggplot2需要把数据整理成长格式,方便映射:

library(quantmod)
library(ggplot2)
library(tidyr)
library(dplyr)

tickers <- c("TSN", "^GSPC")
start_date <- "2022-02-20"

# 下载数据并合并为数据框
portfolioPrices <- NULL
for (Ticker in tickers) {
  portfolioPrices <- cbind(portfolioPrices,
                           getSymbols(Ticker, from = start_date, src = "yahoo", auto.assign=FALSE)[,4])
}
portfolioPrices <- portfolioPrices[apply(portfolioPrices,1,function(x) all(!is.na(x))),]
colnames(portfolioPrices) <- tickers

# 转换为长格式数据框
price_df <- data.frame(Date = index(portfolioPrices), coredata(portfolioPrices)) %>%
  pivot_longer(cols = -Date, names_to = "Ticker", values_to = "Price")

# 方式1:双Y轴对比原始价格
ggplot(price_df, aes(x = Date)) +
  geom_line(aes(y = Price, color = Ticker)) +
  scale_y_continuous(
    name = "TSN 股价",
    sec.axis = sec_axis(~ . * (max(price_df$Price[price_df$Ticker=="TSN"])/max(price_df$Price[price_df$Ticker=="^GSPC"])), 
                        name = "标普500 指数")
  ) +
  labs(title = "TSN vs 标普500 价格走势对比", x = "日期") +
  theme_minimal()

# 方式2:归一化到起始值(更直观对比涨幅)
price_df_norm <- price_df %>%
  group_by(Ticker) %>%
  mutate(Norm_Price = Price / first(Price) * 100) %>%
  ungroup()

ggplot(price_df_norm, aes(x = Date, y = Norm_Price, color = Ticker)) +
  geom_line() +
  labs(title = "TSN vs 标普500 归一化涨幅对比", x = "日期", y = "相对于起始日的价格(%)") +
  theme_minimal()

内容的提问来源于stack exchange,提问作者Vladislav Pyatnitskiy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:21:48