Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
258 views
in Technique[技术] by (71.8m points)

r - Clear labeling of times class data on horizontal barplot/geom_segment

Background: I need to display the time each hospital bed is emptied (via patient discharge) and the time a new patient is placed in the bed, with markers indicating steps taken in between to prepare the bed for the new patient.

Plotting goals: My intention is to have two horizontal bars for each Room/Bed: one (currently in grey) showing the patient who's been discharged, and another (in blue) showing the new patient who's been placed in the same bed.

Question: How can I better display time on the x-axis? I'd be grateful for any referrals to documentation on working with class = "times" data, too.

Sample data:

BedMap <- structure(list(
  Date = structure(c(17210, 17210, 17210, 17210, 17210, 17210, 17210), class = "Date"), 
  RoomBed = c("TestBed1", "TestBed2", "TestBed3", "TestBed4", "TestBed5", "TestBed6", "TestBed7"), 
  UnitGroup = c("Tele", "Tele", "2P", "2P", "3P", "Tele", "ICU"), 
  DcOrderTime = structure(c(0.358333333333333, 0.377777777777778, 0.430555555555556, 0.470833333333333, 0.395833333333333, 0.623611111111111, 0.441666666666667), 
                      format = "h:m:s", class = "times"), 
  DcTime = structure(c(0.457638888888889, 0.475694444444444, 0.5, 0.59375, 0.625, 0.700694444444444, 0.770833333333333), 
                 format = "h:m:s", class = "times"), 
  DecisionTime = structure(c(0.582638888888889, 0.539583333333333, 0.886111111111111, 0.596527777777778, 0.675, 0.653472222222222, 0.777777777777778), 
                       format = "h:m:s", class = "times"), 
  RequestBedTime = structure(c(0.60625, 0.545138888888889, 0.91875, 0.84375, 0.707638888888889, 0.713888888888889, 0.857638888888889), 
                         format = "h:m:s", class = "times"),
  DepartTime = structure(c(0.629166666666667, 0.599305555555556, 0.974305555555556, 0.952083333333333, 0.859722222222222, 0.770138888888889, 0.910416666666667), 
                     format = "h:m:s", class = "times")), 
  class = "data.frame", row.names = c(NA, -7L), 
  .Names = c("Date", "RoomBed", "UnitGroup", "DcOrderTime", "DcTime", "DecisionTime", "RequestBedTime", "DepartTime"))

And current plot, with times displayed as decimals:

enter image description here

ggplot(BedMap) +
  geom_segment(aes(x = 0, #start of light grey bar, indicates bed occupied & discharge planning has not yet started
               y = RoomBed, 
               xend = DcOrderTime, #end of light grey bar
               yend = RoomBed), 
           color = "Light Grey", 
           size = 6) +
  geom_segment(aes(x = DcOrderTime, #start of dark grey bar, indicates bed still occupied but discharge planning has begun
               y = RoomBed, 
               xend = DcTime, #end of dark grey bar, indicates patient has been discharged, bed is unoccupied
               yend = RoomBed), 
               color = "Dark Grey", 
               size = 6) +
  geom_segment(aes(x = DepartTime, #start of blue bar, indicates new patient has been placed in bed
               y = RoomBed, 
               xend = 1, #end of blue bar (set at midnight/end of day)
               yend = RoomBed), 
               color = "Blue", 
               size = 6) +
  geom_point(aes(x = DecisionTime, 
             y = RoomBed), 
         color = "black", size = 3) +
  geom_point(aes(x = RequestBedTime, 
             y = RoomBed), 
         color = "green", size = 3) +
  theme(legend.position = "none") +
  labs(x = "Time", y = "Room-Bed", title = "Daily Bed Map")

When I view the BedMap df, the times show up formatted correctly (eg. DcOrderTime shows up as "08:36:00", "09:04:00", "10:20:00", "11:18:00", "09:30:00", etc.). But the x-axis is displayed as a decimal. Is there a way to just tell my plot code to display the x-axis as "times" class, without having to map the decimals to display values?

View(BedMap)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The issue is, I think, linked to the fact that the times class appears to be holding durations rather than times of day (though I cannot actually find the documentation on the class, having never used it before). Because that format is not explicitly handled by ggplot it is being converted to numeric for plotting (you can see the stored numeric values in your output from dput).

While there is likely a better solution involving converting to POSIX or storing the values directly as time of day, you can accomplish your immediate goal by simply multiplying the numeric value (which is fraction of a day) by 24 to get the time. Then, set sensible axis breaks and add labels as desired, like so:

ggplot(BedMap) +
  geom_segment(aes(x = 0, #start of light grey bar, indicates bed occupied & discharge planning has not yet started
                   y = RoomBed, 
                   xend = 24*DcOrderTime, #end of light grey bar
                   yend = RoomBed), 
               color = "Light Grey", 
               size = 6) +
  geom_segment(aes(x = 24*DcOrderTime, #start of dark grey bar, indicates bed still occupied but discharge planning has begun
                   y = RoomBed, 
                   xend = 24*DcTime, #end of dark grey bar, indicates patient has been discharged, bed is unoccupied
                   yend = RoomBed), 
               color = "Dark Grey", 
               size = 6) +
  geom_segment(aes(x = 24*DepartTime, #start of blue bar, indicates new patient has been placed in bed
                   y = RoomBed, 
                   xend = 24, #end of blue bar (set at midnight/end of day)
                   yend = RoomBed), 
               color = "Blue", 
               size = 6) +
  geom_point(aes(x = 24*DecisionTime, 
                 y = RoomBed), 
             color = "black", size = 3) +
  geom_point(aes(x = 24*RequestBedTime, 
                 y = RoomBed), 
             color = "green", size = 3) +
  theme(legend.position = "none") +
  labs(x = "Time", y = "Room-Bed", title = "Daily Bed Map") +
  scale_x_continuous(breaks = seq(0, 24, 3)
                     , labels = sprintf("%02d:00",seq(0, 24, 3))
                     )

Which gives

enter image description here

The builtin in scale_x_time does not appear to work here, and that is part of what leads me to suspsect that the times class holds durations rather than times of day. If you are using this format often, it may be worthwhile to instead write your own transformation/scale function to use repeatedly.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...