시계열에서 20 년 동안의 일일 데이터를 그리는 방법


9

https://dl.dropbox.com/u/22681355/ORACLE.csv 데이터 세트가 있으며 'Date'로 'Open'의 일일 변경 사항을 플로팅하려고하므로 다음을 수행했습니다.

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

그리고 나는 다음을 얻는다 :

여기에 이미지 설명을 입력하십시오

이제 이것은 분명히 가장 좋은 플롯이 아니므로 자세한 데이터를 그릴 때 올바른 방법이 무엇인지 궁금합니다.


1
음모는 실제로 그렇게 나쁘지 않습니다 .... 개선 방법은 강조하고 싶은 것에 달려 있습니다. 주간 데이터를 플롯하고 싶습니까? 부드러운 선을 추가 하시겠습니까? 당신은 확실히 x 축 레이블을 바꿔야합니다 ....
Peter Flom

예. dl.dropbox.com/u/22681355/Untitled.tiff 와 같이 부드러운 선을 원합니다 . 스케일이 몇 년이면 괜찮지 만 부드러운 선이 필수적입니다. 유형을 "l"로 변경하려고 시도했지만 실제로 아무것도하지 않았습니다.
dbr

에서 R하나의 방법 부드러운 라인입니다 추가 할 수 있습니다 loess. 나는 밖으로 나가고 있지만 R에서 잃어 버리십시오. 문제가 발생하면 게시물을 수정하면 누군가가 당신을 도울 수 있습니다. 다른 스무딩 방법도 있지만 loess가 좋은 기본값이라고 생각합니다.
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. 일주일에 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

좋아, 평균을 내야하지 않는 것이 중요하다면 주말 보간 샘플 코드를 제공하여 답변을 업데이트했습니다.
Dmitry Laptev

당신이 보간에서 R에 의존 할 경우 @dbr 그런데, 그것은 매우 쉬운 것입니다 :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)으로 마이그레이션하지 않고 Cross Validated 에서 여기서 논의하십시오 .

진짜 문제는 즉 DateA와 처리 요소 이산 변수 --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 원래 원래 눈을 돕기 위해 색이 추가되었습니다. 그러나 결과를 살펴보면 2000 년 인터넷 주식 폭등 이전 6 년 중 5 년 동안 주황색 주 (거의 늦여름)가 모두 강한 상승세를 보인 것이 흥미 롭습니다. 그 후에는 그 경향이 사라진 것 같습니다.
whuber

나도 그 사실을 알아 차리고 관계가 무엇인지 궁금해했다.
존 로버트슨

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 "Date"라고 쓸 것입니다. 상대 날짜 인 경우 (공백 허용) "1990 년 1 월 1 일 이후의 년"과 같은 내용을 작성합니다. 이 예에서 나는 복수의 "년"만이 할 것이 분명하다는 것을 희망한다. 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 [! (weekdays (as.Date (mydf $ mydate)) % in % c ( '토요일', '일요일'))]]
SlowLearner

그러나 데이터 세트에서 이미 제거 된 토요일과 일요일 날짜는 포함되지 않습니다.
dbr

아 귀하의 질문을 완전히 이해하지 못했을 수 있습니다. 데이터를 부드럽게하고 싶다면 loess와 같은 방법이 있지만 데이터가 변경됩니다. 또는 세부 사항을 표시하는 매우 큰 플롯 이미지를 작성할 수 있습니다. 예를 들어 너비가 20,000 픽셀 이상입니다.
SlowLearner

Dmitry의 솔루션을 사용하지만 이전 값과 다음 값의 평균을 전가하는 대신 0을 전가하는 것은 어떻습니까?
dbr

0

플롯의 모양과 관련하여 x 축 아래에 여러 레이블을 추가하면 시각적으로 향상된다고 가정합니다. 제안 된 줄거리의 모습은 http://imgur.com/ZTNPniA에서 볼 수 있습니다.

나는 그런 음모를 만드는 법을 모른다. 그것은 단지 아이디어 (R에서 실현되지 않은)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.