Paul Miller
2012-Mar-30 15:08 UTC
[R] Adding text for written comments to bottom of graphs
Hello All, Recently developed the code below for graphing patterns of chemotherapy administration. As someone just starting to use R in their work, I managed to figure out some parts of the code but needed help with others. setwd("N:/Regimen Coding/0906/Plots Test") getwd() TestData <- structure(list(profile_key = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3), line = c(1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1), instance = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2), drug = structure(c(1L, 2L, 1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L, 2L, 1L, 3L, 4L, 3L), .Label = c("Drug A", "Drug B", "Drug C", "Drug D"), class = "factor"), pattern = structure(c(1L, 1L, 4L, 4L, 4L, 3L, 3L, 3L, 3L, 2L, 2L, 5L, 5L, 5L, 5L, 5L), .Label = c(" Begin (A), Begin (B), End (B), End (A)", " Begin (A, B), End (A, B)", " Begin (A, B), End (A, B), Begin (C), End (C), Begin (D), End (D)", " Begin (A, B, C), End (A, B), End (C)", "Begin (A, B, C), End (A, B, C), Begin (C), Begin (D), End (C, D)" ), class = "factor"), start_drug = c(0, 0.7143, 0, 0, 0, 0, 0, 14.5714, 25.4286, 0, 0, 0, 0, 0, 20, 18), stop_drug = c(21, 18, 20, 20, 36, 7.429, 7.429, 21.857, 231.286, 35.286, 35.286, 17, 17, 17, 32.8571, 32.8571)), .Names = c("profile_key", "line", "instance", "drug", "pattern", "start_drug", "stop_drug"), row.names = c(NA, -16L), class = "data.frame") TestData require(reshape) TestData <- melt(TestData, measure.vars = c("start_drug", "stop_drug")) TestData$drug <- factor(TestData$drug, levels = c("Drug D", "Drug C", "Drug B", "Drug A")) TestData$key_line <- with(TestData,paste(profile_key, line, sep = "")) TestData require(ggplot2) temp <- TestData TempData <- split(TestData, TestData$key_line) for(temp in TempData){ png(filename = paste("plot", unique(temp$key_line), ".png", sep = ""), width=600, height=300) p <- ggplot(temp, aes(value, drug, fill = factor(instance))) + geom_line(size = 6) + xlab("\n Time (Weeks)") + ylab("") + theme_bw() + opts(title = paste("Pattern = ", unique(temp$pattern), " \n (profile_key = ", unique(temp$profile_key), ", line = ", unique(temp$line), ") \n", sep = "")) + opts(legend.position="none") print(p) dev.off() } Would like to add lines for written comments to the bottom of each graph. These would look something like: cat( "Regimen 1: __________________________________________________________", "\n", "\n", "Regimen 2: __________________________________________________________", "\n", "\n", "Regimen 3: __________________________________________________________", "\n", "\n", "Regimen 4: __________________________________________________________", "\n", "\n", "Regimen 5: __________________________________________________________", "\n", "\n", "Rationale: __________________________________________________________", "\n", "\n", " __________________________________________________________", "\n", "\n", " __________________________________________________________", "\n", "\n", " __________________________________________________________", "\n", "\n", " __________________________________________________________", "\n", "\n", sep="" ) Not sure exactly how one ought to approach this in R. Can it be done in one step by adding to my ggplot2 code? Would it be better to do it using some sort of post processing? Is it possible to add the text by placing what would be the equivalent of a SAS put statement before the "dev.off()"? Thanks, Paul
baptiste auguie
2012-Mar-30 21:10 UTC
[R] Adding text for written comments to bottom of graphs
Hi, I would do the following, library(ggplot2) require(reshape) TestData <- structure(list(profile_key = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3), line = c(1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1), instance = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2), drug = structure(c(1L, 2L, 1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L, 2L, 1L, 3L, 4L, 3L), .Label = c("Drug A", "Drug B", "Drug C", "Drug D"), class = "factor"), pattern = structure(c(1L, 1L, 4L, 4L, 4L, 3L, 3L, 3L, 3L, 2L, 2L, 5L, 5L, 5L, 5L, 5L), .Label c(" Begin (A), Begin (B), End (B), End (A)", " Begin (A, B), End (A, B)", " Begin (A, B), End (A, B), Begin (C), End (C), Begin (D), End (D)", " Begin (A, B, C), End (A, B), End (C)", "Begin (A, B, C), End (A, B, C), Begin (C), Begin (D), End (C, D)" ), class = "factor"), start_drug = c(0, 0.7143, 0, 0, 0, 0, 0, 14.5714, 25.4286, 0, 0, 0, 0, 0, 20, 18), stop_drug = c(21, 18, 20, 20, 36, 7.429, 7.429, 21.857, 231.286, 35.286, 35.286, 17, 17, 17, 32.8571, 32.8571)), .Names = c("profile_key", "line", "instance", "drug", "pattern", "start_drug", "stop_drug"), row.names = c(NA, -16L), class = "data.frame") TestData <- melt(TestData, measure.vars = c("start_drug", "stop_drug")) TestData$drug <- factor(TestData$drug, levels = c("Drug D", "Drug C", "Drug B", "Drug A")) TestData$key_line <- with(TestData,paste(profile_key, line, sep = "")) str(TestData) ## wrapper to create one title make_title <- function(d){ with(d, paste("Pattern = ", unique(pattern), " \n (profile_key = ", unique(profile_key), ", line = ", unique(line), ") \n", sep = "")) } ## create one plot given a sub-data.frame make_plot <- function(d){ ggplot(TestData, aes(value, drug, fill = factor(instance))) + geom_line(size = 6) + xlab("\n Time (Weeks)") + ylab("") + theme_bw() + opts(title=make_title(d), legend.position="none") } library(plyr) ## apply the function to each subset and store in a list plots <- dlply(TestData, "key_line", make_plot) library(gridExtra) annotation <- paste( "Regimen 1: __________________________________________________________", "\n", "\n", "Regimen 2: __________________________________________________________", "\n", "\n", "Regimen 3: __________________________________________________________", "\n", "\n", "Regimen 4: __________________________________________________________", "\n", "\n", "Regimen 5: __________________________________________________________", "\n", "\n", "Rationale: __________________________________________________________", "\n", "\n", " __________________________________________________________", "\n", "\n", " __________________________________________________________", "\n", "\n", " __________________________________________________________", "\n", "\n", " __________________________________________________________", "\n", "\n", sep="" ) ## add annotation at the bottom ("subtitle") make_annotation <- function(p, sub=textGrob(annotation, x=1, hjust=1.1)){ arrangeGrob(p, sub=sub) } ## apply annotations plots_annotated <- llply(plots, make_annotation) ## print to multi-page pdf pdf("multiple_pages.pdf", height=12, width=10) print(plots_annotated) dev.off() HTH, baptiste On 31 March 2012 04:08, Paul Miller <pjmiller_57 at yahoo.com> wrote:> Hello All, > > Recently developed the code below for graphing patterns of chemotherapy administration. As someone just starting to use R in their work, I managed to figure out some parts of the code but needed help with others. > > setwd("N:/Regimen Coding/0906/Plots Test") > getwd() > > TestData <- structure(list(profile_key = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, > 2, 3, 3, 3, 3, 3), line = c(1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, > 1, 1, 1, 1, 1), instance = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 2), drug = structure(c(1L, 2L, 1L, 2L, 3L, 1L, 2L, > 3L, 4L, 1L, 2L, 2L, 1L, 3L, 4L, 3L), .Label = c("Drug A", "Drug B", > "Drug C", "Drug D"), class = "factor"), pattern = structure(c(1L, > 1L, 4L, 4L, 4L, 3L, 3L, 3L, 3L, 2L, 2L, 5L, 5L, 5L, 5L, 5L), .Label = c(" Begin (A), Begin (B), End (B), End (A)", > " Begin (A, B), End (A, B)", " Begin (A, B), End (A, B), Begin (C), End (C), Begin (D), End (D)", > " Begin (A, B, C), End (A, B), End (C)", "Begin (A, B, C), End (A, B, C), Begin (C), Begin (D), End (C, D)" > ), class = "factor"), start_drug = c(0, 0.7143, 0, 0, 0, 0, 0, > 14.5714, 25.4286, 0, 0, 0, 0, 0, 20, 18), stop_drug = c(21, 18, > 20, 20, 36, 7.429, 7.429, 21.857, 231.286, 35.286, 35.286, 17, > 17, 17, 32.8571, 32.8571)), .Names = c("profile_key", "line", > "instance", "drug", "pattern", "start_drug", "stop_drug"), row.names = c(NA, > -16L), class = "data.frame") > > TestData > > require(reshape) > TestData <- melt(TestData, measure.vars = c("start_drug", "stop_drug")) > TestData$drug <- factor(TestData$drug, levels = c("Drug D", "Drug C", "Drug B", "Drug A")) > TestData$key_line <- with(TestData,paste(profile_key, line, sep = "")) > TestData > > require(ggplot2) > > temp <- TestData > TempData <- split(TestData, TestData$key_line) > > for(temp in TempData){ > > png(filename = paste("plot", unique(temp$key_line), ".png", sep = ""), width=600, height=300) > > p <- ggplot(temp, aes(value, drug, fill = factor(instance))) + geom_line(size = 6) + xlab("\n Time (Weeks)") + ylab("") + theme_bw() + > ? ? opts(title = paste("Pattern = ", unique(temp$pattern), " \n (profile_key = ", unique(temp$profile_key), ", line = ", unique(temp$line), ") \n", sep = "")) + > ? ? opts(legend.position="none") > print(p) > dev.off() > } > > Would like to add lines for written comments to the bottom of each graph. These would look something like: > > cat( > "Regimen 1: __________________________________________________________", "\n", "\n", > "Regimen 2: __________________________________________________________", "\n", "\n", > "Regimen 3: __________________________________________________________", "\n", "\n", > "Regimen 4: __________________________________________________________", "\n", "\n", > "Regimen 5: __________________________________________________________", "\n", "\n", > "Rationale: __________________________________________________________", "\n", "\n", > " ? ? ? ? ? __________________________________________________________", "\n", "\n", > " ? ? ? ? ? __________________________________________________________", "\n", "\n", > " ? ? ? ? ? __________________________________________________________", "\n", "\n", > " ? ? ? ? ? __________________________________________________________", "\n", "\n", > sep="" > ) > > Not sure exactly how one ought to approach this in R. Can it be done in one step by adding to my ggplot2 code? Would it be better to do it using some sort of post processing? Is it possible to add the text by placing what would be the equivalent of a SAS put statement before the "dev.off()"? > > Thanks, > > Paul > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
Paul Miller
2012-Mar-31 15:41 UTC
[R] Adding text for written comments to bottom of graphs
Hello Baptiste, What you've done is very interesting. Went through and tried to understand all the steps. Reminded me of studying languages in years gone by. Always found it easier to read and understand a sentence than to construct a sentence of one's own. This is particularly true when you're just learning. Think I basically get it. You've got a function (make_title) that creates the title for each graph. You've got another function (make_graph) that actually creates each graph and gives it a title using the first function. You're then applying the make_graph function to each value of key_line in the TestData dataframe using dlply. dlply is being used instead of by() because you want to start with a data frame and then end up with a list. Next, you use a function called make_annotation to add the comment lines to each graph. The make_annotation function uses arrangeGrob() from the gridExtra package. You apply the function using llply this time because you are starting out with a list and want to end up with a list. Finally, you're outputting the annotated plots to the pdf destination which can handle multiple plots if you specify "multiple_pages.pdf". This seems a lot better than outputting individual graphs and then inserting them into a Word document as I have been doing. The height and width of the page are determined by the height and width options. At this point, was hoping you could help with refining the output. I've looked at the help page for pdf() and can't see how to modify the code in the ways I'd like. Online searches and an examination of my various R books haven't turned up?much either. ? So here's what I'd like to do if possible: ? 1. Get the output to open at 100% magnification. This would be nice but isn't all that important. ? 2. Add a document title to?the top of just the first page?(e.g., "Regimen Patterns for Study X"). ? 3. Add 1 inch margins around the page. ? 4. Make the comment lines roughly (or exactly) the same width as the graphs and justify the text under the graphs. 5. Shrink the size of each graph/comment combination so it's possible to fit two such combinations on a page. ? Thanks, ? Paul
Paul Miller
2012-Apr-06 13:25 UTC
[R] Adding text for written comments to bottom of graphs
Hi Baptiste, Thanks for your help with this. Sorry for being slow to express my appreciation. I had intended to put some more time into tweaking the graphs before responding. Recently have been reading Hadley Wickham's ggplot2 book and have also located some materials on the knitr package. Didn't get far enough in my reading to do the necessary tweaking in a timely fashion though. The result I'm getting now isn't perfect but it's still pretty amazing. Certainly good enough for our internal coding exercise. Next steps will be to add little grey extensions onto the bars and to obtain better control over the sizing and placement of the graphs and comment text. The little grey extensions will represent the time that chemotherapies remain active following their final administration. So far, the best way I've found for controlling the size of the graph is to add to the number of comment lines. As it happens, we wanted more comment lines anyway and so this worked out well. Must be a better way to get the necessary control though. Will try to figure that out once I have more time. Thanks again for your help with this. Paul