knitr - multiple plots within a for loop with grid.arrange - r

I am new to knitr so I am trying to modify the example given at http://yihui.name/knitr/demo/externalization/ to be used with my own r-script. Everything seems to work ok except for a piece of code where the following lines are performed:
for (j in seq(1,length(kkkk)-1))
{
q1=qplot(x[seq(kkkk[j],kkkk[j+1]),1],x[seq(kkkk[j],kkkk[j+1]),2])
q2=qplot(x[seq(kkkk[j],kkkk[j+1]),1],x[seq(kkkk[j],kkkk[j+1]),6])
q3=qplot(x[seq(kkkk[j],kkkk[j+1]),1],x[seq(kkkk[j],kkkk[j+1]),9])
grid.arrange(q1,q2,q3,ncol=1)
}
Those lines will create a series of figures and I would like very much to see them in the final report. Unfortunately nothing shows up. I read the other threads on a similar subject and one of the suggestions was to use print. Unfortunately that also did not force the figures to show up (I have used print(grid.arrange ...) which returns NULL).
Any suggestions?
Many thanks.

Related

Inserting plots inside code chunks in R Markdowns

I'm trying to add a plot to my R Markdown report, however, when I try to knit what I have yet written I found myself with a disastrous error. I have changed a lot of arguments and parameters in order to show the plot on my Markdown.
This is the error I get
I'd like you to help me fix this error so that I can show all the plots I need.
Make sure you've spelled hours correctly. The error suggests you don't have a variable hours in your dataset. Perhaps it ought to be capitalized?

R effects plot displays OK on screen but generated pdf contains no pages

I am using the effects package in R to derive (and plot) the effects of a complicated linear model.
When I use allEffects(linearModel) I can see the results on screen and save it to a pdf file as usual. Since the model has many terms, the output is not useful as it stands.
Therefore I use effects(someTerm, linearModel) to focus on the terms of interest and the results on screen are what I need. However, when saving it to a pdf file, the file contains no useful output (though it does take up 3.5Kb of space). There is no error message from R at the console.
To ease understanding, I created a simple data set and a script for generating the effects plots, in the same way that I tried with the "real" model.
factorData.csv
A,B,C,y
a1,b1,c1,3
a1,b2,c1,4
a2,b1,c1,5
a2,b2,c1,6
a1,b1,c1,2
a1,b1,c2,3.5
a1,b2,c2,4
a2,b1,c2,5.1
a2,b2,c2,6.2
plotEffect.r
require(effects)
dataFile <- '/tmp/factorData.csv'
effectABfile <- '/tmp/effect_AB.pdf'
effectABCfile <- '/tmp/effect_ABC.pdf'
allEffectFile <- '/tmp/lm_eff.pdf'
df <- read.csv(file=dataFile,header=TRUE,sep=',')
linearModel <- lm(y~A*B*C,data=df)
lm_eff <- allEffects(linearModel)
pdf(file=effectABfile)
plot(effect('A:B',linearModel))
dev.off()
pdf(file=allEffectFile)
plot(lm_eff)
dev.off()
pdf(file=effectABCfile)
plot(Effect(c('A','B','C'),linearModel))
dev.off()
As you can see, I tried allEffects, effect and Effect; allEffects is the only one that works for me. Please note that the script assumes that the data is placed in /tmp/factorData.csv - you might need to change the path of course. I also randomised the order in which the plots are generated, with no effect.
I had a look elsewhere on stackoverflow and saving plots to pdfs fails was the closest but the advice there (to issue dev.off() after each plot to 'close' the pdf file) is something I do already, as seen in plotEffect.r.
I tried this script on 2 machines, each running Lubuntu 14.04.1 64-bit with R version 3.0.2 and the latest effects package installed within R using install.packages. The results were the same.
I would be very grateful for advice on how to fix the problem of saving (instances of) this plot type to a pdf.
Fix/workaround
As suggested by #Roland in the comments below, if you wish to save grid plots (such as the output from the effects plots in this instance) into pdf files, it is better/more reliable to generate the plots separately/manually (rather than in a script). It does not appear to be (as much of) an issue for base graphics or even ggplot2 graphics, where I for one have never encountered this problem/needed this workaround in the past. Thanks to #Roland for suggesting this fix!
#Roland also added that Sys.sleep() might help in scripts. Although it did not do so in my case, I discovered that it was possible to paste several such plotting commands and R would run them as a batch, saving the plots to pdf correctly. Therefore, I believe it should be possible to recover much of the benefits of running the script by taking these steps:
Use R to create the text representation of the pdf(), plot() and dev.off() triad of commands
The main script outputs this plotting command text (specific to each instance of a plot) to a file
Open the plotting command text in a text editor
Copy the entire contents of the commands file and paste it into the R console
Optionally, you may wish to use the command line in Step 3 and 4 - How can I load a file's contents into the clipboard? has useful advice.
This two stage procedure is a reasonable workaround, but arguably there should be no need for it.

