Zaman serilerinde 20 yıllık günlük veriler nasıl çizilir


9

Aşağıdaki veri kümesi var: https://dl.dropbox.com/u/22681355/ORACLE.csv ve 'Tarih' ile 'Aç' günlük değişiklikleri çizmek istiyorum, bu yüzden aşağıdakileri yaptım:

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

ve aşağıdakileri alıyorum:

resim açıklamasını buraya girin

Şimdi bu açıkça en güzel arsa değil, bu yüzden böyle ayrıntılı verileri çizerken kullanmak için doğru yöntemin ne olduğunu merak ediyorum?


1
Arsa aslında o kadar da kötü değil .... ama nasıl iyileştirileceğini vurgulamak istediğinize bağlıdır. Sadece haftalık verileri çizmek ister misiniz? Düzgün bir çizgi eklemek ister misiniz? Kesinlikle x ekseni etiketlerini değiştirmelisin ...
Peter Flom

Evet, bunun gibi düzgün çizgilere sahip olmak istiyorum, örneğin: dl.dropbox.com/u/22681355/Untitled.tiff , ölçek yıllardaysa sorun değil, ancak düzgün çizgi esastır. Ben "l" türünü değiştirmeye çalıştım ama gerçekten hiçbir şey yapmadı.
dbr

Bir Rşekilde düzgün çizgiler eklemektir loess. Ben çıkış yolundayım, ama denemek ister misiniz? Başka yumuşatma yöntemleri de var, ama bence iyi bir temerrüt.
Peter Flom

Yanıtlar:


8

Verilerinizle ilgili sorun, son derece ayrıntılı olması değil: hafta sonları hiç değeriniz yok, bu yüzden boşluklarla çiziliyor. Bununla başa çıkmanın iki yolu vardır:

  1. Ya bazı yumuşatma yöntemden (hafta sonları yaklaşık değerler tahmin etmeye çalışır smooth.spline, loessvs.). Basit enterpolasyon kodu aşağıdadır. Ancak bu durumda verilere "doğal olmayan" ve yapay bir şey sunacaksınız. Bu yüzden ikinci seçeneği tercih ediyorum.
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. Günlük bazdan haftalık bazda gidebilir, sadece bir haftaya başlayan beş ardışık noktanın ortalamasını alabilirsiniz (örneğin, bu durumda bazı bilgileri "öldürüyorsunuz"). Bunun nasıl yapılacağına dair kısa bir örnek
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")

Umarım yardımcı olur.


1
teşekkürler, bu gerçekten yararlı. Sorun şu ki, bu hisse senedi verileri olduğundan, günlükten haftalık temele dönüşmek bazı önemli verileri kesinlikle 'öldürebilir'. Günler için düzgün çizgiler ve hafta sonları için boş alanlar olmanın herhangi bir yolu var mı?
dbr

Tamam, eğer ortalamamanız önemliyse, cevabı güncelledim, hafta sonları enterpolasyon için örnek kod sağladım.
Dmitry Laptev

@dbr Bu arada, enterpolasyonda R'ye güvenmek istiyorsanız, bu son derece kolay olurdu:plot(as.Date(oracle$Date), oracle$Open, type='l')
Dmitry Laptev

1
Ve sadece hafta sonları sadece boşluklar istiyorsanız openValues <- c(openValues, mean(oracle$Open[i:i-1])), ilk yöntemdeki satırı değiştirinopenValues <- c(openValues, NA)
Dmitry Laptev

9

Sorun birçok istatistiksel yazılım ortamında yaygın olduğundan, bunu R'ye özgü bir foruma (StackOverflow gibi) taşımak yerine burada Cross Validated üzerinde tartışalım .

Gerçek mesele yani Datebir olarak kabul edilir faktörü ayrık değişken -a - ve çizgiler düzgün bağlanmamış edilmiyor yüzden. (Noktalar yatay yönde kusursuz bir şekilde çizilmez.)

Çizim karşılaştırması

Sağ plan yapmak için, Datealan bir faktörden gerçek bir tarihe dönüştürüldü, her hafta basit bir hesaplama ile tanımlandı (Cumartesi ve Pazar arasındaki haftaları kırdı) ve satırlar hafta sonları döngü yaparak haftalar boyunca kesildi:

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))

