I have this data in R:
library(ggplot2)
library(dplyr)
set.seed(123)
data <- data.frame(
height = rnorm(1000, mean = 170, sd = 10),
weight = rnorm(1000, mean = 70, sd = 15),
country = sample(c("USA", "Canada", "UK", "Australia"), 1000, replace = TRUE)
)
I use this code to make a facet of height vs weight for each country:
library(ggplot2)
library(gridExtra)
# Create separate plots for each country
p1 <- ggplot(data %>% filter(country == "USA"), aes(x = height, y = weight)) +
geom_point(alpha = 0.5) +
labs(title = "USA", x = "Height (cm)", y = "Weight (kg)") +
theme_minimal()
p2 <- ggplot(data %>% filter(country == "Canada"), aes(x = height, y = weight)) +
geom_point(alpha = 0.5) +
labs(title = "Canada", x = "Height (cm)", y = "Weight (kg)") +
theme_minimal()
p3 <- ggplot(data %>% filter(country == "UK"), aes(x = height, y = weight)) +
geom_point(alpha = 0.5) +
labs(title = "UK", x = "Height (cm)", y = "Weight (kg)") +
theme_minimal()
p4 <- ggplot(data %>% filter(country == "Australia"), aes(x = height, y = weight)) +
geom_point(alpha = 0.5) +
labs(title = "Australia", x = "Height (cm)", y = "Weight (kg)") +
theme_minimal()
grid.arrange(p1, p2, p3, p4, ncol = 2)
Is there some in R that instead of manually making all these graphs, I can automatically make each graph with the correct titles and tile them together on the same page?
Right now I am doing this manually and its taking some time (e.g. I have 20 such graphs) – is it not possible to do this automatically?
>Solution :
If you don’t want facets, the way to go is to just write your own plotting function, and apply that to the data. E.g. like so:
my_fun <- function(data, title) {
ggplot(data, aes(x = height, y = weight)) +
geom_point(alpha = 0.5) +
labs(title = title, x = "Height (cm)", y = "Weight (kg)") +
theme_minimal()
}
spl <- split(data, data$country)
my_plots <- purrr::map2(spl, names(spl), my_fun)
patchwork::wrap_plots(my_plots)
This generalizes; any time you find yourself writing lots of very similar code, you should probably applying a function instead.

