ggplot2: выделить область диаграммы

Я работаю с некоторыми данными временных рядов и хотел бы выделять область диаграммы всякий раз, когда выполняются определенные условия. Например:

require(ggplot2)
require(quantmod)
initDate <- "1993-01-31"
endDate <- "2012-08-10"
symbols <- c("SPY")
getSymbols(symbols, from=initDate, to=endDate, index.class=c("POSIXt","POSIXct"))
spy<-SPY$SPY.Adjusted
spy$sma<-SMA(spy$SPY.Adjusted,200)
spy<-spy[-(1:199),] 
spy<-as.data.frame(spy)
ggplot(spy,aes(x=index(spy),y=spy$SPY.Adjusted))+geom_line()+geom_line(aes(x=index(spy),y=spy$sma))

Приведенный выше код отображает данные, но как я могу выделить раздел, когда когда-либо закрытие выше sma? Этот вопрос аналогичен Как выделить временные диапазоны на графике?, но тогда это вручную. Есть ли функция в ggplot2 для условного построения?


person user1234440    schedule 26.08.2012    source источник
comment
Вопрос, на который вы ссылаетесь, является способом сделать это. ggplot2 еще не имеет функциональности для понимания чего-то вроде geom_shade_the_region_that_I_have_in_mind_you_know_that_one(). Вы должны на самом деле сказать, какую область вы хотите затенить.   -  person joran    schedule 27.08.2012
comment
Вы повысите свои шансы на то, что не-кванты поэкспериментируют с вашим кодом, если вставите правильные библиотечные вызовы, чтобы указать, какие пакеты необходимы для запуска этого кода.   -  person IRTFM    schedule 27.08.2012
comment
@joran Большое спасибо за проницательный ответ~ буду усердно работать, чтобы придумать что-нибудь полезное.   -  person user1234440    schedule 27.08.2012
comment
Однако я должен добавить, что, безусловно, можно использовать технику связанного вопроса для написания функции, которая возвращает желаемый объект geom_rect. Но вам все равно придется написать эту функцию самостоятельно, «вручную».   -  person joran    schedule 27.08.2012


Ответы (1)


На основе кода в TA.R пакета quantmod, вот код, который использует rle для поиска начала и конца прямоугольников.

runs <- rle(as.logical(spy[, 1] > spy[, 2]))
l <- list(start=cumsum(runs$length)[which(runs$values)] - runs$length[which(runs$values)] + 1,
          end=cumsum(runs$lengths)[which(runs$values)])
rect <- data.frame(xmin=l$start, xmax=l$end, ymin=-Inf, ymax=Inf)

Объедините это с кодом ggplot2 из принятого ответа на вопрос, на который вы ссылались:

ggplot(spy,aes(x=index(spy),y=spy$SPY.Adjusted))+geom_line()+geom_line(aes(x=index(spy),y=spy$sma))+geom_rect(data=rect, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax), color="grey20", alpha=0.5, inherit.aes = FALSE)

И вы получаете:

введите здесь описание изображения

Если вы измените порядок построения и используете alpha=1 в geom_rect, это может (или не может) выглядеть так, как вы хотите:

ggplot(spy,aes(x=index(spy),y=spy$SPY.Adjusted))+geom_rect(data=rect, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax), border=NA, color="grey20", alpha=1, inherit.aes = FALSE)+geom_line()+geom_line(aes(x=index(spy),y=spy$sma))

введите здесь описание изображения


Поскольку у вас есть объект xts. Возможно, вы даже не захотите конвертировать в data.frame. Вот как вы можете построить его, используя новый метод plot.xts в xtsExtra, созданный Майклом Вейландтом в рамках Google Summer of Code проект.

spy <- as.xts(spy)
require(xtsExtra)
plot(spy, screens=1,
     blocks=list(start.time=paste(index(spy)[l$start]),
                 end.time=paste(index(spy)[l$end]), col='lightblue'),                    
     legend.loc='bottomright', auto.legend=TRUE)

введите здесь описание изображения

person GSee    schedule 26.08.2012