Reputation: 2443
I have the following data frame, describing short periods of sleep throughout the day. Here is a sample:
structure(list(starttime = structure(c(1507252170, 1507534980,
1507523940, 1508901450, 1507254150, 1507775670, 1507603260, 1507708020,
1507539960, 1508857170, 1507534740, 1507784520, 1508813190, 1507536060,
1507523160, 1508901870, 1507539840, 1507523520, 1507775640, 1507713660,
1507782240, 1507254390, 1507612950, 1507623210, 1507595190, 1508819730,
1508815680, 1507695990, 1508809830, 1508857050, 1507708530, 1508898960,
1507780860, 1508862510, 1507825860, 1507603830, 1507620630, 1507699950,
1508899320, 1507825980, 1507607970, 1507533120, 1507790460, 1507597110,
1508862570, 1508813640, 1507515420, 1507533180, 1507794360, 1507593210,
1507515360, 1507777710, 1507609710, 1507828440, 1507535040, 1508908470,
1507623270, 1507607400, 1507535100, 1507791360, 1507524060, 1507620210,
1507620330, 1507782300, 1507710690, 1508903760, 1507607370, 1507708380,
1508807400, 1507536000, 1507534800, 1507593030, 1508813160, 1507594230,
1507791720, 1507791000, 1507515600, 1507620570, 1507515480, 1507356150,
1508857110, 1507789500, 1507361400, 1507718940, 1507597260, 1507597980,
1507782630, 1507361760, 1507790580, 1507696290, 1507790490, 1507828260,
1507613610, 1508085480, 1508085420, 1508899020, 1507606380, 1507828380,
1507605780, 1507780050), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
endtime = structure(c(1507254150, 1507535040, 1507524060,
1508901870, 1507254390, 1507777710, 1507603830, 1507708380,
1507540260, 1508862510, 1507534800, 1507785450, 1508813640,
1507539840, 1507523280, 1508902530, 1507539960, 1507523580,
1507775670, 1507718940, 1507782630, 1507257510, 1507613610,
1507623270, 1507597110, 1508856990, 1508819730, 1507696110,
1508810070, 1508857110, 1507708950, 1508899320, 1507781280,
1508862570, 1507825980, 1507604130, 1507620690, 1507700070,
1508899440, 1507828080, 1507609710, 1507533180, 1507790490,
1507597260, 1508862930, 1508813880, 1507515480, 1507534740,
1507797330, 1507593540, 1507515420, 1507780050, 1507610040,
1507829820, 1507535100, 1508908890, 1507624710, 1507607790,
1507536000, 1507791720, 1507524120, 1507620330, 1507620570,
1507782630, 1507711050, 1508903790, 1507607790, 1507708530,
1508809530, 1507536060, 1507534860, 1507593210, 1508813190,
1507595190, 1507793580, 1507791120, 1507515780, 1507620630,
1507515540, 1507356390, 1508857170, 1507790070, 1507361760,
1507719270, 1507597980, 1507603260, 1507784520, 1507364670,
1507791000, 1507696350, 1507791510, 1507828380, 1507613910,
1508085660, 1508085480, 1508899080, 1507607370, 1507828440,
1507606050, 1507780860), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
sleeptype = c("asleep", "awake", "restless", "rem", "awake",
"light", "wake", "wake", "asleep", "asleep", "restless",
"rem", "deep", "asleep", "restless", "light", "restless",
"restless", "wake", "light", "deep", "asleep", "light", "restless",
"deep", "Unknown", "light", "asleep", "wake", "asleep", "rem",
"wake", "wake", "restless", "restless", "rem", "restless",
"restless", "light", "asleep", "rem", "restless", "light",
"light", "asleep", "light", "asleep", "asleep", "rem", "wake",
"restless", "deep", "light", "asleep", "restless", "deep",
"asleep", "deep", "asleep", "light", "asleep", "asleep",
"restless", "deep", "deep", "light", "deep", "light", "light",
"restless", "asleep", "light", "light", "rem", "wake", "light",
"restless", "awake", "restless", "wake", "restless", "light",
"wake", "rem", "wake", "light", "light", "light", "wake",
"awake", "wake", "restless", "rem", "asleep", "restless",
"restless", "light", "awake", "rem", "light"), Date = structure(c(17445,
17448, 17448, 17464, 17445, 17451, 17449, 17450, 17448, 17463,
17448, 17451, 17463, 17448, 17448, 17464, 17448, 17448, 17451,
17450, 17451, 17445, 17449, 17449, 17449, 17463, 17463, 17450,
17463, 17463, 17450, 17464, 17451, 17463, 17451, 17449, 17449,
17450, 17464, 17451, 17449, 17448, 17451, 17449, 17463, 17463,
17448, 17448, 17451, 17448, 17448, 17451, 17449, 17451, 17448,
17464, 17449, 17449, 17448, 17451, 17448, 17449, 17449, 17451,
17450, 17464, 17449, 17450, 17463, 17448, 17448, 17448, 17463,
17449, 17451, 17451, 17448, 17449, 17448, 17446, 17463, 17451,
17446, 17450, 17449, 17449, 17451, 17446, 17451, 17450, 17451,
17451, 17449, 17454, 17454, 17464, 17449, 17451, 17449, 17451
), class = "Date")), row.names = c(NA, -100L), class = c("tbl_df",
"tbl", "data.frame"))
Each of the days contains data from different hours of the day. I would like to plot the time on the x axis, the type of sleep as a factor on the y axis. Here is what I have so far:
ggplot() + geom_segment(data = df, aes(x =starttime, y = sleeptype, xend = endtime,
yend = sleeptype, col= sleeptype), size = 2) +
facet_wrap(~Date, scales = "free_x") +
scale_x_datetime(breaks = date_breaks("1 hour"), date_labels = "%H")
I am missing two things:
How can I connect the segments with vertical (more like diagonal) lines? For an example see the link. https://www.google.co.il/search?q=sleep+stages&source=lnms&tbm=isch&sa=X&ved=0ahUKEwj5j_LFv-_dAhVCiRoKHaE2AxgQ_AUIDigB&biw=1920&bih=894#imgdii=mPhTg0I0Sw3DQM:&imgrc=-M2t6q6EI9fZdM:
I would like the time limit to be 00:00 to 23:59 for each facet. The closest I got was scales = "free_x"
, but this focuses on the available period of each day. I would like all days to be the same. If I don't use the free scales, the time limit for each facet is the entire period of time of the whole data frame.
Any help would be appreciated. Thanks!
Upvotes: 1
Views: 336
Reputation: 66560
I think this can be addressed in two steps:
1) Assign a number to the various sleeptypes, which can be used with geom_step
.
2) Create an alternate timestamp which uses an arbitrary day (Sys.Date will be today, but it could be any day and not matter) paired with the time portion of your timestamps.
The simplest way to present the resulting data is with geom_step
, but that geom works best when the data is continuous without any gaps, ie where each starttime
corresponds to the last enddtime
. It still works decently here but we don't get to see the duration of the last segment in each clump of data.
Alternatively, to see the length of all the segments, we could use geom_segment
, but then we'd have to manually create the vertical pieces and add those, like here: R - (ggplot) Make geom_step jumps dashed
library(lubridate); library(dplyr)
# convenience function to convert datetime to today
today_time <- function(datetime) {
ymd_hms(paste(Sys.Date(), hour(datetime), minute(datetime), second(datetime)))
}
df2 <- df %>%
# These are my guesses, of course code as
mutate(sleep_level = case_when(sleeptype == "awake" ~ 6,
sleeptype == "wake" ~ 6,
sleeptype == "rem" ~ 5,
sleeptype == "restless" ~ 4,
sleeptype == "light" ~ 3,
sleeptype == "asleep" ~ 2,
sleeptype == "deep" ~ 1,
# TRUE captures everything else, incl NA
TRUE ~ -1),
start_today = today_time(starttime),
end_today = today_time(endtime)
)
ggplot(df2) +
geom_hline(yintercept = 0, color = "gray70") +
geom_step(aes(x = start_today, y = sleep_level)) +
# geom_segment(aes(x = start_today, xend = end_today,
# y = sleep_level, yend = sleep_level)) +
facet_wrap(~Date) +
scale_x_datetime(date_labels = "%H:%M")
Upvotes: 1