library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   4.0.0     ✔ tibble    3.3.0
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.1.0     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(purrrfect)

Attaching package: 'purrrfect'

The following objects are masked from 'package:base':

    replicate, tabulate
library(patchwork)

N <- 10000
(simstudy <- parameters(~lambda,
                        c(0.5, 1, 1.5, 2)
                        )
  %>% add_trials(N)
  %>% mutate(X = map_dbl(lambda, \(l) rexp(1, rate = l)))
  %>% mutate(Y = map_dbl(lambda, \(l) rexp(1, rate = l)))
  %>% mutate(U = X + Y)
  %>% mutate(fU = dgamma(U, shape = 2, rate = lambda))
) %>% head
# A tibble: 6 × 6
  lambda .trial     X     Y     U     fU
   <dbl>  <dbl> <dbl> <dbl> <dbl>  <dbl>
1    0.5      1 0.331 0.277 0.608 0.112 
2    0.5      2 0.357 1.73  2.09  0.184 
3    0.5      3 0.965 4.81  5.77  0.0805
4    0.5      4 1.52  7.11  8.64  0.0288
5    0.5      5 1.63  6.38  8.00  0.0366
6    0.5      6 3.09  3.07  6.16  0.0707
(ggplot(data = simstudy)
 + geom_histogram(aes(x = U, y = after_stat(density)),
                  fill = 'goldenrod', bins = 40)
 + geom_line(aes(x = U, y = fU), col = 'cornflowerblue', size = 1)
 + theme_classic(base_size = 16)
 + xlim(c(0,30))
 + facet_wrap(~lambda, scales = 'free_y', labeller = label_both)
)
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
Warning: Removed 8 rows containing missing values or values outside the scale range
(`geom_bar()`).