0
votes

I am fairly new to R and am attempting to plot data frames simultaneously using ggplot2.

I have two data frames.

One is called WorkSchedMonday and consist of 96 rows and 4 columns.

structure(c(9, 9, 9, 9, 18, 18, 36, 36, 36, 36, 64, 80, 96, 96, 
112, 128, 168, 168, 296, 312, 14, 14, 14, 21, 21, 21, 21, 35, 
49, 49, 12, 12, 6, 6, 0, 0, 0, 0, 6, 6), .Dim = c(10L, 4L), .Dimnames = list(
    c("04:00", "04:15", "04:30", "04:45", "05:00", "05:15", "05:30", 
    "05:45", "06:00", "06:15"), c("WorkSchedAndIndivMondayAtHome", 
    "WorkSchedAndIndivMondayAtSingleWorkPlace", "WorkSchedAndIndivMondayAtVarietyOfPlaces", 
    "WorkSchedAndIndivMondayWorkingOnTheMove")))

The other is called WorkSchedTuesday and consist of 96 rows and 4 columns.

 structure(c(0, 0, 0, 0, 9, 9, 27, 27, 36, 36, 64, 80, 96, 96, 
112, 128, 168, 168, 296, 312, 14, 14, 14, 21, 21, 21, 21, 35, 
49, 49, 12, 12, 6, 6, 0, 0, 0, 0, 6, 6), .Dim = c(10L, 4L), .Dimnames = list(
    c("04:00", "04:15", "04:30", "04:45", "05:00", "05:15", "05:30", 
    "05:45", "06:00", "06:15"), c("WorkSchedAndIndivTuesdayAtHome", 
    "WorkSchedAndIndivTuesdayAtSingleWorkPlace", "WorkSchedAndIndivTuesdayAtVarietyOfPlaces", 
    "WorkSchedAndIndivTuesdayWorkingOnTheMove")))

Using the following code a plotted the 2 data frames.

WorkSchedWeek<-as.matrix(cbind(WorkSchedAndIndivMondayAtHome,WorkSchedAndIndivMondayAtSingleWorkPlace,WorkSchedAndIndivMondayAtVarietyOfPlaces, WorkSchedAndIndivMondayWorkingOnTheMove, WorkSchedAndIndivTuesdayAtHome,WorkSchedAndIndivTuesdayAtSingleWorkPlace,WorkSchedAndIndivTuesdayAtVarietyOfPlaces, WorkSchedAndIndivTuesdayWorkingOnTheMove))



####


melted_WorkSchedWeek<- melt(WorkSchedWeek)


plot<-ggplot(melted_WorkSchedWeek) + geom_col(aes(x = Var1,y = value,fill = Var2),position = "fill")  + theme(legend.position="right", axis.text.x = element_text(angle = 90, hjust = 1))


plot + labs(x="Time", y="Probabilities", colour="Work schedules", fill="Work schedules") 

Timing work schedules

New plot

However I would like to create the above plot using ggplot (or lattice) . On x axis is time (0400 till 0345 _ 24hours) per days (Monday and Tuesday), y axis probability distributions. The plot is filled with work schedules values. Can somebody help me? Thanks

2
It will be easier to help if you can share the data in a way that makes it easy for others to load. Best practice is to add the output of dput(head(WorkSchedMonday, 10)) and dput(head(WorkSchedTuesday, 10)) into your question. - Jon Spring
@JonSpring thank you I updated my question. - Rfanatic
I don't understand what type of chart the sketch represents. Stacked bars? A table? - camille
@camille geom_col but is there a nicer way - Rfanatic

2 Answers

4
votes

You can use facet_grid to make two graphs side by side but sharing an axis. But this requires you to first merge your two dataframes.

To do this we standardize your variables, add a day column, a time column and then use rbind:

WorkSchedMonday = data.frame(structure(c(9, 9, 9, 9, 18, 18, 36, 36, 36, 36, 64, 80, 96, 96, 
  112, 128, 168, 168, 296, 312, 14, 14, 14, 21, 21, 21, 21, 35, 
  49, 49, 12, 12, 6, 6, 0, 0, 0, 0, 6, 6), .Dim = c(10L, 4L), .Dimnames = list(
  c("04:00", "04:15", "04:30", "04:45", "05:00", "05:15", "05:30", 
  "05:45", "06:00", "06:15"), c("WorkSchedAndIndivMondayAtHome", 
  "WorkSchedAndIndivMondayAtSingleWorkPlace", "WorkSchedAndIndivMondayAtVarietyOfPlaces", 
  "WorkSchedAndIndivMondayWorkingOnTheMove"))))
names(WorkSchedMonday) = c("AtHome", "SingleWork", "Variety", "OnTheMove")
WorkSchedMonday$time = rownames(WorkSchedMonday)

WorkSchedTuesday = data.frame(structure(c(0, 0, 0, 0, 9, 9, 27, 27, 36, 36, 64, 80, 96, 96, 
  112, 128, 168, 168, 296, 312, 14, 14, 14, 21, 21, 21, 21, 35, 
  49, 49, 12, 12, 6, 6, 0, 0, 0, 0, 6, 6), .Dim = c(10L, 4L), .Dimnames = list(
  c("04:00", "04:15", "04:30", "04:45", "05:00", "05:15", "05:30", 
  "05:45", "06:00", "06:15"), c("WorkSchedAndIndivMondayAtHome", 
  "WorkSchedAndIndivMondayAtSingleWorkPlace", "WorkSchedAndIndivMondayAtVarietyOfPlaces", 
  "WorkSchedAndIndivMondayWorkingOnTheMove"))))
names(WorkSchedTuesday) = c("AtHome", "SingleWork", "Variety", "OnTheMove")
WorkSchedTuesday$time = rownames(WorkSchedTuesday)

WorkSchedMonday$day =  "Monday"
WorkSchedTuesday$day =  "Tuesday"
WorkSched = rbind(WorkSchedMonday, WorkSchedTuesday)

With that done, you can melt your dataframe like you did before and run the same ggplot, but with facet_grid along the variable that you want your graph to be separated by (day).

WorkSched_melt = melt(WorkSched, id.vars = c("time", "day"))
ggplot(WorkSched_melt, aes(x = time, y = value, fill = variable)) + geom_col(position = "fill") + 
  facet_grid(. ~ day) + theme(legend.position="right", axis.text.x = element_text(angle = 90, hjust = 1))

resulting plot

As a general rule, avoid using really big and clunky variable names, and also avoid having a necessary variable (in this case, time) as your row name.

2
votes

Here is a solution with the data preparation code done with package dplyr.

library(ggplot2)
library(dplyr)

WorkSchedWeek <- cbind(WorkSchedMonday, WorkSchedTuesday)
WorkSchedWeek <- as.data.frame(WorkSchedWeek)
WorkSchedWeek <- cbind.data.frame(Hour = row.names(WorkSchedWeek), WorkSchedWeek)

melted_WorkSchedWeek <- reshape2::melt(WorkSchedWeek, id.vars = "Hour")

melted_WorkSchedWeek %>%
  mutate(variable = sub("^WorkSchedAndIndiv", "", variable),
         Month = sub("(^.{3}).*", "\\1", variable),
         variable = sub("^.*day", "", variable)) %>%
  ggplot(aes(x = Hour,y = value, fill = variable)) + 
  geom_col(position = "fill") + 
  theme(legend.position = "right", 
        axis.text.x = element_text(angle = 90, hjust = 1)) +
  facet_wrap(~ Month)

enter image description here