How can I save a list of scatterplots - r

I wanna save a list of scatterplots with their filenames.
Therefor I give each plot a name, which worked perfectly:
names(scatterplot_standardcurve) <-
sub("\\.xlsx$",
".png",
names(standardcurve_concentration))
> print(scatterplot_standardcurve)
$K_20210722
$A_20210722
$c_20210722
$d_20210722
$t_20210722
$v_20210722
And then I want to save them in a specific folder but I always get an error
lapply(names(scatterplot_standardcurve),
function(nm) print(scatterplot_standardcurve[[nm]]) +
ggsave(filename = file.path("Z:/output/scatterplot_standardcurve/",
nm )))
Error: Unknown graphics device ''

Using imap you'll be able to iterate over the ggplot object as well as it's name. Try -
library(purrr)
library(ggplot2)
imap(scatterplot_standardcurve,
~ggsave(sprintf("Z:/output/scatterplot_standardcurve/%s.png", .y), .x))

Related

Retrieve the name of the last value as a character vector

I am trying to automate the naming of a ggplot output saved using ggsave()
When I create the following plot I am able to retrieve the name of the plot using a combination of the deparse and substitute functions if I state the plot name explicitly
# make the plot
df <- data.frame(x = 1:10, y = 1:10)
my_plot <- ggplot(df, aes(x, y))+geom_point()
# generate the file name
filename <- paste0(deparse(substitute(my_plot)), ".jpg")
filename
However, I am trying to pass the plot name to the substitute function directly using without having to state it twice using .Last.value. This generates the incorrect result.
my_plot_name <- deparse(substitute(.Last.value))
my_plot_name
## [1] ".Last.value"
How can I access the name of the last ggplot object (or any other object) to be saved without stating the name explicitly?
EDIT: To be specific, my desired output based on the above example and some pseudo code would look like this:
filename <- paste0(deparse(substitute(.Last.value)), ".jpg")
filename
## [1] "my_plot.jpg"
You should be able to get it directly from the filename you're creating:
my_plot_name <- tools::file_path_sans_ext(filename)
my_plot_name
## [1] "my_plot"
Updated after edits:
.Last.value will only store the value, not the name of the variable that the value is being assigned into. First idea I'd have otherwise would be to check the names of variables in the environment to find which is equal to .Last.value. It seems to work in this simple case of your example:
my_plot <- ggplot(df, aes(x, y))+geom_point()
filename <- paste0(Filter(function(i) identical(get(i), .Last.value), ls()), ".jpg")
filename
## [1] "my_plot.jpg"

How can I save a list of ggplot with unique file names?

That's my current code for saving a list of different ggplots:
The problem is that it saves all the different plotnames (raphael_2021_022.png
and raphael_2021_023.png - which I want!) but every unique png file contains always the same ggplot (raphael_2021_023.png) even though it has a different name
names(barplots_emmeans) <-
sub("\\.xlsx$",
".png",
names(raphael_calc_sum))
> barplots_emmeans
$raphael_2021_022.png
$raphael_2021_023.png
lapply(names(barplots_emmeans),
function(nm) barplots_emmeans[[nm]] +
ggsave(filename = file.path("C:/Users/Raphael/Desktop/barplot_emmeans/",
nm )))
How can I fix that?

How to `dput` a `ggplot` object?

I am looking for a way to save some ggplot objects for later use. The dput function creates a string that when passed to dget() would return the errors of unexpected <:
The first one is here: .internal.selfref = <. This can be easily solved by setting .internal.selfref to NULL.
The remaining seven are distributed across different attributes, with the arguments being <environment>. I tried to change the <environment>'s to something like NULL or environment(), but none of them works - the environment is not set right and the object not found error is returned.
Some searches led me to the function ggedit::dput.ggedit. But it gives me the error:
# Error in sprintf("%s = %s", item, y) :
# invalid type of argument[2]: 'symbol'
I am thinking, either I set the environments right in using the dput function, or I figure out why ggedit::dput.ggedit does not work...
Any idea?
Not using dput(), but to save your ggplot objects for later use, you could save them as .rds files (just like any R objects).
Example:
my_plot <- ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
saveRDS(my_plot, "my_plot.rds")
And to restore your object in another session, another script, etc.
my_plot <- readRDS("my_plot.rds")
You can try a tidyverse
Save the plot beside the data in a tibble using nest and map.
library(tidyverse)
res <- mtcars %>%
as.tibble() %>%
nest() %>%
mutate(res=map(data, ~ggplot(.,aes(mpg, disp)) + geom_point()))
Then save the data.frame using save or saveRDS.
Finally, call the plot:
res$res
The size is 4kb for tibble(mtcars) vs. 21kb with plot.

