I have recently been going through some of the modules on Software Carpentry's "Programming in R" lesson, and I have experienced problems displaying some of my plots in RStudio.
Here is the link to the site:
http://swcarpentry.github.io/r-novice-inflammation/04-cond/index.html
Here is the page with the download link for the inflammation data files (r-novice-inflammation-data.zip) if necessary:
http://swcarpentry.github.io/r-novice-inflammation/setup.html
And the practice problem that I am on is called "Choosing Plots Based on Data"
I was supposed to create a function that creates a box plot or stripchart for a file on patient inflammation data based on whether the vector of that data that is called meets a certain threshold. Here is my code:
dat <- read.csv(file = "data/inflammation-01.csv", header = FALSE)
plot_dist <- function(x, threshold) {
if (length(x) > threshold) {
boxplot(x)
} else {
stripchart(x)
}
}
plot_dist(dat[, 10], threshold = 10)
When I call the function, however, no plots are displayed. I went to the plots section in Rstudio, but still found no plots. On my console, the output after calling this function is something like:
Does anyone have any ideas why my plots aren't being displayed? I don't think there is anything wrong with the function, since I don't get any errors after calling it, it just doesn't plot anything. Thanks much!
Related
In the following example, I want to write the residuals plot of each model in a file. I do not need to see them in my display.
for (i in 1:500){
temp.model<-lme(as.formula(paste("Var",i) ~ X1*X2, sep=""), data = example, random=~1| Exp/Person)
jpeg(paste("C:/Myfolder", i, ".jpg", sep = ""), quality=50, bg="white")
plot(temp.model)
dev.off ()
graphics.off()
}
When I run this code without loop, I obtain what I want. However, it creates blank files within the loop.
Any ideas?
Thank you.
The answer is in the FAQ, FAQ 7.22 in fact. However this is not obvious until you realize that the plot.lme function from the nlme package uses lattice/trellis graphics to do the actual plotting (there are references on the help page for plot.lme, but not obvious).
The short form of the solution (but I still recommend reading the FAQ and the other documentation to fully understand the issue) is to wrap the plot in a print command.
Dear Stackoverflow'ers!
I have simple database, app. 130 variables, 1500 records and lots of similar plots to create. I try to avoid save them by hand. The for loop works perfectly for plots (in RStudio).
Here are the data as .csv on dropbox.
data <- read.csv2("data.csv", header=TRUE)
data <- select(data,v1,v2,v3,v4,v5,v6,v7)
for (i in data) {
sjp.frq(i)
}
I would like to save the plots in some directory as a separate .png or .jpg files. I found some clues here. The code looks like this:
data <- select(df,v1,v2,v3,v4,v5,v6,v7)
variables <- names(data)
for (i in data) {
png(paste0("plots/plot_",names(data)[i],".png"))
sjp.frq(i)
dev.off()
}
I deliberately simplified the sjp.frq expression to not make the code unnessecarely complicated.
And here's the problem. I get only single .png file in folder. Where do I make mistake? There should be seven of them.
Best regards, MaciejB.
PS. I follow the suggestion of making code reproducible and added sample of my databaase. When I use i.e. iris, it works. It seems to be something wrong with my data, some NA's maybe? But when I used na.omit() it's the same.
PS.2 I checked another ploting functions like hist() or plot() but it's the same. Only one plot produced and saved.
This works here!
data1 <- read.csv2("~/Temp/data.csv", header=TRUE)
data <- select(data1,v1,v2,v3,v4,v5,v6,v7)
variables <- names(data)
dane=1:length(variables)
for (i in dane ) { #i=2
png(paste0("Temp/plot_",names(data)[i],".png"))
sjp.frq(data[,i],title = names(data)[i])
dev.off()
}
Here 3 of all plots:
I am trying to create a pdf with several plots. More specifically, I want to save my plots, 4 in each page. Therefore, I have the following code in r (which works, but leaves a page empty -the first one-):
pdf("Plots/plots_numeric_four_in_page.pdf",paper="a4r",width = 14)
graphlist <- lapply(3:NCOL(agg_num), function(i) {
force(i)
tempColName=dataName_num[i]
print (tempColName)
p<-qplot(Group.1,agg_num[[tempColName]],data = agg_num,color=Group.2,geom = "line",main=tempColName) + xlab("Date") + ylab(paste("Count of ", tempColName)) + geom_line(size=1.5)+ scale_x_date(labels = date_format("%m/%Y"))+
theme(legend.position="bottom",legend.direction="horizontal")+ guides(col=guide_legend(ncol=3))
})
do.call("marrangeGrob",c(graphlist,ncol=2,nrow=2))
dev.off()
It correctly displays around 50 plots, 4 in each page correctly in a PDF. However, it leaves the first page empty and starts from the second. I looked at marrangeGrob options, but I couldnt find anything to address the problem. Do you know any workaround, or any way to resolve this issue?
There's a known bug between ggplot2 in gridExtra that's causing this for some marrangeGrob's that contain ggplots. Manually overriding the grid.draw.arrangelist function (src) (marrangeGrob returns an arrangelist object) may potentially fix it (suggested here).
grid.draw.arrangelist <- function(x, ...) {
for(ii in seq_along(x)){
if(ii>1) grid.newpage() # skips grid.newpage() call the first time around
grid.draw(x[[ii]])
}
}
It may be safer to define a new class for the arrangelist object in question and apply the fix to it than override grid.draw for every marrageGrob call in scope.
In the following example, I want to write the residuals plot of each model in a file. I do not need to see them in my display.
for (i in 1:500){
temp.model<-lme(as.formula(paste("Var",i) ~ X1*X2, sep=""), data = example, random=~1| Exp/Person)
jpeg(paste("C:/Myfolder", i, ".jpg", sep = ""), quality=50, bg="white")
plot(temp.model)
dev.off ()
graphics.off()
}
When I run this code without loop, I obtain what I want. However, it creates blank files within the loop.
Any ideas?
Thank you.
The answer is in the FAQ, FAQ 7.22 in fact. However this is not obvious until you realize that the plot.lme function from the nlme package uses lattice/trellis graphics to do the actual plotting (there are references on the help page for plot.lme, but not obvious).
The short form of the solution (but I still recommend reading the FAQ and the other documentation to fully understand the issue) is to wrap the plot in a print command.
I do a lot of data exploration in R and I would like to keep every plot I generate (from the interactive R console). I am thinking of a directory where everything I plot is automatically saved as a time-stamped PDF. I also do not want this to interfere with the normal display of plots.
Is there something that I can add to my ~/.Rprofile that will do this?
The general idea is to write a script generating the plot in order to regenerate it. The ESS documentation (in a README) says it well under 'Philosophies for using ESS':
The source code is real. The objects are realizations of the
source code. Source for EVERY user modified object is placed in a
particular directory or directories, for later editing and
retrieval.
With any editor allows stepwise (or regionwise) execution of commands you can keep track of your work this way.
The best approach is to use a script file (or sweave or knitr file) so that you can just recreate all the graphs when you need them (into a pdf file or other).
But here is the start of an approach that does the basics of what you asked:
savegraphs <- local({i <- 1;
function(){
if(dev.cur()>1){
filename <- sprintf('graphs/SavedPlot%03d.pdf', i)
dev.copy2pdf( file=filename )
i <<- i + 1
}
}
})
setHook('before.plot.new', savegraphs )
setHook('before.grid.newpage', savegraphs )
Now just before you create a new graph the current one will be saved into the graphs folder of the current working folder (make sure that it exists). This means that if you add to a plot (lines, points, abline, etc.) then the annotations will be included. However you will need to run plot.new in order for the last plot to be saved (and if you close the current graphics device without running another plot.new then that last plot will not be saved).
This version will overwrite plots saved from a previous R session in the same working directory. It will also fail if you use something other than base or grid graphics (and maybe even with some complicated plots then). I would not be surprised if there are some extra plots on occasion that show up (when internally a plot is created to get some parameters, then immediatly replaced with the one of interest). There are probably other things that I have overlooked as well, but this might get you started.
you could write your own wrapper functions for your commonly used plot functions. This wrapper function would call both the on-screen display and a timestamped pdf version. You could source() this function in your ~/.Rprofile so that it's available every time you run R.
For latice's xyplot, using the windows device for the on-screen display:
library(lattice)
my.xyplot <- function(...){
dir.create(file.path("~","RPlots"))
my.chart <- xyplot(...)
trellis.device(device="windows",height = 8, width = 8)
print(my.chart)
trellis.device(device = "pdf",
file = file.path("~", "RPlots",
paste("xyplot",format(Sys.time(),"_%Y%m%d_%H-%M-%S"),
".pdf", sep = "")),
paper = "letter", width = 8, height = 8)
print(my.chart)
dev.off()
}
my.data <- data.frame(x=-100:100)
my.data$y <- my.data$x^2
my.xyplot(y~x,data=my.data)
As others have said, you should probably get in the habit of working from an R script, rather than working exclusively from the interactive terminal. If you save your scripts, everything is reproducible and modifiable in the future. Nonetheless, a "log of plots" is an interesting idea.