Cara memplot data harian 20 tahun dalam deret waktu

9

Saya memiliki dataset berikut: https://dl.dropbox.com/u/22681355/ORACLE.csv dan ingin merencanakan perubahan harian di 'Buka' dengan 'Tanggal', jadi saya melakukan hal berikut:

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

dan saya mendapatkan yang berikut ini:

masukkan deskripsi gambar di sini

Sekarang ini jelas bukan plot terbaik yang pernah ada, jadi saya bertanya-tanya apa metode yang tepat untuk digunakan ketika memplot data terperinci seperti itu?

dbr
sumber
1
Plot sebenarnya tidak terlalu buruk .... tapi bagaimana memperbaikinya tergantung pada apa yang ingin Anda tekankan. Apakah Anda ingin memplot data mingguan saja? Apakah Anda ingin menambahkan garis yang halus? Anda harus mengganti label sumbu-x, tentu saja ....
Peter Flom
Ya, saya ingin memiliki garis yang halus, seperti ini misalnya: dl.dropbox.com/u/22681355/Untitle.tiff , tidak apa-apa jika skalanya bertahun-tahun, tetapi garis yang halus akan sangat penting. Saya sudah mencoba mengubah tipe menjadi "l" tetapi tidak benar-benar melakukan apa pun.
dbr
Dalam Rsatu cara menambahkan garis-garis halus adalah loess. Saya sedang dalam perjalanan keluar, tetapi coba? Loess di R dan, jika Anda mengalami kesulitan, edit posting Anda dan seseorang pasti akan dapat membantu Anda. Ada metode smoothing lain juga, tapi saya pikir loess adalah default yang bagus.
Peter Flom

Jawaban:

8

Masalah dengan data Anda bukan karena itu sangat rinci: Anda tidak memiliki nilai di akhir pekan, itu sebabnya ia diplot dengan kesenjangan. Ada dua cara untuk menghadapinya:

  1. Entah mencoba menebak nilai-nilai perkiraan di akhir pekan dengan beberapa metode smoothing ( smooth.spline, loess, dll). Kode interpolasi sederhana ada di bawah ini. Tetapi dalam hal ini Anda akan memperkenalkan sesuatu yang "tidak alami" dan buatan untuk data. Itu sebabnya saya lebih suka opsi kedua.
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. Anda dapat beralih dari basis harian ke basis mingguan, hanya rata-rata (misalnya) lima poin berurutan yang belog menjadi satu minggu (dalam hal ini Anda "membunuh" beberapa informasi). Contoh singkat bagaimana melakukannya
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")

Semoga ini bisa membantu.

Dmitry Laptev
sumber
1
terima kasih, ini sangat membantu. masalahnya adalah karena ini adalah data stok, beralih dari basis harian ke mingguan pasti dapat 'membunuh' beberapa data penting. Apakah ada cara untuk membuat garis-garis halus untuk hari-hari dan ruang kosong untuk akhir pekan?
dbr
Ok, jika penting bagi Anda untuk tidak rata-rata, maka saya telah memperbarui jawabannya, memberikan kode sampel interpolasi akhir pekan.
Dmitry Laptev
@dbr By the way, jika Anda ingin bergantung pada R dalam interpolasi, itu akan sangat mudah:plot(as.Date(oracle$Date), oracle$Open, type='l')
Dmitry Laptev
1
Dan jika Anda hanya ingin celah di akhir pekan, ganti baris openValues <- c(openValues, mean(oracle$Open[i:i-1]))di metode pertama denganopenValues <- c(openValues, NA)
Dmitry Laptev
9

Karena masalah umum terjadi pada banyak lingkungan perangkat lunak statistik, mari kita bahas di sini di Cross Validated daripada memigrasikannya ke forum R-spesifik (seperti StackOverflow).

Masalah sebenarnya adalah bahwa Datediperlakukan sebagai faktor - variabel diskrit - dan garis tidak terhubung dengan benar. (Poin juga tidak diplot dengan sempurna secara akurat dalam arah horizontal.)

Plot perbandingan

Untuk membuat plot tangan kanan, Datebidang dikonversi dari faktor ke tanggal aktual, setiap minggu diidentifikasi dengan perhitungan sederhana (melanggar minggu antara hari Sabtu dan Minggu) dan garis-garis diinterupsi selama akhir pekan dengan pengulangan selama beberapa minggu:

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

