Ilustrasi Kasus - ‘SocMed Insights’
Aplikasi analitik media sosial ‘SocMed Insights’ mengumpulkan berbagai data untuk keperluan berikut. Kerjakan tiap poin dengan perhitungan manual DAN sintaks RStudio.
Variabel acak diskrit nilainya bisa dihitung satu per satu (0, 1, 2, …), sedangkan variabel acak kontinu nilainya bisa berupa angka desimal apa pun dalam suatu rentang.
klasifikasi <- data.frame(
Variabel = c("(a) Jumlah komentar per unggahan",
"(b) Durasi video yang ditonton (detik)"),
Tipe = c("Diskrit", "Kontinu"),
Alasan = c("Hasil menghitung, berupa bilangan bulat (0, 1, 2, ...)",
"Hasil mengukur waktu, bisa desimal (mis. 12,57 detik)")
)
knitr::kable(klasifikasi)
| Variabel | Tipe | Alasan |
|---|---|---|
| (a) Jumlah komentar per unggahan | Diskrit | Hasil menghitung, berupa bilangan bulat (0, 1, 2, …) |
| (b) Durasi video yang ditonton (detik) | Kontinu | Hasil mengukur waktu, bisa desimal (mis. 12,57 detik) |
Kesimpulan: jumlah komentar adalah variabel acak diskrit (dihitung), sedangkan durasi video yang ditonton adalah variabel acak kontinu (diukur).
Data di bawah ini adalah data simulasi (bukan data asli) untuk memperlihatkan perbedaan sifat kedua variabel.
set.seed(123)
komentar <- rpois(200, lambda = 4) # data hitungan (diskrit)
durasi <- rnorm(200, mean = 45, sd = 10) # data ukuran (kontinu)
# 6 data pertama
head(komentar)
## [1] 3 6 3 6 7 1
round(head(durasi), 2)
## [1] 37.90 47.57 42.53 41.52 35.48 44.55
# Apakah semua nilai komentar bilangan bulat?
all(komentar == floor(komentar))
## [1] TRUE
# Banyak nilai yang berbeda (dari 200 data)
c(komentar = length(unique(komentar)), durasi = length(unique(durasi)))
## komentar durasi
## 11 200
Jumlah komentar hanya muncul pada sedikit nilai bulat yang bisa didaftar, sedangkan durasi hampir selalu menghasilkan nilai desimal yang berbeda-beda.
op <- par(mfrow = c(1, 2))
barplot(table(komentar), col = "steelblue", cex.names = 0.8,
main = "Jumlah Komentar (Diskrit)",
xlab = "Jumlah komentar", ylab = "Frekuensi")
hist(durasi, breaks = 15, freq = FALSE, col = "orange", border = "white",
main = "Durasi Tonton (Kontinu)",
xlab = "Durasi (detik)", ylab = "Kepekatan")
lines(density(durasi), lwd = 2, col = "darkred")
par(op)
Diketahui: peluang klik iklan \(p = 0{,}25\) dan iklan ditampilkan ke \(n = 10\) pengguna. Ditanya: P(X = 2), rata-rata, dan SD jumlah klik.
Syarat binomial terpenuhi: n tetap (10), tiap pengguna hanya punya 2 hasil (klik atau tidak), p konstan (0,25), dan antarpengguna saling bebas.
Rumus:
\[P(X=x)=\binom{n}{x}p^x(1-p)^{n-x}, \qquad E(X)=np, \qquad Var(X)=np(1-p)\]
Tabel ini setara dengan Tabel Binomial (n = 10, p = 0,25) di materi.
n <- 10
p <- 0.25
x <- 0:n
tabel_binom <- data.frame(
x = x,
`P(X = x)` = round(dbinom(x, n, p), 4),
`P(X <= x)` = round(pbinom(x, n, p), 4),
check.names = FALSE
)
knitr::kable(tabel_binom, align = "c")
| x | P(X = x) | P(X <= x) |
|---|---|---|
| 0 | 0.0563 | 0.0563 |
| 1 | 0.1877 | 0.2440 |
| 2 | 0.2816 | 0.5256 |
| 3 | 0.2503 | 0.7759 |
| 4 | 0.1460 | 0.9219 |
| 5 | 0.0584 | 0.9803 |
| 6 | 0.0162 | 0.9965 |
| 7 | 0.0031 | 0.9996 |
| 8 | 0.0004 | 1.0000 |
| 9 | 0.0000 | 1.0000 |
| 10 | 0.0000 | 1.0000 |
# Langkah manual satu per satu
komb <- choose(n, 2) # C(10,2)
pangkat_p <- p^2 # (0,25)^2
pangkat_q <- (1 - p)^(n - 2) # (0,75)^8
data.frame(Komponen = c("C(10,2)", "(0,25)^2", "(0,75)^8"),
Nilai = c(komb, pangkat_p, pangkat_q))
## Komponen Nilai
## 1 C(10,2) 45.0000000
## 2 (0,25)^2 0.0625000
## 3 (0,75)^8 0.1001129
manual_2 <- komb * pangkat_p * pangkat_q
manual_2
## [1] 0.2815676
# Verifikasi dengan fungsi bawaan R
p_tepat2 <- dbinom(2, size = n, prob = p)
# Cara baca tabel kumulatif: P(X=2) = P(X<=2) - P(X<=1)
via_tabel <- pbinom(2, n, p) - pbinom(1, n, p)
data.frame(Cara = c("Manual (rumus)", "dbinom()", "Selisih kumulatif tabel"),
Hasil = round(c(manual_2, p_tepat2, via_tabel), 4))
## Cara Hasil
## 1 Manual (rumus) 0.2816
## 2 dbinom() 0.2816
## 3 Selisih kumulatif tabel 0.2816
rata2 <- n * p
varians <- n * p * (1 - p)
sd_klik <- sqrt(varians)
data.frame(Ukuran = c("Rata-rata E(X) = np", "Varians = np(1-p)", "SD = akar varians"),
Nilai = round(c(rata2, varians, sd_klik), 4))
## Ukuran Nilai
## 1 Rata-rata E(X) = np 2.5000
## 2 Varians = np(1-p) 1.8750
## 3 SD = akar varians 1.3693
Kita simulasikan 100.000 kali iklan ditampilkan ke 10 pengguna. Jika perhitungan benar, hasil simulasi harus mendekati hasil teori.
set.seed(2026)
sim_klik <- rbinom(100000, size = n, prob = p)
data.frame(Ukuran = c("P(X = 2)", "Rata-rata", "SD"),
Teori = round(c(p_tepat2, rata2, sd_klik), 4),
Simulasi = round(c(mean(sim_klik == 2), mean(sim_klik), sd(sim_klik)), 4))
## Ukuran Teori Simulasi
## 1 P(X = 2) 0.2816 0.2808
## 2 Rata-rata 2.5000 2.5057
## 3 SD 1.3693 1.3737
P(tepat 2 pengguna klik) = 0.2816, yaitu sekitar 28.16%.
Rata-rata jumlah klik = 2.5 pengguna dari 10 pengguna.
SD jumlah klik = 1.3693 pengguna, artinya jumlah klik biasanya menyimpang sekitar 1 sampai 2 pengguna dari rata-rata.
op <- par(mfrow = c(1, 2))
# Grafik 1: PMF
warna <- ifelse(x == 2, "firebrick", "steelblue")
bp <- barplot(dbinom(x, n, p), names.arg = x, col = warna, cex.names = 0.8,
ylim = c(0, max(dbinom(x, n, p)) + 0.07),
main = "PMF Binomial (n = 10, p = 0,25)",
xlab = "Jumlah pengguna yang mengklik (x)", ylab = "P(X = x)")
text(bp, dbinom(x, n, p), labels = round(dbinom(x, n, p), 3), pos = 3, cex = 0.7)
# posisi rata-rata (2,5) pada sumbu barplot
pos_rata <- bp[1] + (bp[2] - bp[1]) * rata2
abline(v = pos_rata, lty = 2, lwd = 2)
text(pos_rata, max(dbinom(x, n, p)) + 0.06, "rata-rata = 2,5", pos = 4, cex = 0.8)
legend("right", legend = c("P(X = 2)", "Nilai lain"),
fill = c("firebrick", "steelblue"), bty = "n", cex = 0.85)
# Grafik 2: CDF (kumulatif)
plot(x, pbinom(x, n, p), type = "s", lwd = 2, col = "darkgreen",
main = "Peluang Kumulatif P(X <= x)",
xlab = "Jumlah pengguna yang mengklik (x)", ylab = "P(X <= x)")
points(x, pbinom(x, n, p), pch = 19, col = "darkgreen")
abline(h = pbinom(2, n, p), lty = 3, col = "gray40")
text(8, pbinom(2, n, p) + 0.04,
paste0("P(X <= 2) = ", round(pbinom(2, n, p), 4)), cex = 0.8)
par(op)
Diketahui: rata-rata unggahan foto \(\lambda = 8\) per menit. Ditanya: (a) P(X = 5) secara manual, (b) P(X > 12) dengan RStudio.
Rumus:
\[P(X=x)=\frac{e^{-\lambda}\lambda^x}{x!}, \qquad E(X)=Var(X)=\lambda\]
Tabel ini setara dengan Tabel Poisson (\(\lambda\) = 8) di materi.
lambda <- 8
x <- 0:20
tabel_pois <- data.frame(
x = x,
`P(X = x)` = round(dpois(x, lambda), 4),
`P(X <= x)` = round(ppois(x, lambda), 4),
check.names = FALSE
)
knitr::kable(tabel_pois, align = "c")
| x | P(X = x) | P(X <= x) |
|---|---|---|
| 0 | 0.0003 | 0.0003 |
| 1 | 0.0027 | 0.0030 |
| 2 | 0.0107 | 0.0138 |
| 3 | 0.0286 | 0.0424 |
| 4 | 0.0573 | 0.0996 |
| 5 | 0.0916 | 0.1912 |
| 6 | 0.1221 | 0.3134 |
| 7 | 0.1396 | 0.4530 |
| 8 | 0.1396 | 0.5925 |
| 9 | 0.1241 | 0.7166 |
| 10 | 0.0993 | 0.8159 |
| 11 | 0.0722 | 0.8881 |
| 12 | 0.0481 | 0.9362 |
| 13 | 0.0296 | 0.9658 |
| 14 | 0.0169 | 0.9827 |
| 15 | 0.0090 | 0.9918 |
| 16 | 0.0045 | 0.9963 |
| 17 | 0.0021 | 0.9984 |
| 18 | 0.0009 | 0.9993 |
| 19 | 0.0004 | 0.9997 |
| 20 | 0.0002 | 0.9999 |
# Langkah manual, ditulis satu per satu
e_min_lambda <- exp(-lambda) # e^-8
lambda_pangkat <- lambda^5 # 8^5
faktorial <- factorial(5) # 5!
data.frame(Komponen = c("e^-8", "8^5", "5!"),
Nilai = c(e_min_lambda, lambda_pangkat, faktorial))
## Komponen Nilai
## 1 e^-8 3.354626e-04
## 2 8^5 3.276800e+04
## 3 5! 1.200000e+02
hasil_manual <- e_min_lambda * lambda_pangkat / faktorial
hasil_manual
## [1] 0.09160366
# Verifikasi dengan fungsi bawaan R
dpois(5, lambda)
## [1] 0.09160366
# Cara baca tabel kumulatif: P(X=5) = P(X<=5) - P(X<=4)
ppois(5, lambda) - ppois(4, lambda)
## [1] 0.09160366
Hasil: P(X = 5) = 0.0916, yaitu sekitar 9.16%.
\[P(X>12) = 1 - P(X \le 12)\]
p_kurang12 <- ppois(12, lambda) # P(X <= 12)
p_kurang12
## [1] 0.9362028
# Cara 1: komplemen
p_lebih12 <- 1 - ppois(12, lambda)
p_lebih12
## [1] 0.0637972
# Cara 2: argumen lower.tail
ppois(12, lambda, lower.tail = FALSE)
## [1] 0.0637972
# Cara 3: jumlahkan peluang 0 sampai 12, lalu komplemen
1 - sum(dpois(0:12, lambda))
## [1] 0.0637972
# Cara 4: jumlahkan langsung peluang 13 sampai batas besar
sum(dpois(13:100, lambda))
## [1] 0.0637972
Peluang server menerima lebih dari 12 unggahan dalam semenit hanya 0.0638 (sekitar 6.38%), jadi tergolong jarang terjadi.
set.seed(2026)
sim_unggah <- rpois(100000, lambda = lambda)
data.frame(Ukuran = c("P(X = 5)", "P(X > 12)", "Rata-rata", "Varians"),
Teori = round(c(hasil_manual, p_lebih12, lambda, lambda), 4),
Simulasi = round(c(mean(sim_unggah == 5), mean(sim_unggah > 12),
mean(sim_unggah), var(sim_unggah)), 4))
## Ukuran Teori Simulasi
## 1 P(X = 5) 0.0916 0.0913
## 2 P(X > 12) 0.0638 0.0645
## 3 Rata-rata 8.0000 8.0139
## 4 Varians 8.0000 8.0635
op <- par(mfrow = c(1, 2))
# Grafik 1: PMF
warna <- ifelse(x == 5, "firebrick", ifelse(x > 12, "darkorange", "steelblue"))
barplot(dpois(x, lambda), names.arg = x, col = warna, cex.names = 0.7,
main = "PMF Poisson (\u03bb = 8)",
xlab = "Jumlah unggahan foto per menit (x)", ylab = "P(X = x)")
legend("topright", legend = c("P(X = 5)", "P(X > 12)", "Lainnya"),
fill = c("firebrick", "darkorange", "steelblue"), bty = "n", cex = 0.8)
# Grafik 2: CDF
plot(x, ppois(x, lambda), type = "s", lwd = 2, col = "darkgreen",
main = "Peluang Kumulatif P(X <= x)",
xlab = "Jumlah unggahan foto per menit (x)", ylab = "P(X <= x)")
points(x, ppois(x, lambda), pch = 19, col = "darkgreen")
abline(v = 12, lty = 2, col = "darkorange", lwd = 2)
abline(h = ppois(12, lambda), lty = 3, col = "gray40")
text(16.5, 0.5,
paste0("P(X <= 12) = ", round(ppois(12, lambda), 4), "\nP(X > 12) = ",
round(p_lebih12, 4)), cex = 0.8)
par(op)
Diketahui: waktu muat halaman ~ Normal dengan \(\mu = 3\) detik dan \(\sigma = 0{,}5\) detik. Ditanya: (a) P(loading > 4 detik), (b) batas waktu 5% loading terlama.
Standardisasi:
\[Z=\frac{X-\mu}{\sigma}=\frac{4-3}{0{,}5}=2\]
Jadi P(X > 4) = P(Z > 2) = 1 - P(Z \(\le\) 2).
mu <- 3
sigma <- 0.5
z_hit <- (4 - mu) / sigma
z_hit
## [1] 2
# Nilai tabel Z: Phi(2,00)
phi_2 <- pnorm(z_hit)
round(phi_2, 4)
## [1] 0.9772
# Lewat nilai Z baku (sama dengan membaca Tabel Z)
1 - phi_2
## [1] 0.02275013
# Langsung dari distribusi aslinya (hasil harus sama)
p_lebih4 <- 1 - pnorm(4, mean = mu, sd = sigma)
p_lebih4
## [1] 0.02275013
# Dengan argumen lower.tail
pnorm(4, mean = mu, sd = sigma, lower.tail = FALSE)
## [1] 0.02275013
Hasil: P(loading > 4 detik) = 0.0228 atau sekitar 2.28%.
Kita mencari nilai \(x\) sehingga P(X > x) = 0,05, atau P(X \(\le\) x) = 0,95.
Pada Tabel Z, nilai 0,95 berada di antara Z = 1,64 dan Z = 1,65:
data.frame(Z = c(1.64, 1.65),
`Phi(Z)` = round(pnorm(c(1.64, 1.65)), 4),
check.names = FALSE)
## Z Phi(Z)
## 1 1.64 0.9495
## 2 1.65 0.9505
Nilai 0,9500 tepat di tengah keduanya, sehingga \(Z \approx 1{,}645\). Maka:
\[X=\mu+Z\sigma = 3 + 1{,}645(0{,}5) = 3{,}8225\]
z_batas <- qnorm(0.95)
z_batas
## [1] 1.644854
batas <- mu + z_batas * sigma # manual dari rumus
batas
## [1] 3.822427
qnorm(0.95, mean = mu, sd = sigma) # verifikasi langsung
## [1] 3.822427
# Cek balik: peluang di atas batas harus tepat 5%
1 - pnorm(batas, mean = mu, sd = sigma)
## [1] 0.05
Halaman yang waktu muatnya lebih dari 3.8224 detik termasuk 5% loading terlama.
set.seed(2026)
sim_load <- rnorm(100000, mean = mu, sd = sigma)
data.frame(Ukuran = c("P(loading > 4)", "Batas 5% terlama"),
Teori = round(c(p_lebih4, batas), 4),
Simulasi = round(c(mean(sim_load > 4), quantile(sim_load, 0.95)), 4),
row.names = NULL)
## Ukuran Teori Simulasi
## 1 P(loading > 4) 0.0228 0.0232
## 2 Batas 5% terlama 3.8224 3.8225
aturan <- data.frame(
Rentang = c("mu +/- 1 sigma", "mu +/- 2 sigma", "mu +/- 3 sigma"),
Batas = c("2,5 - 3,5", "2,0 - 4,0", "1,5 - 4,5"),
Peluang = round(c(pnorm(1) - pnorm(-1),
pnorm(2) - pnorm(-2),
pnorm(3) - pnorm(-3)), 4)
)
knitr::kable(aturan)
| Rentang | Batas | Peluang |
|---|---|---|
| mu +/- 1 sigma | 2,5 - 3,5 | 0.6827 |
| mu +/- 2 sigma | 2,0 - 4,0 | 0.9545 |
| mu +/- 3 sigma | 1,5 - 4,5 | 0.9973 |
Ini menjelaskan hasil (a): 4 detik berada tepat di \(\mu + 2\sigma\), dan sisa di ekor kanan adalah (1 - 0,9545)/2, kira-kira 0,0228.
x <- seq(1, 5, length.out = 500)
y <- dnorm(x, mean = mu, sd = sigma)
op <- par(mfrow = c(1, 2))
# Grafik 1: P(X > 4)
plot(x, y, type = "l", lwd = 2, main = "P(loading > 4 detik)",
xlab = "Waktu muat (detik)", ylab = "Kepekatan f(x)")
xs <- seq(4, 5, length.out = 100)
polygon(c(4, xs, 5), c(0, dnorm(xs, mu, sigma), 0),
col = rgb(1, 0, 0, 0.4), border = NA)
abline(v = mu, lty = 2)
text(4.45, 0.3, paste0("Luas = ", round(p_lebih4, 4)), cex = 0.85)
arrows(4.45, 0.26, 4.35, 0.04, length = 0.08)
# Grafik 2: batas 5% terlama
plot(x, y, type = "l", lwd = 2, main = "Batas 5% loading terlama",
xlab = "Waktu muat (detik)", ylab = "Kepekatan f(x)")
xs <- seq(batas, 5, length.out = 100)
polygon(c(batas, xs, 5), c(0, dnorm(xs, mu, sigma), 0),
col = rgb(0, 0, 1, 0.4), border = NA)
abline(v = batas, col = "blue", lwd = 2)
text(3.9, 0.45, paste0("x = ", round(batas, 3), " detik"),
col = "blue", cex = 0.75, adj = 0)
text(3.9, 0.38, "luas kanan = 5%", col = "blue", cex = 0.72, adj = 0)
par(op)
Grafik berikut menunjukkan hal yang sama pada skala Z (distribusi normal baku), sesuai cara membaca Tabel Z:
z <- seq(-4, 4, length.out = 500)
fz <- dnorm(z)
plot(z, fz, type = "l", lwd = 2,
main = "Distribusi Normal Baku (Z)",
xlab = "Z", ylab = "Kepekatan")
zs <- seq(2, 4, length.out = 100)
polygon(c(2, zs, 4), c(0, dnorm(zs), 0), col = rgb(1, 0, 0, 0.4), border = NA)
zs <- seq(z_batas, 4, length.out = 100)
polygon(c(z_batas, zs, 4), c(0, dnorm(zs), 0), col = rgb(0, 0, 1, 0.3), border = NA)
abline(v = c(2, z_batas), lty = 2, col = c("red", "blue"))
legend("topleft",
legend = c("Z = 2 (X = 4 detik)", "Z = 1,645 (X = 3,8224 detik)"),
lty = 2, col = c("red", "blue"), bty = "n", cex = 0.85)
Blok ini membandingkan hasil hitungan dengan nilai yang diharapkan (sesuai tabel dan perhitungan manual). Jika ada yang tidak cocok, proses knit akan berhenti dengan pesan error.
cek <- c(
"Soal 2: manual = dbinom" = isTRUE(all.equal(manual_2, p_tepat2)),
"Soal 2: P(X=2) = 0,2816" = round(p_tepat2, 4) == 0.2816,
"Soal 2: rata-rata = 2,5" = rata2 == 2.5,
"Soal 2: SD = 1,3693" = round(sd_klik, 4) == 1.3693,
"Soal 3: manual = dpois" = isTRUE(all.equal(hasil_manual, dpois(5, lambda))),
"Soal 3: P(X=5) = 0,0916" = round(hasil_manual, 4) == 0.0916,
"Soal 3: P(X<=12) = 0,9362" = round(p_kurang12, 4) == 0.9362,
"Soal 3: P(X>12) = 0,0638" = round(p_lebih12, 4) == 0.0638,
"Soal 4: Z = 2" = z_hit == 2,
"Soal 4: P(>4 detik) = 0,0228" = round(p_lebih4, 4) == 0.0228,
"Soal 4: batas = 3,8224" = round(batas, 4) == 3.8224
)
stopifnot(all(cek))
data.frame(Pengecekan = names(cek),
Hasil = ifelse(cek, "Sesuai", "TIDAK SESUAI"),
row.names = NULL)
## Pengecekan Hasil
## 1 Soal 2: manual = dbinom Sesuai
## 2 Soal 2: P(X=2) = 0,2816 Sesuai
## 3 Soal 2: rata-rata = 2,5 Sesuai
## 4 Soal 2: SD = 1,3693 Sesuai
## 5 Soal 3: manual = dpois Sesuai
## 6 Soal 3: P(X=5) = 0,0916 Sesuai
## 7 Soal 3: P(X<=12) = 0,9362 Sesuai
## 8 Soal 3: P(X>12) = 0,0638 Sesuai
## 9 Soal 4: Z = 2 Sesuai
## 10 Soal 4: P(>4 detik) = 0,0228 Sesuai
## 11 Soal 4: batas = 3,8224 Sesuai
rekap <- data.frame(
No = c("1", "2", "2", "2", "3", "3", "4", "4"),
Pertanyaan = c("Tipe variabel (a) dan (b)",
"P(tepat 2 klik)", "Rata-rata klik", "SD klik",
"P(tepat 5 unggahan)", "P(lebih dari 12 unggahan)",
"P(loading > 4 detik)", "Batas 5% terlama (detik)"),
Jawaban = c("(a) Diskrit, (b) Kontinu",
sprintf("%.4f", p_tepat2), sprintf("%.1f", rata2), sprintf("%.4f", sd_klik),
sprintf("%.4f", hasil_manual), sprintf("%.4f", p_lebih12),
sprintf("%.4f", p_lebih4), sprintf("%.4f", batas))
)
knitr::kable(rekap)
| No | Pertanyaan | Jawaban |
|---|---|---|
| 1 | Tipe variabel (a) dan (b) | (a) Diskrit, (b) Kontinu |
| 2 | P(tepat 2 klik) | 0.2816 |
| 2 | Rata-rata klik | 2.5 |
| 2 | SD klik | 1.3693 |
| 3 | P(tepat 5 unggahan) | 0.0916 |
| 3 | P(lebih dari 12 unggahan) | 0.0638 |
| 4 | P(loading > 4 detik) | 0.0228 |
| 4 | Batas 5% terlama (detik) | 3.8224 |
sessionInfo()
## R version 4.6.1 (2026-06-24 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26200)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=English_Indonesia.utf8 LC_CTYPE=English_Indonesia.utf8
## [3] LC_MONETARY=English_Indonesia.utf8 LC_NUMERIC=C
## [5] LC_TIME=English_Indonesia.utf8
##
## time zone: Asia/Jakarta
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## loaded via a namespace (and not attached):
## [1] digest_0.6.39 R6_2.6.1 fastmap_1.2.0 xfun_0.60
## [5] cachem_1.1.0 knitr_1.52 htmltools_0.5.9 rmarkdown_2.32
## [9] lifecycle_1.0.5 cli_3.6.6 sass_0.4.10 jquerylib_0.1.4
## [13] compiler_4.6.1 rstudioapi_0.19.0 tools_4.6.1 evaluate_1.0.5
## [17] bslib_0.12.0 yaml_2.3.12 otel_0.2.0 jsonlite_2.0.0
## [21] rlang_1.3.0