I have a dataset with a column storing hundreds of writing samples. My goal is to export each writing sample into a separate image. Below, my current code:
library(tidyverse)
library(ggplot2)
library(ggtext)
library(magick)
df <- data.frame(
ID = 1:2,
Sample = c("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \r\r\nUt enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
)
First, I calculate the number of characters for each writing sample (spaces between words included) to establish the text size in ggtext::geom_textbox
. This will enable users to set the same text size across all the writing samples:
max_text <- df |>
rowwise() |>
mutate(n = nchar(Sample)) |>
ungroup() |>
top_n(1, n)
p_longest_text <- ggplot(max_text, aes(label = Sample)) +
ggtext::geom_textbox(x = 0, y = 1, width = 0.9, hjust = 0, vjust = 1, size = 3, box.colour = "white") +
theme_void()
ggsave("longest_text.png", p_longest_text, width = 1000, height = 1200, units = "px", bg = "white")
After establishing an adequate text size, I can use the value (in the current toy data set is size = 3
) in the for-loop to generate one image for each writing sample. The text size will be the same across all the images:
for(i in 1:nrow(df)) {
tec <- paste0(df[i,]$ID, ".png")
p <- ggplot(df[i,], aes(label = Sample)) +
ggtext::geom_textbox(x = 0, y = 1, width = 0.9, hjust = 0, vjust = 1, size = 3, box.colour = "white") +
theme_void()
ggsave(tec, p, width = 1000, height = 1200, units = "px", bg = "white")
}
Unfortunately, two issues remain:
- I am unable to crop out the empty space. Unfortunately,
image_trim()
does not work well because it leaves no margin between the text and the cropped section.image_crop
seems more promising but I don't know how to adjust it to each image differently. - Right now, the code requires the user to manually try different text sizes to determine the value to use in the for-loop. It would be great to automatize this process so that the chunk of code can be run without a user's decision.
Any help will be appreciated!