ggplot2 - importing and plotting multiple .csv files

I have tried batch importing, but I think ggplot2 requires data frames and I have only been able to make a list of elements. I have set up a simple code in ggplot2 that imports data from multiple csv files and overlays their trendlines. All of the .csv files are in the same folder and have the same format. Is there a way to import all of the .csv files from the folder and plot all of them in ggplot without copying this code hundreds of times?
Thank you for your help!
library(ggplot2)
points1 <- read.csv("http://drive.google.com")[1:10,1:2]
points2 <- read.csv("http://drive.google.com")[1:10,1:2]
g <- (ggplot(points1, aes(x=ALPHA, y=BETA))
+labs(title="Model Run", subtitle="run4", y="LabelY", x="LabelX", caption="run4")
+ coord_cartesian(xlim=c(0,10), ylim=c(0,11))
#+ geom_point(data = points1)#
+geom_smooth(method="loess", span=.8, data = points1, se=FALSE)
#+ geom_point(data = points2)#
+geom_smooth(method="loess", span=.8, data = points2, se=FALSE))
plot(g)
This is a fun one. I am using some packages from the tidyverse (ggplot, purrr, readr) to make it more consistent.
Since you want to plot all the data in one plot, it makes sense to put all of it into one dataframe. The function purrr::map_df is perfect for this.
library(tidyverse)
files <- list.files("data/", "*.csv", full.names = T)
names(files) <- list.files("data/", "*.csv")
df <- map_df(files, ~read_csv(.), .id = "origin")
df %>% ggplot()+
aes(x,y, color = origin)+
geom_point()
A few explainations
The first two lines create a named vector with its elements being the full paths to the csv-files and the names of this vector being the filenames. This makes is easier to use the .id argument of map_df, which creates an additional column namend "origin" from the filenames. The notation inside map might seem a little weird at first, you could also supply a function written elesewhere to apply to each element but the ~ symbol is pretty handy: it creates a function right there and this function always takes the argument . as the current element of the vector or list you are iterating over.

r interpret string as list element

I generate a bunch of graphs and write them into a list variable, something like the following.
graphsListHolder <- list()
loop around the following code for as many plots as I make
filename <- paste some elements together to create a unique name
graphsListHolder[[filename]] <- p # p is the name of the ggplot plot
I save graphsListHolder as a .rds file.
Later I want to read in the res file, choose from plots in the graphsListHolder file and display with grid.arrange. I can hardcode the plot number and the following example works fine when run, plotting two graphs, one on top of the other.
grid.arrange(
graphsListHolder[[3]], graphsListHolder[[5]]
)
But if I construct a character variable temp like this (or variations on this)
temp <- "graphsListHolder[[3]], graphsListHolder[[5]]"
and change the grid.arrange code to
grid.arrange(
temp
)
I get
Error in gList(list("graphsListHolder[[3]], graphsListHolder[[5]]", wrapvp = list( :
only 'grobs' allowed in "gList"
In addition: Warning message:
In grob$wrapvp <- vp : Coercing LHS to a list
I also tried eval(parse(text = temp) without success.
I'm not sure how you want to choose them, but say you had a vector of the elements you wanted
x <- c(3,5)
Then you could do
grid.arrange(grobs=graphsListHolder[x])
Trying to turn arbitrary strings into executable code usually isn't a good idea. Often there are more "traditional" alternatives in R.
For example
graphsListHolder<-Map(function(x) {
ggplot(data.frame(x=1:10, y=x*1:10)) + geom_point(aes(x,y)) + ggtitle(x)}, 1:5)
x <- c(3,5)
grid.arrange(grobs=graphsListHolder[x])

Resources