2013-11-09 3 views
3

Я хочу складывать график по шкале времени. Ниже мои данные:R ggplot2 geom_rect stacked up

Flight_No Dest  Date Time STD.60 STD.45  Date2   start  end 
1 ab0729 KP 14-Oct-13 00:05  1  0 2013-10-14 2013-10-14 00:05:00 2013-10-14 00:20:00 
2 ab8063 KI 14-Oct-13 00:20  0  3 2013-10-14 2013-10-14 00:20:00 2013-10-14 00:35:00 
3 ab0337 ST 14-Oct-13 00:30  1  0 2013-10-14 2013-10-14 00:30:00 2013-10-14 00:45:00 

Ниже приведен код для построения графика:

data$Total<-data$STD.60+data$STD.45  
ggplot(data,aes(x=start,y=Total,xmin=start,xmax=end,ymin=0,ymax=Total,alpha=0,fill=factor(Dest)))+geom_rect() 

Над производит этот график:

enter image description here

Однако, я хочу, чтобы сложить эти rectanlges когда есть перекрытие. то есть между 00:30 и 00:35, значение оси y должно быть показано как 4 вместо 3.

Пожалуйста, помогите.

+0

Я не думаю, что есть «автоматический» способ сделать это. Вероятно, вы обречены самим закодировать это. Надеюсь, кто-то докажет, что я неправ. –

+0

@ RomanLuštrik действительно ... – agstudy

ответ

3

После того, как даты отсортированы, легко вычислить перекрывающиеся диапазоны. Для каждого интервала я проверяю, есть ли какое-либо перекрытие (начало> конец), и если да, и я добавляю следующую итоговую сумму со следующей общей текущей.

## choose just relevant columns 
d <- dat[,c('start','end','Dest','Total')] 
# Make sure the data is sorted 
d <- d[ order(d$start), ] 
h <- d 
## here all the main stuff 
for (i in head(seq_len(nrow(d)),-1)){ 
    if(d[i+1,'start'] < d[i,'end']){ 
    xx <- d[i,] 
    xx$start <- d[i+1,'start'] 
    xx$Total <- d[i,'Total'] +d[i+1,'Total'] 
    h <- rbind(h,xx) 
    } 
} 

library(ggplot2) 
ggplot(h,aes(x=start,y=Total,xmin=start,xmax=end,ymin=0,ymax=Total, 
      ,fill=factor(Dest),alpha=0))+ 
    geom_rect() 

EDIT

добавить вручную метки оси х с использованием scale_x_datetime. Я использую также пакет scales для форматирования дат.

library(scales) 
last_plot() 
scale_x_datetime(breaks=unique(c(h$start,h$end)), 
       labels = date_format("%H:%M")) 

enter image description here

+0

Привет, между 00:20 и 00:30 - значение должно быть 3. Между 00:30 - 00:35 значение должно быть 4. Далее, граф не показывает ST перекрытие между 00:30 и 00:35 – Chandra

+0

@Chandra, вы хотите сохранить перекрытие? потому что здесь я удаляю его. – agstudy

+0

Спасибо, что помогли. Я хочу сохранить перекрытие – Chandra

2

Вот это решение, которое зависит от: (1) Разделение оси времени в 5 минут широких бункеров, (2) Восстановление данных в долгосрочной форме, и (3) Пользуясь возможностей укладки geom_bar(position="stack").

enter image description here

dat = structure(list(Dest = c("KP", "KI", "ST"), Total = c(1L, 3L, 1L), 
    start = structure(c(1381730700, 1381731600, 1381732200), 
    class = c("POSIXct", "POSIXt"), tzone = ""), 
    end = structure(c(1381731600, 1381732500, 1381733100), 
    class = c("POSIXct", "POSIXt"), tzone = "")), 
    .Names = c("Dest", "Total", "start", "end"), 
    class = "data.frame", row.names = c(NA, -3L)) 

# Use loop to split each row of data into bins. 
Time = as.POSIXct(vector()) 
Dest = vector("character", length=0) 
Total = vector("integer", length=0) 

for (i in seq(nrow(dat))) { 
    times = seq(from=dat[i, "start"], to=dat[i, "end"], by="5 min") 
    times = head(times, -1) # Remove last element. 
    Time = c(Time, times) 
    Dest = c(Dest, rep(dat[i, "Dest"], length(times))) 
    Total= c(Total, rep(dat[i, "Total"], length(times))) 
} 

dat2 = data.frame(Time, Total, Dest) 

library(ggplot2) 
p = ggplot(dat2, aes(x=Time, y=Total, fill=Dest)) + 
    geom_bar(stat="identity", position="stack", width=300, color="grey30") 

ggsave("plot.png", plot=p, width=10, height=4.5, dpi=120) 

Примечания:

  1. Вы можете изменить ширину бен изменив seq(..., by= аргумент. См. ?seq.POSIXt.
  2. Возможно, вы захотите округлить start и end раз до ближайшей минуты, чтобы облегчить процесс биннинга.
  3. geom_bar(..., width=300) работает, потому что есть 300 секунд за 5 минут. При необходимости отрегулируйте.
  4. Маркировка по оси X находится в центре баров, но они действительно применяют левый край панели. Отрегулируйте с помощью scale_x_datetime(breaks=, как показано на рисунке @agstudy.
+0

@ bdemarest-- Спасибо за отличное решение – Chandra

+0

@Chandra Добро пожаловать. Рад, что я могу помочь! – bdemarest

Смежные вопросы