如何在时间序列中绘制 20 年的每日数据

机器算法验证 r 数据可视化
2022-03-24 05:31:02

我有以下数据集:https ://dl.dropbox.com/u/22681355/ORACLE.csv 并想按“日期”绘制“打开”的每日变化,所以我做了以下事情:

oracle <- read.csv(file="http://dl.dropbox.com/u/22681355/ORACLE.csv", header=TRUE)
plot(oracle$Date, oracle$Open, type="l")

我得到以下信息:

在此处输入图像描述

现在这显然不是有史以来最好的情节,所以我想知道在绘制如此详细的数据时使用什么正确的方法?

4个回答

因为这个问题在许多统计软件环境中都很常见,所以让我们在Cross Validated上讨论它,而不是将它迁移到特定于 R 的论坛(例如 StackOverflow)。

真正的问题是它Date被视为一个因素——一个离散变量——因此线路没有正确连接。 (在水平方向上也不是完美准确地绘制点。)

情节比较

为了制作右手图,该Date字段从一个因子转换为实际日期,每周通过简单的计算确定(打破周六和周日之间的周数),并且通过在周内循环在周末中断行:

oracle$date <- as.Date(oracle$Date)
oracle$week.num <- (as.integer(oracle$date) + 3) %/% 7 
oracle$week <- as.Date(oracle$week.num * 7 - 3, as.Date("1970-01-01", "%Y-%m-%d"))

par(mfrow=c(1,2))
plot(as.factor(unclass(oracle$Date[1:120])), oracle$Open[1:120], type="l",
     main="Original Plot: Inset", xlab="Factor code")
plot(oracle$date[1:120], oracle$Open[1:120], type="n", ylab="Price", 
     main="Oracle Opening Prices")
tmp <- by(oracle[1:120,], oracle$week[1:120], function(x) lines(x$date, x$Open, lwd=2))

(相当于每周的日期,给出该周的星期一,也存储在oracle数据框中,因为它对于绘制每周聚合数据很有用。)

只需模拟最后一行显示所有数据即可达到初衷。为了添加有关季节性行为的一些信息,以下图表在每个日历年中按周改变颜色:

par(mfrow=c(1,1))
colors <- terrain.colors(52)
plot(oracle$date, oracle$Open, type="n", main="Oracle Opening Prices")
tmp <- by(oracle, oracle$week, 
          function(x) lines(x$date, x$Open, col=colors[x$week.num %% 52 + 1]))

最终情节

您的数据的问题不在于它非常详细:您在周末没有值,这就是为什么它被绘制成空白。有两种方法可以处理它:

  1. smooth.spline要么尝试使用一些平滑方法( 、loess等)在周末猜测近似值。简单插值的代码如下。但在这种情况下,您将在数据中引入一些“不自然”和人为的东西。这就是为什么我更喜欢第二种选择。
currentDate <- min(as.Date(oracle$Date))
dates <- c(currentDate)
openValues <- c(oracle$Open[5045])
i <- 5044
while (i > 0) {
  currentDate <- currentDate + 1;
  dates <- c(dates, currentDate)
  if (currentDate == as.Date(oracle$Date[i])) {
        # just copy value and move
        openValues <- c(openValues, oracle$Open[i])
        i <- i-1
      } else {
        # interpolate value
        openValues <- c(openValues, mean(oracle$Open[i:i-1]))
  }
}
plot(dates, openValues, type="l")
  1. 您可以从每天到每周,只需平均(例如)一周后的五个连续点(在这种情况下,您正在“杀死”一些信息)。只是一个简单的例子来说明如何做到这一点
openValues = c(mean(oracle$Open[1:5]));
dates = c(as.Date(oracle$Date[1]));
for (i in seq(6,5045,5)) {
  openValues = c(openValues, mean(oracle$Open[i:i+5]));
      dates = c(dates, as.Date(oracle$Date[i]));
}
plot(dates, openValues, type="l")

希望它会有所帮助。

我不会在周末插值。周六很少有证券交易所交易,而我所知道的周日也没有。您正在引入对从未存在的数据的估计,那么为什么不直接从数据集中删除周六和周日呢?我会做如下的事情:

require(ggplot2)
require(scales)
require(gridExtra)
require(lubridate)
require(reshape)

set.seed(12345)

# Create data frame from random data
daysback <- 1000 # number of days, only a few for this example
startdate <- as.Date(format(now()), format = "%Y-%m-%d") - days(daysback)
mydf <- data.frame(mydate = seq(as.Date(startdate), by = "day", length.out = daysback),
                   open = runif(daysback, min = 600, max = 800))

# Now that we have a data frame, remove the weekend days
mydf <- mydf[!(weekdays(as.Date(mydf$mydate)) %in% c('Saturday','Sunday')),] # remove weekend days
    # Calculate change, except for the first date
    mydf$diff <- c(NA, diff(mydf$open))
    # Remove first row with no 'diff' value
    firstdate <- head(mydf$mydate, 1)
mydf <- mydf[mydf$mydate > firstdate, ]

p <- ggplot(mydf, aes(x = mydate, y = diff)) +
    geom_bar(data = mydf, stat = "identity", fill = "red")

print(p)

关于绘图的外观,我想在 x 轴下添加多个标签会在视觉上改善它。您可以在这里看到建议情节的外观http://imgur.com/ZTNPniA

我不知道如何制作这样的情节,这只是一个想法(我还没有看到在 R 中实现)