วิธีพล็อตข้อมูล 20 ปีต่อวันในอนุกรมเวลา


9

ฉันมีชุดข้อมูลต่อไปนี้: 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")

และฉันได้รับต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้เห็นได้ชัดว่าไม่ใช่พล็อตที่อร่อยที่สุดเท่าที่เคยมีมาดังนั้นฉันสงสัยว่าวิธีการที่ถูกต้องที่จะใช้เมื่อทำการพล็อตข้อมูลรายละเอียดนั้นคืออะไร?


1
พล็อตเรื่องจริงแล้วไม่เลวนัก .... แต่วิธีการปรับปรุงขึ้นอยู่กับสิ่งที่คุณต้องการเน้น คุณต้องการที่จะลงจุดข้อมูลรายสัปดาห์หรือไม่ คุณต้องการเพิ่มเส้นเรียบหรือไม่? คุณควรที่จะเปลี่ยนป้ายชื่อแกน x อย่างแน่นอน ....
ปีเตอร์ Flom

ใช่ฉันต้องการที่จะมีเส้นเรียบเช่นนี้เช่น: dl.dropbox.com/u/22681355/Utitled.tiffมันก็โอเคถ้าขนาดอยู่ในปี แต่เส้นที่เรียบจะสำคัญ ฉันพยายามเปลี่ยนประเภทเป็น "l" แต่มันไม่ได้ทำอะไรเลย
dbr

ในวิธีหนึ่งที่จะเพิ่มเส้นเรียบR loessฉันกำลังจะออกไป แต่ลอง? loess ใน R และหากคุณมีปัญหาให้แก้ไขโพสต์ของคุณและใครบางคนจะสามารถช่วยคุณได้อย่างแน่นอน มีวิธีการปรับให้เรียบอื่น ๆ เช่นกัน แต่ฉันคิดว่าเหลืองเป็นค่าเริ่มต้นที่ดี
Peter Flom

คำตอบ:


8

ปัญหาเกี่ยวกับข้อมูลของคุณไม่ได้มีรายละเอียดมาก: คุณไม่มีค่าในวันหยุดสุดสัปดาห์นั่นเป็นสาเหตุที่ข้อมูลถูกพล็อตด้วยช่องว่าง มีสองวิธีในการจัดการกับมัน:

  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. คุณสามารถเปลี่ยนจากรายวันเป็นรายสัปดาห์เพียงเฉลี่ย (ตัวอย่าง) ห้าคะแนนตามลำดับที่ belog ถึงหนึ่งสัปดาห์ (ในกรณีนี้คุณกำลัง "ฆ่า" ข้อมูลบางอย่าง) เป็นเพียงตัวอย่างสั้น ๆ ว่าจะทำอย่างไร
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

ตกลงถ้าเป็นเรื่องสำคัญสำหรับคุณที่จะไม่เฉลี่ยฉันได้อัปเดตคำตอบโดยให้โค้ดตัวอย่างของการแก้ไขวันหยุดสุดสัปดาห์
Dmitry Laptev

@dbr โดยวิธีถ้าคุณต้องการพึ่งพา R ในการแก้ไขนั่นจะง่ายมาก:plot(as.Date(oracle$Date), oracle$Open, type='l')
Dmitry Laptev

1
และในกรณีที่คุณเพียงต้องการช่องว่างเมื่อสุดสัปดาห์ให้แทนที่บรรทัดopenValues <- c(openValues, mean(oracle$Open[i:i-1]))ในวิธีแรกด้วยopenValues <- c(openValues, NA)
Dmitry Laptev

9

เนื่องจากปัญหาเป็นเรื่องปกติของสภาพแวดล้อมทางสถิติของซอฟต์แวร์เรามาพูดคุยกันที่นี่เกี่ยวกับการตรวจสอบความถูกต้องของข้อมูลแทนที่จะทำการย้ายข้อมูลไปยังฟอรัมที่ระบุเฉพาะ 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))

(วันที่เทียบเท่าของแต่ละสัปดาห์โดยให้วันจันทร์ของสัปดาห์นั้นถูกเก็บไว้ในoracledataframe ด้วยเพราะมันจะมีประโยชน์สำหรับการวางแผนข้อมูลรวมรายสัปดาห์)

ความตั้งใจดั้งเดิมสามารถทำได้ง่ายๆโดยการจำลองบรรทัดสุดท้ายเพื่อแสดงข้อมูลทั้งหมด ในการเพิ่มข้อมูลเกี่ยวกับพฤติกรรมตามฤดูกาลพล็อตต่อไปนี้จะเปลี่ยนสีตามสัปดาห์ตลอดแต่ละปีปฏิทิน:

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 สัปดาห์สีส้ม (ช่วงปลายฤดูร้อนโดยประมาณ) ทั้งหมดแสดงแนวโน้มที่แข็งแกร่งขึ้น หลังจากนั้นแนวโน้มดังกล่าวดูเหมือนจะหายไป
whuber

ฉันสังเกตเห็นเช่นกันและสงสัยว่าความสัมพันธ์ถ้ามีคืออะไร
John Robertson

whuber และ @John Robertson - อาจไม่เกี่ยวข้องอย่างใกล้ชิดเกินไป แต่ 1998 ก็เช่นกันเมื่อ Microsoft ย้ายไปที่ codebase ที่ทันสมัยด้วย Sql Server 7.0 / Sql Server 2000 และในปี 2000 พวกเขาได้แข่งขันกับ Oracle: en.wikipedia.org/wiki/ Microsoft_SQL_Server # Genesis
Rob

1
@ Andre ฉันจะเขียน "วันที่" ถ้าเป็นวันที่สัมพันธ์กัน - พื้นที่ว่าง - ฉันจะเขียนบางอย่างเช่น "ปีนับตั้งแต่ 1 มกราคม 2533" ในตัวอย่างนั้นฉันหวังว่าชัดเจนว่า "ปี" พหูพจน์เท่านั้นที่จะทำได้ BTW โดยปกติแล้วฉันจะวิเคราะห์ข้อมูลที่เกี่ยวข้องกับเวลาโดยใช้วันที่สัมพัทธ์ (สำหรับความเสถียรเชิงตัวเลขความง่ายในการอ่านข้อมูลสรุปทางสถิติ ฯลฯ ) แต่จะแปลงกลับเป็นวันที่ที่แท้จริงสำหรับการแสดงผลกราฟิก (เพราะหน้าจอควรใช้หน่วยวัดที่มีความหมาย .
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 สันนิษฐานว่าหากมีวันที่พวกเขาจะถูกนำมาใช้ดังนั้นคุณควรลบคนที่คุณไม่ต้องการ ท้ายที่สุดก็ไม่ยากรหัสข้างต้นส่วนใหญ่ไม่จำเป็นบิตที่สำคัญคือการลบและที่ต้องใช้เพียงหนึ่งบรรทัดคือ mydf <- mydf [! (วันธรรมดา (ตามวันที่ (mydf $ mydate))% ใน% c ('วันเสาร์', 'วันอาทิตย์')),]
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.