UFO ET IT

R + ggplot : 이벤트가있는 시계열

ufoet 2020. 12. 11. 19:03
반응형

R + ggplot : 이벤트가있는 시계열


저는 R / ggplot 초보자입니다. 연속 가변 시계열의 geom_line 플롯을 만든 다음 이벤트로 구성된 레이어를 추가하고 싶습니다. 연속 변수와 타임 스탬프는 하나의 data.frame에 저장되고 이벤트와 해당 타임 스탬프는 다른 data.frame에 저장됩니다.

제가 정말로 하고 싶은 것은 finance.google.com의 차트와 같은 것입니다. 시계열은 주가이고 뉴스 이벤트를 나타내는 "플래그"가 있습니다. 저는 실제로 금융 관련 자료를 그리는 것은 아니지만 그래프 유형은 비슷합니다. 로그 파일 데이터의 시각화를 플롯하려고합니다. 여기 제가 의미하는 바의 예가 있습니다 ...

이벤트가있는 Google 차트

권장되는 경우 (?), 각 레이어에 대해 별도의 data.frame을 사용하고 싶습니다 (하나는 연속 변수 관찰 용, 다른 하나는 이벤트 용).

시행 착오를 거친 후 이것은 내가 얻을 수있는 한 가깝습니다. 여기에서는 ggplot과 함께 제공되는 데이터 세트의 예제 데이터를 사용하고 있습니다. "경제학"에는 내가 계획하고 싶은 시계열 데이터가 포함되어 있고 "대통령"에는 몇 가지 이벤트 (대통령 선거)가 포함되어 있습니다.

library(ggplot2)
data(presidential)
data(economics)

presidential <- presidential[-(1:3),]
yrng <- range(economics$unemploy)
ymin <- yrng[1]
ymax <- yrng[1] + 0.1*(yrng[2]-yrng[1])

p2 <- ggplot()
p2 <- p2 + geom_line(mapping=aes(x=date, y=unemploy), data=economics , size=3, alpha=0.5) 
p2 <- p2 + scale_x_date("time") +  scale_y_continuous(name="unemployed [1000's]")
p2 <- p2 + geom_segment(mapping=aes(x=start,y=ymin, xend=start, yend=ymax, colour=name), data=presidential, size=2, alpha=0.5)
p2 <- p2 + geom_point(mapping=aes(x=start,y=ymax, colour=name ), data=presidential, size=3) 
p2 <- p2 + geom_text(mapping=aes(x=start, y=ymax, label=name, angle=20, hjust=-0.1, vjust=0.1),size=6, data=presidential)
p2

내 시도

질문 :

  • 매우 희박한 이벤트의 경우 괜찮지 만 로그 파일에서 자주 발생하는 클러스터가 있으면 지저분 해집니다. 짧은 시간 간격으로 발생하는 여러 이벤트를 깔끔하게 표시하는 데 사용할 수있는 기술이 있습니까? position_jitter를 생각하고 있었지만 여기까지 가기가 정말 어려웠습니다. Google 차트는 이러한 이벤트 "플래그"가 많은 경우 서로 위에 스택합니다.

  • 나는 실제로 연속 측정 디스플레이와 동일한 규모로 이벤트 데이터를 고정하는 것을 좋아하지 않습니다. 나는 그것을 facet_grid에 넣는 것을 선호합니다. 문제는 모든 패싯이 동일한 data.frame에서 제공되어야한다는 것입니다 (그게 사실인지 확실하지 않음). 그렇다면 그것은 이상적이지 않은 것 같습니다 (또는 모양 변경 사용을 피하려고 할 수도 있습니까?)


@JD Long의 대답을 좋아하는만큼 R / ggplot2에있는 대답을 넣겠습니다.

접근 방식은 이벤트의 두 번째 데이터 세트를 생성하고이를 사용하여 위치를 결정하는 것입니다. @Angelo가 가진 것부터 시작 :

library(ggplot2)
data(presidential)
data(economics)

이벤트 (대통령) 데이터를 가져 와서 변환합니다. 계산 baseline하고 offset경제 데이터의 일부로 그려집니다. 하단 ( ymin)을 기준선으로 설정합니다 . 이것이 까다로운 부분이 오는 곳입니다. 라벨이 너무 가깝다면 서로 엇갈리게 할 수 있어야합니다. 따라서 인접한 레이블 사이의 간격을 결정하십시오 (이벤트가 정렬되었다고 가정). 양보다 적은 경우 (이 데이터 규모에 대해 약 4 년을 선택했습니다) 레이블이 더 높아야합니다. 그러나 그것은 그 이후의 것보다 높아야하므로 rle의 길이를 얻고 TRUE(즉, 더 높아야 함) 그것을 사용하여 오프셋 벡터를 계산하기 위해 사용하십시오 (의 각 문자열은 TRUE길이에서 2로 카운트 다운해야합니다.FALSEs는 오프셋 1)에 있습니다. 이를 사용하여 막대의 상단 ( ymax) 을 결정합니다 .

events <- presidential[-(1:3),]
baseline = min(economics$unemploy)
delta = 0.05 * diff(range(economics$unemploy))
events$ymin = baseline
events$timelapse = c(diff(events$start),Inf)
events$bump = events$timelapse < 4*370 # ~4 years
offsets <- rle(events$bump)
events$offset <- unlist(mapply(function(l,v) {if(v){(l:1)+1}else{rep(1,l)}}, l=offsets$lengths, v=offsets$values, USE.NAMES=FALSE))
events$ymax <- events$ymin + events$offset * delta

