How to create dynamic names for ggplot? [duplicate] - r

My data (TransDat70) contains 103 variables total. The first 102 are named "V1" through "V102", the last variable is names "Time.Min".
I need to generate 102 ggplots of each variable (V1 through V102) against the variable "Time.Min". I then need to save all these ggplots in a separate file (pdf) preferably all next to/below one another for comparison purposes.
I tried using code that I was able to find online but none has worked for me so far.
Here is my code:
var_list = combn(names(TransDat70)[1: 102], 2, simplify = FALSE)
plot_list = list()
for (i in 1: 3) {
p = ggplot(TransDat70, aes_string(x = var_list[[i]][1], y = var_list[[i]][2])) + geom_point()
plot_list[[i]] = p
}
for (i in 1: 3) {
plot70 = paste("iris_plot_", i, ".tiff", sep = "")
tiff(plot70)
print(plot_list[[i]])
dev.off()
}
pdf("plots.pdf")
for (i in 1: 3) {
print(plot_list[[i]])
}
dev.off()
Any suggestions?

If by separate you meant each plot in a separate file, how about this?
library(ggplot2)
# FAKE DATA AS EXAMPLE
TransDat70 <- data.frame(
1:10,
1:10,
1:10,
1:10,
1:10
)
colnames(TransDat70) <- c('V1', 'V2', 'V3', 'V4', 'Time.Min')
for (i in 1:(length(TransDat70) - 1)) {
p <- ggplot(TransDat70, aes_string(x = paste('V', toString(i), sep=''), y='Time.Min')) + geom_point()
ggsave(paste('~/Desktop/plot_', i, '.pdf', sep=''), p)
}
See the ggsave documentation for more options.
If you meant to have them all in one big file, take a look at Printing multiple ggplots into a single pdf, multiple plots per page.
However, for that many plots it would make a likely make a huge file, which could be problematic to open, especially if you have many points in your plots. In that case it might be better to compare them as separate files.

Related

Saving multiple GGplots to a pdf, multiple on one page in a for loop

I am trying to save multiple ggplots that essentially do a histogram of each column. Ideally I would like to have 2 or 3 graphs per page, but for now I am fine with just 1 per page. The ggplots look fine, but I cannot seem to get the ggplots to save correctly(although probably not doing it correctly).
item_set <- unique(df$Item_number)
for(i in 1:length(item_set)){
n <- as.character(item_set[i])
temp <- wide_data[, grep(n, names(wide_data))]
temp <- temp[, grep("Time", names(temp))]
coln <- colnames(temp)
ggplot(data = temp, aes_string(x = coln)) + geom_histogram(color = "black", fill = "white", bins = 70)
ggsave("Time Spent - Entire Sample.pdf")
}
So for each ggplot, it is basically just taking column by column, by column name(coln) and creating a histogram. How can I save all of these to a single pdf?
Maybe you will find this example of creating ggplots in a loop useful.
# Plot separate ggplot figures in a loop.
library(ggplot2)
# Make list of variable names to loop over.
var_list = combn(names(iris)[1:3], 2, simplify=FALSE)
# Make plots.
plot_list = list()
for (i in 1:3) {
p = ggplot(iris, aes_string(x=var_list[[i]][1], y=var_list[[i]][2])) +
geom_point(size=3, aes(colour=Species))
plot_list[[i]] = p
}
# Save plots to tiff. Makes a separate file for each plot.
for (i in 1:3) {
file_name = paste("iris_plot_", i, ".tiff", sep="")
tiff(file_name)
print(plot_list[[i]])
dev.off()
}
# Another option: create pdf where each page is a separate plot.
pdf("plots.pdf")
for (i in 1:3) {
print(plot_list[[i]])
}
dev.off()

Save multiple plots as individual PDFs with unique names in R