(Her haftaya denk gelen ve o haftanın Pazartesi gününü veren bir tarih eşdeğeri de veri çerçevesine kaydedildi oracleçünkü haftalık toplu verileri çizmek için yararlı olabilir.)

Orijinal amaç, tüm verileri görüntülemek için son satırı taklit ederek elde edilebilir. Mevsimsel davranışlar hakkında bilgi eklemek için, aşağıdaki grafik her takvim yılı boyunca haftaya göre rengi değiştirir:

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]))

Son grafik


Bir finans insanı değil, ama mevsimsel trend hilesini seviyorum.
John Robertson

@John Başlangıçta renk sadece göze yardımcı olmak için eklendi. Ancak sonuca baktığımda, 2000 yılında İnternet stok patlamasından önceki altı yılın beşinde, turuncu haftaların (kabaca yaz sonu) hepsinin güçlü bir artış eğilimi sergilediğini ilginç buluyorum. Daha sonra bu eğilim yok olmuş gibi görünüyor.
whuber

Bunu da fark ettim ve varsa ilişkinin ne olduğunu merak ettim.
John Robertson

whuber ve @John Robertson - Çok yakından ilişkili olmayabilir, ancak 1998 Microsoft'un Sql Server 7.0 / Sql Server 2000 ile modern kod tabanına taşındığı ve 2000 yılına kadar Oracle'a daha güçlü rekabet sağladıkları zamandı: en.wikipedia.org/wiki/ Microsoft_SQL_Server # Genesis
Rob

1
@Andre "Tarih" yazardım. Göreceli tarihler ise, o zaman - alan izni - "1 Ocak 1990'dan bu yana geçen yıllar" gibi bir şey yazardım. Bu örnekte umarım sadece çoğul “yılların” yapılacağı açıktır. BTW, genellikle göreceli tarihleri ​​(sayısal kararlılık, istatistiksel özetleri okuma vb. İçin) kullanarak zamanla ilgili verileri analiz edeceğim, ancak bunları grafik ekranlar için gerçek tarihlere dönüştüreceğim (çünkü ekranlar anlamlı, yorumlanabilir ölçüm birimleri kullanmalıdır) .
whuber

1

Ben hafta sonları enterpolat olmaz. Çok az borsa Cumartesi günü işlem görüyor ve Pazar günü bilmediğim borsa yok. Hiç var olmayan veriler için bir tahmin sunuyorsunuz, neden Cumartesi ve Pazar günlerini veri kümesinden kaldırmıyorsunuz? Aşağıdaki gibi bir şey yaparım:

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)

Evet, almak istediğim şey bu. ama hafta sonları 'atlayarak' satırlar arasında boşluk bırakmanın daha kolay bir yolu yok mu?
dbr

Sanırım R, tarihler varsa, kullanılacaklarını varsayar, bu yüzden istemediğinizleri kaldırmanız gerekir. Sonuçta, zor değil, yukarıdaki kod çoğunlukla gereksiz, önemli bit kaldırma ve sadece bir satır gerektirir, yani mydf <- mydf [! (Hafta içi (as.Date (mydf $ mydate))% c ('Cumartesi', 'Pazar')),]
Yavaş Öğrenci

ancak veri kümesinde zaten kaldırılmış, Cumartesi ve Pazar günleri dahil değildir
dbr

Ah. Sorunuzu tamamen yanlış anlamış olabilirim. Sadece verileri pürüzsüzleştirmek istiyorsanız, katılıyorum, lös gibi bir şey gitmek için bir yoldur, ancak bu verileri değiştirecektir. Ya da ayrıntıları gösteren çizimin çok, çok büyük bir görüntüsünü oluşturabilirsiniz. Örneğin, 20.000 piksel genişliğinde falan.
SlowLearner

ve Dmitry'nin çözümünü kullanmaya ne dersiniz, ancak önceki ve sonraki değerin ortalamasını sadece 0'lara çarptırmak yerine?
dbr

0

Grafiğinizin görünümü ile ilgili olarak, x ekseni altına birden fazla etiket eklemenin görsel olarak iyileştireceğini düşünüyorum. Burada görebileceğiniz önerilen arsa görünümü http://imgur.com/ZTNPniA

Böyle bir arsa nasıl yapılacağını bilmiyorum, sadece bir fikir (R'de gerçekleştiğini görmedim)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.