이것을 플롯으로 합치면 :

ggplot() +
    geom_line(mapping=aes(x=date, y=unemploy), data=economics , size=3, alpha=0.5) +
    geom_segment(data = events, mapping=aes(x=start, y=ymin, xend=start, yend=ymax)) +
    geom_point(data = events, mapping=aes(x=start,y=ymax), size=3) +
    geom_text(data = events, mapping=aes(x=start, y=ymax, label=name), hjust=-0.1, vjust=0.1, size=6) +
    scale_x_date("time") +  
    scale_y_continuous(name="unemployed \[1000's\]")

패싯 할 수는 있지만 스케일이 다르면 까다 롭습니다. 또 다른 접근 방식은 두 개의 그래프를 구성하는 것입니다. 플롯의 x 범위가 동일한 지 확인하고, 레이블이 모두 하위 플롯에 맞도록하고, 상위 플롯에서 x 축을 제거하기 위해 수행해야하는 몇 가지 추가 조작이 있습니다.

xrange = range(c(economics$date, events$start))

p1 <- ggplot(data=economics, mapping=aes(x=date, y=unemploy)) +
    geom_line(size=3, alpha=0.5) +
    scale_x_date("", limits=xrange) +  
    scale_y_continuous(name="unemployed [1000's]") +
    opts(axis.text.x = theme_blank(), axis.title.x = theme_blank())

ylims <- c(0, (max(events$offset)+1)*delta) + baseline
p2 <- ggplot(data = events, mapping=aes(x=start)) +
    geom_segment(mapping=aes(y=ymin, xend=start, yend=ymax)) +
    geom_point(mapping=aes(y=ymax), size=3) +
    geom_text(mapping=aes(y=ymax, label=name), hjust=-0.1, vjust=0.1, size=6) +
    scale_x_date("time", limits=xrange) +
    scale_y_continuous("", breaks=NA, limits=ylims)

#install.packages("ggExtra", repos="http://R-Forge.R-project.org")
library(ggExtra)

align.plots(p1, p2, heights=c(3,1))


이제는 다음 사람만큼 ggplot을 좋아하지만 Google Finance 유형 차트를 만들고 싶다면 Google 그래픽 API로만하지 않는 이유는 무엇입니까?!? 당신은 이것을 좋아할 것입니다 :

install.packages("googleVis")
library(googleVis)

dates <- seq(as.Date("2011/1/1"), as.Date("2011/12/31"), "days")
happiness <- rnorm(365)^ 2
happiness[333:365] <- happiness[333:365]  * 3 + 20
Title <- NA
Annotation <- NA
df <- data.frame(dates, happiness, Title, Annotation)
df$Title[333] <- "Discovers Google Viz"
df$Annotation[333] <- "Google Viz API interface by Markus Gesmann causes acute increases in happiness."

### Everything above here is just for making up data ### 
## from here down is the actual graphics bits        ###
AnnoTimeLine  <- gvisAnnotatedTimeLine(df, datevar="dates",
                                       numvar="happiness", 
                                       titlevar="Title", annotationvar="Annotation",
                                       options=list(displayAnnotations=TRUE,
                                                    legendPosition='newRow',
                                                    width=600, height=300)
                                       )
# Display chart
plot(AnnoTimeLine) 
# Create Google Gadget
cat(createGoogleGadget(AnnoTimeLine), file="annotimeline.xml")

다음과 같은 환상적인 차트를 생성합니다.

여기에 이미지 설명 입력


Plotlyggplot을 대화 형으로 만드는 쉬운 방법입니다. 이벤트를 표시하려면 색상과 같이 미학적으로 표시 할 수있는 요소로 강제합니다.

최종 결과는 커서를 드래그 할 수있는 플롯입니다. 플롯에는 관심있는 데이터가 표시됩니다.

여기에 이미지 설명 입력

다음은 ggplot을 만드는 코드입니다.

# load data    
data(presidential)
data(economics)

# events of interest
events <- presidential[-(1:3),]

# strip year from economics and events data frames
economics$year = as.numeric(format(economics$date, format = "%Y")) 

# use dplyr to summarise data by year
#install.packages("dplyr")
library(dplyr)
econonomics_mean <- economics %>% 
  group_by(year) %>% 
  summarise(mean_unemployment = mean(unemploy))

# add president terms to summarized data frame as a factor
president <- c(rep(NA,14), rep("Reagan", 8), rep("Bush", 4), rep("Clinton", 8), rep("Bush", 8), rep("Obama", 7))
econonomics_mean$president <- president

# create ggplot
p <- ggplot(data = econonomics_mean, aes(x = year, y = mean_unemployment)) +
  geom_point(aes(color = president)) +
  geom_line(alpha = 1/3)

ggplot을 플롯 객체로 만드는 데 한 줄의 코드 만 필요합니다.

# make it interactive!
#install.packages("plotly")
library(plotly)
ggplotly(p)

참고 URL : https://stackoverflow.com/questions/8317584/r-ggplot-time-series-with-events

반응형