I have a function that creates a plot and saves it as a pdf file. I plan on running this function in a loop for 100+ columns of a dataset. My question is how to make each pdf file uniquely named so it doesnt overwrite the previous file every time a new one is made. I tried to make it work with C integer format
pdf(file = "~/PTY/Data/ROC Curves/ROC%03d.pdf", onefile = F, width = 7, height = 7)
with the intended outcome of titling each plot ROC001, ROC002... but it still overwrites each new one as ROC001.
createROC <- function(x) {
ROCtable <- createNAtable(x) #create dataset w/out NAs
x_NA <-x[!is.na(x)] #create analyte vector w/out NAs
#create ROC variable
newROC <- rocit(score = x_NA, class = ROCtable$DSM, negref = "0", method = "non")
#create pdf
pdf(file = "~/PTY/Data/ROC Curves/ROC%03d.pdf", onefile = F, width = 7, height = 7)
#create ROC plot
plot(newROC, legend = F)
dev.off()
}
My function takes a vector (data1$IL6, data1$age, etc) as an input. Ideally, I would be able to title each plot after the input (IL6, age, etc).
Thank you ahead of time for your help
The problem is that you are opening and closing the graphics device with each plot, and the counter resets at 001 each time. You need one call to pdf(), followed by all of your calls to plot(), followed by dev.off(), like so:
# Some data with named columns
df <- data.frame(a = 1:10, b = 11:20, c = 21:30)
# A plotting function without `pdf()` and `dev.off()`
create_plot <- function(x, main) {
plot(x, main = main)
}
# Open graphics device
pdf(file = "filename-%03d.pdf", onefile = FALSE)
# Apply plotting function to each column of `df` in a loop
for (j in 1:3) {
create_plot(df[, j], names(df)[j])
}
# Close graphics device
dev.off()
This should generate filename-001.pdf, filename-002.pdf, and filename-003.pdf in your working directory.

Is there a way to loop through directories in one r-script file

