I have event data like this. The first column is event name. The second column is event time. Multiple occurrences are separated by ;
. I want to plot the occurrences of the same event in the same row. The name of events is shown on the Y-axis in horizontal orientation. The time is shown on X-axis in the vertical orientation. Event time should be annotated at each event as well. How can I plot it in R?
event1 14:30:00;16:30:00;17:15:00;18:30:00;19:30:00
event2 14:30:00
event3 13:45:00;15:15:00;17:15:00
event4 13:15:00;14:15:00;15:30:00;16:25:00;17:55:00;19:40:00
event5 21:00:00
event6 13:10:00;14:15:00;15:55:00;17:40:00
event7 16:45:00;18:15:00;20:30:00
event8 14:00:00;16:45:00;18:30:00
event9 15:00:00;17:45:00;20:00:00
event10 21:00:00
event11 13:00:00
event12 14:00:00;14:30:00;15:00:00;15:30:00;16:00:00;16:30:00;17:00:00;17:30:00;18:00:00;18:30:00;19:00:00;19:30:00;20:00:00
event13 14:00:00;14:25:00;15:10:00;15:25:00
event14 17:50:00;18:15:00;19:15:00;20:25:00;20:45:00
event15 14:15:00;16:00:00;17:15:00;18:45:00;19:45:00
event16 14:30:00;16:00:00;17:30:00
event17 19:15:00
CodePudding user response:
Using tidyr::separate_rows()
to separate the times in the second column, then converting to time, ordering the first column by number, and plotting:
library(tidyverse)
library(lubridate)
dat %>%
separate_rows(time, sep = ";") %>%
mutate(
event = fct_reorder(event, as.numeric(str_extract(event, "\\d "))),
time = parse_date_time(time, orders = "HMS")
) %>%
ggplot(aes(time, event))
geom_point()
geom_text(
aes(label = strftime(time, "%H:%M")),
angle = 30,
size = 8 / .pt,
hjust = 0,
nudge_y = .25
)
scale_x_datetime(
date_breaks = "1 hour",
date_minor_breaks = "15 min",
date_labels = "%H:%M"
)
scale_y_discrete(expand = expansion(add = c(.6, 1)))
theme_bw()
theme(
axis.text.x = element_text(angle = 90, vjust = .5)
)
CodePudding user response:
As a tidyverse
/ggplot2
solution, you can use a combination of separate_rows
to separate out the different event times separated by semicolons and transform the dataset from wide to long.
library(tidyverse)
library(lubridate)
library(scales)
df <- read_table("
event1 14:30:00;16:30:00;17:15:00;18:30:00;19:30:00
event2 14:30:00
event3 13:45:00;15:15:00;17:15:00
event4 13:15:00;14:15:00;15:30:00;16:25:00;17:55:00;19:40:00
event5 21:00:00
event6 13:10:00;14:15:00;15:55:00;17:40:00
event7 16:45:00;18:15:00;20:30:00
event8 14:00:00;16:45:00;18:30:00
event9 15:00:00;17:45:00;20:00:00
event10 21:00:00
event11 13:00:00
event12 14:00:00;14:30:00;15:00:00;15:30:00;16:00:00;16:30:00;17:00:00;17:30:00;18:00:00;18:30:00;19:00:00;19:30:00;20:00:00
event13 14:00:00;14:25:00;15:10:00;15:25:00
event14 17:50:00;18:15:00;19:15:00;20:25:00;20:45:00
event15 14:15:00;16:00:00;17:15:00;18:45:00;19:45:00
event16 14:30:00;16:00:00;17:30:00
event17 19:15:00", col_names = c("event", "time")) %>%
separate_rows(time, sep = ";") %>%
mutate(time = as.POSIXct(time, format = "%H:%M:%S")) %>%
mutate(event = str_replace_all(event, "event", "")) %>%
mutate(event = as.numeric(event))
df %>%
ggplot(aes(x = event, # event number on x-axis
y = time)) # time on y-axis
geom_point()
scale_x_continuous(breaks = breaks_pretty(n = 12))
scale_y_datetime(breaks = breaks_pretty(n = 12)) # change 12 to something else if desired