20年分の日次データを時系列にプロットする方法


9

次のデータセット:https : //dl.dropbox.com/u/22681355/ORACLE.csvが あり、「Open」の「Date」による毎日の変化をプロットしたいので、次のようにしました:

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

そして私は以下を取得します:

ここに画像の説明を入力してください

これは明らかにこれまでで最も良いプロットではないので、そのような詳細なデータをプロットするときに使用する適切な方法は何でしょうか。


1
プロットは実際にはそれほど悪くはありません....しかし、それを改善する方法は、強調したいものによって異なります。週次データのみをプロットしますか?滑らかな線を追加しますか?あなたは....確かに、x軸のラベルを変更するべきである
ピーターFlom -復活モニカ

はい、たとえばdl.dropbox.com/u/22681355/Untitled.tiffのように、滑らかなラインが欲しいのですが、スケールが年単位である場合は問題ありませんが、滑らかなラインが不可欠です。タイプを「l」に変更しようとしましたが、実際には何もしませんでした。
dbr

R片道滑らかなラインを追加することですloess。私は途中ですが、Rで?loessを試してください。問題が発生した場合は、投稿を編集してください。誰かがあなたを助けることができます。他にもスムージング方法がありますが、レスが良いデフォルトだと思います。
ピーターフロム-モニカの回復

回答:


8

データの問題は、それが非常に詳細であることではありません。週末には値がないため、ギャップがプロットされます。これに対処するには2つの方法があります。

  1. いずれかのいくつかの平滑化方法(と、週末に近似値を推測しようsmooth.splineloessなど)。簡単な補間のコードは以下のとおりです。ただし、この場合は、データに「不自然」で人工的なものを導入します。それが私が2番目のオプションを好む理由です。
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. 毎日から毎週に移動して、(たとえば)1週間を記録する5つの連続したポイントを平均するだけです(この場合、いくつかの情報を「殺している」)。それを行う方法の簡単な例は
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")

お役に立てば幸いです。


1
おかげで、これは本当に役に立ちます。問題は、これが株価データであるため、毎日から週単位に切り替えると、いくつかの重要なデータが確実に「殺される」可能性があることです。日には滑らかな線を、週末には空のスペースを作る方法はありますか?
dbr

わかりました、あなたが平均しないことが重要であるなら、私は答えを更新し、週末を補間するサンプルコードを提供しました。
ドミトリー・ラプテフ

ところで@dbrあなたが補間でRに依存する場合、それは非常に簡単になります:plot(as.Date(oracle$Date), oracle$Open, type='l')
ドミトリーラプテフ

1
そして、週末に単にギャップが必要な場合openValues <- c(openValues, mean(oracle$Open[i:i-1]))は、最初のメソッドの行をopenValues <- c(openValues, NA)
Dmitry Laptev

9

問題は多くの統計ソフトウェア環境に共通しているため、R固有のフォーラム(StackOverflowなど)に移行するのではなく、ここで相互検証で議論しましょう。

本当の問題は、それがあるDateとして扱われる因子離散変数-A- -及び線が正しく接続されていないので。 (または、水平方向に完全に正確にプロットされている点ではありません。)

プロット比較

右側のプロットを作成するために、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]))

最終プロット


金融関係者ではありませんが、私は季節的なトレンドトリックが好きです。
John Robertson、

@John元々、目を助けるために色が追加されました。しかし、結果を見てみると、2000年のインターネット株価の急増に先立つ6年間のうち5年間で、オレンジ色の週(ほぼ夏の終わり)がすべて強い上昇傾向を示したことは興味深いことです。その後、その傾向は消えたように見えます。
whuber

私もそれに気づき、もしあるとすれば、その関係は何だったのだろうと思いました。
John Robertson

whuberと@John Robertson-密接に関連しているわけではないかもしれませんが、1998年は、MicrosoftがSql Server 7.0 / Sql Server 2000を備えた最新のコードベースに移行し、2000年までにOracleとの競争が激化したときでもありました:en.wikipedia.org/wiki/ Microsoft_SQL_Server#Genesis
Rob

1
@Andre私は「日付」と書きます。相対的な日付であれば、スペースが許せば、「1990年1月1日からの年数」のように書けます。その例では、複数の「年」だけが機能することは明らかだと思います。ちなみに、私は通常、相対的な日付を使用して時間関連データを分析します(数値の安定性、統計サマリーの読みやすさなどのため)が、グラフ表示の実際の日付に変換し直します(表示は意味のある解釈可能な測定単位を使用する必要があるため) 。
whuber

1

週末は補間しません。土曜日に取引される証券取引所はほとんどなく、日曜日に取引所は知りません。存在しなかったデータの推定を導入しているので、代わりにデータセットから土曜日と日曜日を削除しないのはなぜですか?私は以下のようなことをします:

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)

はい、これは私が入手したいものです。しかし、週末を「スキップ」することで行の間に空白を残すだけの簡単な方法はありませんか?
dbr

私はRが日付がある場合はそれが使用されると想定していると思うので、不要なものは削除する必要があります。結局のところ、難しくはありません。上記のコードはほとんど不要です。重要なビットは削除であり、1行しか必要ありません。つまり、mydf <-mydf [!(weekdays(as.Date(mydf $ mydate))%in%c ( 'Saturday'、 'Sunday'))、]
SlowLearner

ただし、データセットではすでに削除されており、土曜日と日曜日の日付は含まれていません
dbr

ああ。私はあなたの質問を完全に誤解したかもしれません。データを平滑化したいだけなら、私は同意します。レスのようなものが進むべき道ですが、それはデータを変えるでしょう。または、詳細を示すプロットの非常に大きな画像を作成できます。たとえば、幅20,000ピクセルなどです。
SlowLearner

Dmitryの解法を使用するのはどうでしょうか。ただし、前の値と次の値の平均を代入する代わりに、0を代入するだけですか。
dbr

0

プロットの外観について、x軸の下に複数のラベルを追加すると視覚的に改善されると思います。ここで確認できる推奨プロットの外観http://imgur.com/ZTNPniA

私はそのようなプロットを作成する方法がわかりません、それは単なるアイデアです(私はRで実現されたのを見たことはありません)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.