I have a couple hundred folders (observations), each with a few text files (each one is a trial). I was able to figure out, with some help, how to loop through the text files and create one image of the graph so it is saved in the folder/directory...
setwd("~/data/observation1")
library(ggplot2)
files <- list.files(pattern=".txt")
for (i in files){
mylist <- lapply(setNames(files, files), read.table, header = T)
mylist <- lapply(names(mylist), function(i) {cbind(mylist[[i]], ID = i)})
mydata <- do.call(rbind, mylist)
}
ggplot(mydata, aes(x = place, y = firing_rate, colour = ID)) + geom_point() + geom_path()
dev.print(pdf, 'observation1.pdf')
It works perfectly, but now I am trying to zoom out, so to say, so I can apply the aforementioned code to all the other folders/directories (observation2, observation3, etc.) without having to go through and change the setwd() one by one.
Additionally, it would also be great if I could somehow just save all the plots (one for each folder) as one big pdf with a few hundred pages.
Any advice for how to do these two things or even start them is greatly appreciated and I will gladly answer any questions.
Here's one approach, you can modify to suit your needs:
setwd("~/data")
my_folders <- c("observation1", "observation2", "observation3") # etc.
for(j in my_folders) {
files <- list.files(path = j, pattern=".txt", full.names=T)
# ... etc
}
You can make a vector of your observations with
vector <- dir(path="~/data/") # this will list all your observations
mylist<- list()
for ( i in 1:length(vector){
setwd(paste0("~/data/",vector[i]))
files[[i]] <- list.files(pattern=".txt")
for (j in files[[i]]){
mylist[[i]] <- lapply(setNames(files[[i]], files[[i]]), read.table, header = T)
mylist[[i]] <- lapply(names(mylist[[i]]), function(j) {cbind(mylist[[i]], ID = j)})
mydata[[i]] <- do.call(rbind, mylist[[i]])
}
}
then you can plot each file in mylist

for loop to generate and save multiple ggplots in a separate file

My data (TransDat70) contains 103 variables total. The first 102 are named "V1" through "V102", the last variable is names "Time.Min".
I need to generate 102 ggplots of each variable (V1 through V102) against the variable "Time.Min". I then need to save all these ggplots in a separate file (pdf) preferably all next to/below one another for comparison purposes.
I tried using code that I was able to find online but none has worked for me so far.
Here is my code:
var_list = combn(names(TransDat70)[1: 102], 2, simplify = FALSE)
plot_list = list()
for (i in 1: 3) {
p = ggplot(TransDat70, aes_string(x = var_list[[i]][1], y = var_list[[i]][2])) + geom_point()
plot_list[[i]] = p
}
for (i in 1: 3) {
plot70 = paste("iris_plot_", i, ".tiff", sep = "")
tiff(plot70)
print(plot_list[[i]])
dev.off()
}
pdf("plots.pdf")
for (i in 1: 3) {
print(plot_list[[i]])
}
dev.off()
Any suggestions?
If by separate you meant each plot in a separate file, how about this?
library(ggplot2)
# FAKE DATA AS EXAMPLE
TransDat70 <- data.frame(
1:10,
1:10,
1:10,
1:10,
1:10
)
colnames(TransDat70) <- c('V1', 'V2', 'V3', 'V4', 'Time.Min')
for (i in 1:(length(TransDat70) - 1)) {
p <- ggplot(TransDat70, aes_string(x = paste('V', toString(i), sep=''), y='Time.Min')) + geom_point()
ggsave(paste('~/Desktop/plot_', i, '.pdf', sep=''), p)
}
See the ggsave documentation for more options.
If you meant to have them all in one big file, take a look at Printing multiple ggplots into a single pdf, multiple plots per page.
However, for that many plots it would make a likely make a huge file, which could be problematic to open, especially if you have many points in your plots. In that case it might be better to compare them as separate files.

Autosaving multiple pages of lattice plots

I was wondering if anyone could assist with code below. I have a huge dataset (> 1000 subjects) which I'm trying to visualise individually.
I was fortunate to find a code written by Tony Cookson from R-bloggers which I've modified for my use. The code works ok but the pdfs produced are damaged-essentially they refuse to open. I have a feeling there's bug somewhere but I haven't yet figured out where. Any assistance would be highly appreciated.
library(lattice)
names = LETTERS[1:3]
for(i in 1:3){
mypath <- file.path("myFilepath", "folder containing 'Plots' subfolder ",
"Plots",paste("myplot_", names[i], ".pdf", sep = ""))
pdf(file=mypath)
mytitle = paste("Theoph Plots", names[i])
xyplot(conc ~ Time | Subject, group = Subject, data = Theoph, type = "l",
layout = c(2, 2), main = mytitle)
dev.off()
}
For the code to be reproducible, you need to replace myFilepath, folder containing 'Plots' subfolder and "Plots" with names of actual folders that can be found on your computer. Please see the original on R-bloggers for more details. I would be very happy to clarify anything that seems ambiguous.
Thanks
Edit:
library(lattice)
names = LETTERS[1:3]
for(i in 1:3){
mypath <- file.path("myFilepath", "folder containing 'Plots' subfolder ",
"Plots",paste("myplot_", names[i], ".pdf", sep = ""))
pdf(file=mypath)
mytitle = paste("Theoph Plots", names[i])
print(xyplot(conc ~ Time | Subject, group = Subject, data = Theoph, type = "l",
layout = c(2, 2), main = mytitle))
dev.off()
}
I've managed to find a temporary solution (above) using the print function. However, I'm currently getting all 12 Subjects in the same pdf. What I really want is 4 subjects (2 by 2 matrix) on separate pdfs so making 3 pdfs in total. Anyone know how to do this?
If you're looking to plot a subset of Subjects on each page, then you have to subset your data for each iteration and then plot.
To get 4 Subjects on each page, you can use the following index builder as a basis for subsetting:
(i - 1) * 4 + 1:4
The trick with the Theoph dataset is that the subject "numbers" are actually ordered factors. So you have to convert the above to a factor, or, as a shortcut, to a character vector.
for(i in 1:3){
## Changed mypath to make it reproducible
mypath <- file.path(tempdir(), paste("myplot_", names[i], ".pdf", sep = ""))
pdf(file=mypath)
mytitle = paste("Theoph Plots", names[i])
myIndex <- as.character((i - 1) * 4 + 1:4) # index builder from above
print(xyplot(conc ~ Time | Subject,
data = Theoph[Theoph$Subject %in% myIndex, ],
type = "l", layout = c(2, 2), main = mytitle))
dev.off()
}
The order of the subjects is a bit screwy, since that variable is an ordered factor, as mentioned. To keep the ordering, you could subset on the levels of that factor:
myIndex <- levels(Theoph$Subject)[(i - 1) * 4 + 1:4]
The best way to build your index will depend on your actual data.

Resources