Inhibit focus stealing when launching a new graphics plot in r

I am familar with matlab, but relatively new to r. I have an r script which produces many different graphical plot windows and takes some time in between each one. While this is running, I tend to be working on other things. The problem is every time a new graphics window is produced, it steals the focus, redirecting keyboard input away from what i am doing. Is there a way in r to prevent focus stealing when a graphical plot is produced?
I have searched everywhere but failed to find any reference to this. I am working in linux.
Any help greatly appreciated.
Thanks
Only on Windows: try putting a bringToTop(-1) in your function:
z <- function() {
plot(1:3)
bringToTop(-1)
}
z()
It will temporarily steal focus but then return it.
Another strategy on Windows:
z <- function(){
windows(restoreConsole=TRUE)
plot(1)
}
z()
I'm still thinking here...
If you are more interested in doing something else while the plots are being produced then I would suggest opening a pdf device so that all the plots go to a pdf file in the background and do not interfere with whatever else you are doing. Then when you are ready to look through the plots you just open the pdf file and look at the plots (and you can easily go back to previous plots this way).
If wmctrl is installed on your system, you can avoid losing focus by redefining the plot function like this:
plot <- function(...) {
graphics::plot(...)
system("wmctrl -a :ACTIVE:")
}
It seems to work quite well, in the fluxbox window manager at least. I tried different scenarios like switching to a different window during a long calculation before plot is called, and opening multiple plots.
Put it into your .Rprofile if you want it to persist.

Generating knitr reports

I'm pretty new to knitr, but I've written a script that generates a report for a county. One of the first lines in the first code chunk is display_county <- "King", and it queries a database to make all sorts of nice things about King County. Now I want to create reports for every county in my state. The only line in the script that needs be changed is the definition of display_county.
I know the brew packages is set up for stuff like this, and I know there's overlap between brew and knitr, but I don't know what I should be using.
This answer using Brew and Sweave would work with minor modifications, but is there a nice knitr way to bypass brew?
If I understand correctly, you are going to use the same Rnw file for each county, so only the variable display_county will be different for each county. I would first make the call to the database to get all the names of counties and store them in a vector (say... myCounties). After that, your reports can be generated with a script containing the following:
for(dc in myCounties) {
knit2pdf(input='county_report.Rnw', output=paste0(dc, '_county_report.pdf'))
}
To handle errors more effectively, you can also wrap the knit2pdf call on a tryCatch statement:
for(dc in myCounties) {
tryCatch(knit2pdf(input='county_report.Rnw', output=paste0(dc, '_county_report.pdf')))
}

issues of wrapping up a set of workable R commands into a function

I generate a dendrogam using a collection of r commands. It worked just fine and saved the generated dendromgram into a PDF file. To improve efficiency, I wrapped these commands as a function, which does not change anything. However, the pdf is just a blank file without any graphical content. Please let me know what’s wrong with my function defintion. Thanks.
myplot<-function(inputcsv, outputfile){
library(ggdendro)
library(ggplot2)
x<-read.csv(inputcsv,header=TRUE)
d<-as.dist(x,diag=FALSE,upper=FALSE)
hc<-hclust(d,"ave")
dhc<-as.dendrogram(hc)
ddata<-dendro_data(dhc,type="rectangle")
ddata$labels$text <- gsub("\\."," ",ddata$labels$text)
ggplot(segment(ddata))+geom_segment(aes(x=x0,y=y0,xend=x1,yend=y1))
pdf(outputfile, width=30,height=35)
last_plot()
dev.off()
}
R FAQ
Wrap your ggplot call in a print() function.
ggplot and friends return an object, and the plotting only happens when the object is printed. When you do this on the command line the printing happens automatically. When you stick it in a script or function you have to do it yourself.
The debate on whether this is a good idea or a dumb thing that just generates questions like this continues...

Resources