(Tanggal yang setara dengan setiap minggu, memberikan hari Senin minggu itu, juga disimpan dalam oraclekerangka data karena dapat berguna untuk memplot data agregat mingguan.)

Niat asli dapat dicapai hanya dengan meniru baris terakhir untuk menampilkan semua data. Untuk menambahkan beberapa informasi tentang perilaku musiman, plot berikut ini memvariasikan warna berdasarkan minggu selama setiap tahun kalender:

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

Plot terakhir

whuber
sumber
Bukan orang keuangan, tapi saya suka trik trending musiman.
John Robertson
@ John Awalnya warna ditambahkan hanya untuk membantu mata. Tetapi setelah melihat hasilnya, saya merasa menarik bahwa dalam lima dari enam tahun sebelum ledakan saham Internet pada tahun 2000, minggu-minggu oranye (sekitar akhir musim panas) semuanya menunjukkan tren kenaikan yang kuat. Setelah itu, kecenderungan itu tampaknya telah menghilang.
whuber
Saya perhatikan itu juga, dan bertanya-tanya apa hubungannya, jika ada.
John Robertson
whuber dan @John Robertson - Mungkin tidak terlalu terkait tetapi 1998 juga ketika Microsoft pindah ke basis kode modern mereka dengan Sql Server 7.0 / Sql Server 2000 dan pada tahun 2000 mereka memberikan persaingan yang lebih kuat untuk Oracle: en.wikipedia.org/wiki/ Microsoft_SQL_Server # Genesis
Rob
1
@Andre saya akan menulis "Tanggal". Jika ini adalah tanggal relatif, maka - ruang mengizinkan - saya akan menulis sesuatu seperti "Tahun sejak 1 Januari 1990." Dalam contoh itu saya harap jelas bahwa hanya "tahun" jamak yang akan dilakukan. BTW, biasanya saya akan menganalisis data terkait waktu menggunakan tanggal relatif (untuk stabilitas numerik, kemudahan membaca ringkasan statistik, dll.) Tetapi akan mengubahnya kembali menjadi tanggal aktual untuk tampilan grafis (karena tampilan harus menggunakan unit pengukuran yang bermakna dan dapat ditafsirkan) .
Whuber
1

Saya tidak akan melakukan interpolasi pada akhir pekan. Sangat sedikit bursa efek yang diperdagangkan pada hari Sabtu dan tidak ada yang saya ketahui pada hari Minggu. Anda memperkenalkan perkiraan untuk data yang tidak pernah ada jadi mengapa tidak menghapus Sabtu dan Minggu dari kumpulan data? Saya akan melakukan sesuatu seperti di bawah ini:

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)
SlowLearner
sumber
ya, ini yang ingin saya dapatkan. tetapi bukankah ada cara yang lebih mudah dengan hanya meninggalkan ruang kosong di antara garis-garis dengan membiarkannya 'melewatkan' akhir pekan?
dbr
Saya pikir R mengasumsikan bahwa jika ada tanggal, mereka ada untuk digunakan, jadi Anda harus menghapus yang tidak Anda inginkan. Lagi pula, ini tidak sulit, kode di atas sebagian besar berlebihan, bit yang penting adalah penghapusan dan yang hanya memerlukan satu baris, yaitu mydf <- mydf [! (Hari kerja (as.Date (mydf $ mydate))% dalam% c ('Sabtu', 'Minggu')),]
SlowLearner
tetapi sudah dihapus dalam dataset, tanggal untuk hari Sabtu dan Minggu tidak termasuk
dbr
Ah. Saya mungkin benar-benar salah memahami pertanyaan Anda. Jika Anda hanya ingin memuluskan data maka saya setuju, sesuatu seperti loess adalah caranya, tetapi itu akan mengubah data. Atau, Anda dapat membuat gambar plot yang sangat besar yang menunjukkan detail. Lebar 20.000 piksel atau sesuatu, misalnya.
SlowLearner
dan bagaimana dengan menggunakan solusi Dmitry tetapi alih-alih menghitung nilai rata-rata dari nilai sebelumnya dan berikutnya hanya menghitung 0?
dbr
0

Mengenai tampilan plot Anda, saya kira menambahkan beberapa label di bawah sumbu x akan meningkatkannya secara visual. Tampilan plot yang disarankan dapat Anda lihat di sini http://imgur.com/ZTNPniA

Saya tidak tahu bagaimana membuat plot seperti itu, itu hanya sebuah ide (yang belum saya sadari terealisasi di R)

Robin Hood
sumber