2016-03-16 26 views
7

Ngày cuối cùng, tôi đã cân nhắc vấn đề sau: Tôi muốn vẽ thời lượng của một hoạt động dưới dạng một dòng, với trục y biểu thị ngày hoạt động xảy ra và trục x biểu thị thời gian trong giờ. Khi tôi giải quyết một hoạt động bắt đầu và kết thúc trong cùng một ngày, điều này thật dễ dàng.Thời lượng là các dòng với ggplot2

Ví dụ:

df1<-structure(list(Date = structure(c(16802, 16803, 16805, 16806, 
16809, 16810, 16812, 16813, 16816, 16820, 16821, 16822, 16829 
), class = "Date"), hms1 = structure(c(1457623680, 1457620860, 
1457621160, 1457622540, 1457625600, 1457621280, 1457620380, 1457619720, 
1457623620, 1457621460, 1457620440, 1457617980, 1457621880), class =  c("POSIXct", "POSIXt"), tzone = ""), hms2 = structure(c(1457632500, 1457627640, 
1457628360, 1457629500, 1457631000, 1457625120, 1457625420, 1457624520, 
1457627640, 1457626800, 1457626800, 1457622060, 1457625540), class = c("POSIXct", 
"POSIXt"), tzone = "")), .Names = c("Date", "hms1", "hms2"), class =  "data.frame", row.names = c(103L, 105L, 108L, 110L, 114L, 117L, 120L, 122L, 127L, 135L, 136L, 138L, 145L)) 

p1<-ggplot(df1, aes(x=Date,y= hms1))+ scale_x_date(breaks = date_breaks("1 day"))+ 
geom_linerange(aes(ymin = hms1, ymax = hms2),color = "red",size = 2)+ coord_flip() 
p1+ylab("Time")+ggtitle("Activity During Day") 

cho cốt truyện mong muốn: ggplot1

Lưu ý rằng ngày sản, là trên cột ngày trong khi số ngày trong hms1m hms2 là sai do quá trình mà tôi sử dụng để lấy thời gian ở định dạng H: M: S.

df1$hms1 <- format(df1$time, format = "%H:%M:%S") 
df1$hms1 <- as.POSIXct(df1$hms1, format = "%H:%M:%S") 

Thing là hầu hết các "hoạt động", tôi đang cố gắng vẽ nhịp trong khoảng thời gian hai ngày. Giải pháp duy nhất tôi đã đưa ra cho đến bây giờ, đang dịch chuyển cả giá trị ngày giờ theo khoảng thời gian thích hợp, để "nhân tạo" đặt chúng trong cùng một ngày, như được đề xuất ở đây 2. Quá trình này mặc dù, tự nhiên dẫn đến trục x hiển thị dấu thời gian "nhân tạo".

Làm cách nào để kiểm soát dấu tick trong ggplot, vì vậy tôi có thể hiển thị dấu thời gian phù hợp? Hoặc thậm chí tốt hơn ai đó có thể đề xuất một giải pháp thanh lịch hơn? Để rõ ràng: Tôi muốn trục y chỉ là ngày bắt đầu sự kiện, nhưng trục x kéo dài hơn 24 giờ.

+0

Nó sẽ được dễ dàng hơn để giúp bạn nếu bạn cung cấp một mẫu dữ liệu bao gồm các giá trị cơ bản bạn đang sử dụng để tính toán hms1 và hms2. – eipi10

+0

Df2 thực sự là lỗi đánh máy, hiện đã được sửa. Ngay bây giờ, tôi không thể bao gồm mẫu dữ liệu ban đầu nhưng nó sẽ được thực hiện càng sớm càng tốt. –

+0

Tôi không hoàn toàn rõ ràng về kết quả mong muốn của bạn sẽ như thế nào. Bạn có muốn trục y chỉ là ngày bắt đầu sự kiện, nhưng trục x kéo dài hơn 24 giờ? Hay bạn muốn các dòng "bọc" từ một ngày có giá trị y đến ngày y-giá trị tiếp theo? Thứ gì khác? – Gregor

Trả lời

5

Tôi không chắc cấu trúc dữ liệu thực của bạn là gì, vì vậy tôi đã tạo một số khoảng thời gian để minh họa như sau: Tôi đã sử dụng các giá trị của bạn cho Date và sau đó sử dụng runif để chọn một số thời gian bắt đầu và kết thúc ngẫu nhiên cho từng hoạt động. Một số khoảng thời gian xảy ra trong một ngày và một số khoảng thời gian hai ngày.

Sau đó tôi đã vẽ sơ đồ dữ liệu như sau: Vẽ các đường nằm ngang được đặt theo chiều dọc vào ngày bắt đầu hoạt động. Dòng bắt đầu vào thời điểm (tính bằng giờ) khi hoạt động bắt đầu (tương đối với Nửa đêm vào ngày bắt đầu hoạt động), và sau đó kéo dài sang bên phải, tuy nhiên hoạt động này kéo dài nhiều giờ.

Quy mô ngang kéo dài đến 48 giờ để các hoạt động bao gồm nhiều ngày có thể được hiển thị. Đường dọc đánh dấu ranh giới ngày, vì vậy bạn có thể xem những hoạt động nào được tiếp tục vào ngày thứ hai. Nếu bạn có các hoạt động kéo dài từ ba ngày trở lên, chỉ cần mở rộng quy mô ngang khi cần để chứa chúng.

# Convert Date to POSIXct and set HMS to beginning of day (i.e., Midnight). 
# To do this, I added 8-hours to account for my locale being the U.S. Pacific time zone. 
df1$Date = as.POSIXct(df1$Date) + 3600*8 

## Create some times for start and end of each activity 
set.seed(20) 
df1$hms1a = df1$Date + runif(nrow(df1), 3600*5, 3600*10) 
df1$hms2a = df1$Date + runif(nrow(df1), 3600*15, 3600*40) 

library(ggplot2) 
library(scales) 
library(stringr) 

ggplot(df1, aes(x=Date)) + 
    scale_x_datetime(breaks = date_breaks("1 day")) + 
    scale_y_continuous(limits = c(0,48), breaks=seq(0,48,2), 
        labels=str_pad(seq(0,48,2) %% 24, 2, pad="0")) + 
    geom_hline(yintercept=seq(0,48,24)) + 
    geom_linerange(aes(ymin = hms1a - Date, ymax = hms2a - Date), color = "red",size = 2) + 
    coord_flip() + ylab("Time (hours)") + 
    ggtitle("Activity During Day") 

enter image description here

+0

giải pháp rất thông minh và đơn giản. Đây cũng là lần đầu tiên tôi nhìn thấy biểu đồ Gantt trong R. – PavoDive

Các vấn đề liên quan