Manipulating x axis in panel plot when a factor is

2019-08-04 09:23发布

问题:

The code I've used is:

mcgc <- ggplot(sam, aes(x = person,y = m, colour = X)) +
              geom_point(size = 0.75) +
              scale_colour_gradient2(high="red", mid="green", limits=c(0,1), guide = "colourbar") +
              geom_hline(aes(yintercept = mad, linetype = "mad"), colour = "blue", size=0.75, show_guide = TRUE) +
              geom_hline(aes(yintercept = mmad, linetype = "mmad"), colour = "black", size=0.75, show_guide = TRUE)  +
              facet_wrap(~ Plan, scales = "free", ncol = 4) +
              scale_linetype_manual(name = "Plan of Health Care", values = c("mad" = 1, "mmad" = 1),guide = "legend")

For this data:

Plan  person X       m  mad  mmad
1  1 95 0.323000 0.400303 0.12
1  2 275 0.341818 0.400303 0.12
1  3  2 0.618000 0.400303 0.12
1  4 75 0.320000 0.400303 0.12
1  5 13 0.399000 0.400303 0.12
1  6 20 0.400000 0.400303 0.12
2  7 219 0.393000 0.353350 0.45
2  8 50 0.060000 0.353350 0.45
2  9 213 0.390000 0.353350 0.45
2  15 204 0.496100 0.353350 0.45
2  19 19 0.393000 0.353350 0.45
2  24 201 0.388000 0.353350 0.45
3  30 219 0.567 0.1254 0.89
3  14 50 0.679 0.1254 0.89
3  55 213 0.1234 0.1254 0.89
3  18 204 0.6135 0.1254 0.89
3  59 19 0.39356 0.1254 0.89
3  101 201 0.300 0.1254 0.89

I'm trying to manipulate the x axis using:

scale_x_continuous(breaks = c(min(person), median(person), max(person)), labels = c(min(person), median(person), max(person))) 

However, given that I had to change person into a factor to order the data properly, the above code does not work. I get the errors, depending on how I fiddle around with the code:

Error: Discrete value supplied to continuous scale
Error in Summary.factor(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L,  : 
  min not meaningful for factors

Changing person to numeric does not work, as the accumulated person for the entire dataset will then be on each Plan figure panel, as opposed to the scale specific for each Plan.

Is there a workaround for this?

回答1:

Build the plots separately and group them with functions from the gridExtra package.

require(ggplot2)

#set breaks and labels (min, median and max) in panel 1
sam1 = subset(sam,sam$Plan==1)
breaks1=c(min(sam1$person),median(sam1$person),max(sam1$person))

plan1 = ggplot(sam1, aes(x = person,y = m, colour=m)) +
  geom_point(size = 2.5) +
  scale_colour_gradient(limits=c(0,1), low="green", high="red", guide="none") +
  geom_hline(aes(yintercept = mad, linetype = "solid"), colour = "blue", size=0.75, show_guide = TRUE) +
  geom_hline(aes(yintercept = mmad, linetype = "solid"), colour = "black", size=0.75, show_guide = TRUE) +
  scale_y_continuous(limits=c(0,1)) +
  scale_x_continuous("",breaks=breaks1,labels=breaks1) + 
  ggtitle("1") +
  theme_bw()

#set breaks and labels (min, median and max) in panel 2
sam2=subset(sam,sam$Plan==2)
breaks2=c(min(sam2$person),median(sam2$person),max(sam2$person))

plan2 = ggplot(sam2, aes(x = person,y = m, colour = m)) +
  geom_point(size = 2.5) +
  scale_colour_gradient(limits=c(0,1), low="green", high="red", guide="none") +
  geom_hline(aes(yintercept = mad, linetype = "solid"), colour = "blue", size=0.75, show_guide = TRUE) +
  geom_hline(aes(yintercept = mmad, linetype = "solid"), colour = "black", size=0.75, show_guide = TRUE)  +
  scale_y_continuous("",limits=c(0,1)) +
  scale_x_continuous("Person",breaks=breaks2,labels=breaks2) +
  ggtitle("2") +
  theme_bw()

#set breaks and labels (min, median and max) in panel 3
sam3=subset(sam,sam$Plan==3)
breaks3=c(min(sam3$person),median(sam3$person),max(sam3$person))

plan3 = ggplot(sam3, aes(x = person,y = m, colour = m)) +
  geom_point(size = 2.5) +
  scale_colour_gradient(limits=c(0,1), low="green", high="red", guide="colourbar") +
  geom_hline(aes(yintercept = mad, linetype = "mad"), colour = "blue", size=0.75, show_guide = TRUE) +
  geom_hline(aes(yintercept = mmad, linetype = "mmad"), colour = "black", size=0.75, show_guide = TRUE)  +
  scale_linetype_manual(name = "Plan of Health Care", values = c("mad" = 1, "mmad" = 1),guide = "legend") +
  scale_y_continuous("",limits=c(0,1)) +
  scale_x_continuous("",breaks=breaks3,labels=breaks3) +
  ggtitle("3") +
  theme_bw()

#using the function form user user971102, posted here: http://stackoverflow.com/questions/14920662/arrange-many-plots-using-gridextra
g_legend<-function(a.gplot){
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  return(legend)}

mylegend = g_legend(plan3)

require(gridExtra)

#adjusting panel widths with code adapted from user971102 and hrbrmstr's code, posted here: http://stackoverflow.com/questions/14920662/arrange-many-plots-using-gridextra
grid.arrange(arrangeGrob(plan1 + theme(legend.position="none"),
                         plan2 + theme(legend.position="none"),
                         plan3 + theme(legend.position="none"),
                         ncol=3),mylegend,
                         widths=unit(c(900,90),"pt"),nrow=1)