35- DML gene-model figure (Table 2)
================
Steven Roberts
11 June, 2026
- [1 Overview](#1-overview)
- [2 Download the NCBI GFF
annotation](#2-download-the-ncbi-gff-annotation)
- [3 Parse gene models](#3-parse-gene-models)
- [4 DML set (Table 2) and coordinate
verification](#4-dml-set-table-2-and-coordinate-verification)
- [5 Build the figure](#5-build-the-figure)
- [6 Summary table](#6-summary-table)
- [7 Session info](#7-session-info)
------------------------------------------------------------------------
# 1 Overview
Publication-quality, multi-panel figure of the **10 annotated gene
models** that harbor the 12 differentially methylated loci (DMLs)
reported in `paper.md` Table 2, with each DML denoted on its gene model.
Companion to `30-dml-dmr-methylkit.Rmd` and `31-dml-dmr-annotation.Rmd`.
- DML headline set: `../output/11-methylkit-klone/myDiff_1055p.tab`
(methylKit, q<0.01, \|meth.diff\|>=55%; positions are 1-based
CpG coordinates)
- Reference: NCBI **GCF\_036588685.1** (PNRI\_Mtr1.1.1.hap1)
- Annotation: downloaded NCBI GFF (this script)
- Output dir: `../output/35-dml-gene-model-figure/`
`rtracklayer`/`GenomicFeatures` are not installed in this environment,
so the GFF is parsed directly with `data.table`/`awk`.
``` bash
mkdir -p ../output/35-dml-gene-model-figure
```
# 2 Download the NCBI GFF annotation
Downloads `GCF_036588685.1_..._genomic.gff` from the NCBI FTP if not
already present, then carves out the lines for the 10 genes of interest
so the rest of the script stays fast and reproducible.
``` bash
out="../output/35-dml-gene-model-figure"
gff="$out/genomic.gff"
if [ ! -s "$gff" ]; then
url="https://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/036/588/685/GCF_036588685.1_PNRI_Mtr1.1.1.hap1/GCF_036588685.1_PNRI_Mtr1.1.1.hap1_genomic.gff.gz"
curl -sS -L -o "$gff.gz" "$url"
gunzip -f "$gff.gz"
fi
ls -la "$gff"
```
## -rw-r--r--@ 1 sr320 staff 331324929 Jun 11 06:52 ../output/35-dml-gene-model-figure/genomic.gff
``` bash
out="../output/35-dml-gene-model-figure"
awk -F'\t' '
BEGIN{ s="LOC134725187 LOC134690221 LOC134714536 LOC134695637 LOC134707074 LOC134720671 LOC134711256 LOC134685297 LOC134712818 LOC134724475 LOC134687110 LOC134687290";
n=split(s,g," "); for(i=1;i<=n;i++) want[g[i]]=1 }
/^#/{next}
{ if(match($9,/gene=[^;]+/)){ gname=substr($9,RSTART+5,RLENGTH-5); if(gname in want) print } }
' "$out/genomic.gff" > "$out/gene_models_raw.gff"
echo "feature lines: $(wc -l < "$out/gene_models_raw.gff")"
cut -f3 "$out/gene_models_raw.gff" | sort | uniq -c
```
## feature lines: 1269
## 596 CDS
## 624 exon
## 12 gene
## 37 mRNA
# 3 Parse gene models
``` r
library(data.table)
library(dplyr)
library(ggplot2)
library(patchwork)
out_dir <- "../output/35-dml-gene-model-figure"
raw <- fread(file.path(out_dir, "gene_models_raw.gff"), sep = "\t", header = FALSE,
quote = "", col.names = c("chr","src","type","start","end",
"score","strand","frame","attr"))
get_attr <- function(attr, key) {
out <- rep(NA_character_, length(attr))
m <- regexpr(paste0(key, "=[^;]+"), attr)
hit <- m > 0
out[hit] <- sub(paste0(key, "="), "", regmatches(attr, m))
out
}
raw[, gene := get_attr(attr, "gene")]
raw[, ID := get_attr(attr, "ID")]
raw[, Parent := get_attr(attr, "Parent")]
raw[, product := get_attr(attr, "product")]
raw[, description := get_attr(attr, "description")]
genes <- raw[type == "gene",
.(gene, chr, start, end, strand,
gene_desc = description, gene_id_full = ID)]
mrna <- raw[type == "mRNA",
.(gene, tx = ID, chr, start, end, strand, product)]
# exon / CDS counts per transcript to help pick the primary isoform
exon_counts <- raw[type == "exon", .N, by = .(tx = Parent)]
setnames(exon_counts, "N", "n_exon")
mrna <- merge(mrna, exon_counts, by = "tx", all.x = TRUE)
mrna[, span := end - start]
# Primary transcript = longest genomic span, tie-break by most exons, then ID
setorder(mrna, gene, -span, -n_exon, tx)
primary <- mrna[, .SD[1], by = gene]
primary[]
```
## gene tx chr start end strand
##
## 1: LOC134685297 rna-XM_063544925.1 NC_086381.1 21116727 21261455 -
## 2: LOC134687110 rna-XM_063547109.1 NC_086382.1 25951921 25959192 +
## 3: LOC134687290 rna-XM_063547445.1 NC_086382.1 36708321 36799106 +
## 4: LOC134690221 rna-XM_063550200.1 NC_086373.1 90602585 90632630 +
## 5: LOC134695637 rna-XM_063556955.1 NC_086373.1 105380391 105513502 -
## 6: LOC134707074 rna-XM_063566562.1 NC_086374.1 34630047 34756161 -
## 7: LOC134711256 rna-XM_063571761.1 NC_086375.1 31935064 31941257 -
## 8: LOC134712818 rna-XM_063574731.1 NC_086375.1 90867638 90891015 +
## 9: LOC134714536 rna-XM_063575859.1 NC_086376.1 5626113 5639140 +
## 10: LOC134720671 rna-XM_063583078.1 NC_086378.1 6588729 6697712 +
## 11: LOC134724475 rna-XM_063587507.1 NC_086379.1 1585149 1617685 +
## 12: LOC134725187 rna-XM_063588806.1 NC_086379.1 47959226 47965210 -
## product
##
## 1: tumor protein p53-inducible protein 11-like%2C transcript variant X4
## 2: alpha-ketoglutarate-dependent dioxygenase alkB homolog 3-like
## 3: mitogen-activated protein kinase kinase kinase 5-like
## 4: GRAM domain-containing protein 4-like
## 5: otoferlin-like%2C transcript variant X1
## 6: receptor-type tyrosine-protein phosphatase N2-like%2C transcript variant X1
## 7: cancer-related nucleoside-triphosphatase homolog%2C transcript variant X1
## 8: uncharacterized LOC134712818
## 9: coatomer subunit epsilon-like
## 10: roundabout homolog 1-like%2C transcript variant X2
## 11: uncharacterized LOC134724475%2C transcript variant X1
## 12: membrane protein BRI3-like
## n_exon span
##
## 1: 7 144728
## 2: 7 7271
## 3: 42 90785
## 4: 18 30045
## 5: 45 133111
## 6: 21 126114
## 7: 6 6193
## 8: 16 23377
## 9: 11 13027
## 10: 26 108983
## 11: 9 32536
## 12: 4 5984
``` r
prim_tx <- primary$tx
exons <- raw[type == "exon" & Parent %in% prim_tx,
.(gene, tx = Parent, start, end, strand)]
cds <- raw[type == "CDS" & Parent %in% prim_tx,
.(gene, tx = Parent, start, end, strand)]
# attach gene to features via primary transcript map
tx2gene <- setNames(primary$gene, primary$tx)
exons[, gene := tx2gene[tx]]
cds[, gene := tx2gene[tx]]
cat("exons per primary transcript:\n"); print(exons[, .N, by = gene])
```
## exons per primary transcript:
## gene N
##
## 1: LOC134690221 18
## 2: LOC134695637 45
## 3: LOC134707074 21
## 4: LOC134711256 6
## 5: LOC134712818 16
## 6: LOC134714536 11
## 7: LOC134720671 26
## 8: LOC134724475 9
## 9: LOC134725187 4
## 10: LOC134685297 7
## 11: LOC134687110 7
## 12: LOC134687290 42
# 4 DML set (Table 2) and coordinate verification
The 12 DMLs of Table 2 are pulled from `myDiff_1055p.tab` by matching
q-values, then each is checked for containment within its assigned gene
span.
``` r
# Corrected genic DML set: 12 DMLs, each inside a unique gene (see
# 35a-dml-assignment-audit.R). The two intergenic loci previously assigned to
# LOC134725187 / LOC134711256 are dropped, and the two genic loci on
# NC_086382.1 (LOC134687110 alkB, LOC134687290 MAP3K5/ASK1) are added.
dml <- data.table(
qvalue = c(5.77e-14, 1.16e-11, 2.92e-13, 4.17e-14, 1.10e-13,
7.20e-13, 8.98e-18, 1.06e-12, 1.32e-13, 2.52e-16,
6.02e-14, 5.83e-13),
chr = c("NC_086379.1","NC_086373.1","NC_086376.1","NC_086373.1","NC_086374.1",
"NC_086378.1","NC_086375.1","NC_086381.1","NC_086375.1","NC_086379.1",
"NC_086382.1","NC_086382.1"),
pos = c(47961734, 90626338, 5631156, 105503509, 34742951,
6633121, 31938079, 21212100, 90876604, 1603830,
25952234, 36708761),
assigned_gene= c("LOC134725187","LOC134690221","LOC134714536","LOC134695637","LOC134707074",
"LOC134720671","LOC134711256","LOC134685297","LOC134712818","LOC134724475",
"LOC134687110","LOC134687290"),
meth_diff = c(56.45, 56.32, 59, -57.86, 58.27,
-55.24, -60.69, -56.07, 55.88, -60.82,
-55.83, -56.50),
status_paper = c("Hyper","Hyper","Hyper","Hypo","Hyper",
"Hypo","Hypo","Hypo","Hyper","Hypo",
"Hypo","Hypo")
)
# direction from the sign of meth.diff (hyper = +, hypo = -)
dml[, direction := factor(ifelse(meth_diff >= 0, "Hyper-methylated", "Hypo-methylated"),
levels = c("Hyper-methylated", "Hypo-methylated"))]
# verify each DML against its assigned gene span
gspan <- genes[, .(assigned_gene = gene, g_chr = chr, g_start = start,
g_end = end, g_strand = strand, gene_desc)]
dml <- merge(dml, gspan, by = "assigned_gene", all.x = TRUE, sort = FALSE)
dml[, in_gene_span := (chr == g_chr & pos >= g_start & pos <= g_end)]
dml[, .(assigned_gene, chr, pos, meth_diff, direction, status_paper,
g_start, g_end, in_gene_span)][order(assigned_gene, pos)]
```
## assigned_gene chr pos meth_diff direction status_paper
##
## 1: LOC134685297 NC_086381.1 21212100 -56.07 Hypo-methylated Hypo
## 2: LOC134687110 NC_086382.1 25952234 -55.83 Hypo-methylated Hypo
## 3: LOC134687290 NC_086382.1 36708761 -56.50 Hypo-methylated Hypo
## 4: LOC134690221 NC_086373.1 90626338 56.32 Hyper-methylated Hyper
## 5: LOC134695637 NC_086373.1 105503509 -57.86 Hypo-methylated Hypo
## 6: LOC134707074 NC_086374.1 34742951 58.27 Hyper-methylated Hyper
## 7: LOC134711256 NC_086375.1 31938079 -60.69 Hypo-methylated Hypo
## 8: LOC134712818 NC_086375.1 90876604 55.88 Hyper-methylated Hyper
## 9: LOC134714536 NC_086376.1 5631156 59.00 Hyper-methylated Hyper
## 10: LOC134720671 NC_086378.1 6633121 -55.24 Hypo-methylated Hypo
## 11: LOC134724475 NC_086379.1 1603830 -60.82 Hypo-methylated Hypo
## 12: LOC134725187 NC_086379.1 47961734 56.45 Hyper-methylated Hyper
## g_start g_end in_gene_span
##
## 1: 21116727 21261455 TRUE
## 2: 25951921 25959192 TRUE
## 3: 36708321 36799106 TRUE
## 4: 90602585 90632630 TRUE
## 5: 105380391 105513502 TRUE
## 6: 34630047 34756161 TRUE
## 7: 31935064 31941257 TRUE
## 8: 90867638 90891015 TRUE
## 9: 5626113 5639140 TRUE
## 10: 6588729 6697712 TRUE
## 11: 1585149 1617687 TRUE
## 12: 47959226 47965210 TRUE
``` r
cat("DMLs inside their assigned gene span:", sum(dml$in_gene_span), "of", nrow(dml), "\n\n")
```
## DMLs inside their assigned gene span: 12 of 12
``` r
cat("DMLs NOT inside assigned gene span:\n")
```
## DMLs NOT inside assigned gene span:
``` r
print(dml[in_gene_span == FALSE, .(assigned_gene, chr, pos, meth_diff)])
```
## Empty data.table (0 rows and 4 cols): assigned_gene,chr,pos,meth_diff
**Note.** This is the **corrected** DML set (see
`35a-dml-assignment-audit.R`). All 12 DMLs fall cleanly inside a unique
gene body — i.e. 12 DMLs across 12 genes, none bidirectional. An earlier
version of the manuscript Table 2 assigned two intergenic loci
(`NC_086379.1:64017640` and `NC_086375.1:43581688`, \~16 Mb / \~11 Mb
from their listed genes) to LOC134725187 and LOC134711256, making them
appear bidirectional, while omitting two genuinely genic loci on
NC\_086382.1 (LOC134687110 *alkB homolog 3-like* and LOC134687290
*MAP3K5 / ASK1-like*). The intergenic loci are dropped here and the two
genic loci added.
# 5 Build the figure
``` r
# warm = hyper, cool = hypo
dml_cols <- c("Hyper-methylated" = "#D6604D", "Hypo-methylated" = "#2166AC")
feat_cols <- c("CDS" = "grey25", "UTR (exon)" = "grey75")
short_name <- function(desc) {
desc <- sub(", transcript variant.*$", "", desc)
desc
}
build_panel <- function(gid) {
g <- genes[gene == gid]
tx <- primary[gene == gid]
ex <- exons[gene == gid]
cd <- cds[gene == gid]
dd <- dml[assigned_gene == gid & in_gene_span == TRUE]
# plot coordinates in kb (absolute genomic position)
x0 <- tx$start / 1e3
x1 <- tx$end / 1e3
ymax_dml <- 1.15
# invisible layer carrying both DML levels so every panel yields an
# identical colour guide (patchwork then collapses it to one legend)
dummy <- data.frame(
direction = factor(c("Hyper-methylated", "Hypo-methylated"),
levels = c("Hyper-methylated", "Hypo-methylated")),
x = x0, y = 0)
p <- ggplot() +
# intron line spanning the primary transcript
geom_segment(aes(x = x0, xend = x1, y = 0, yend = 0),
linewidth = 0.4, colour = "grey40") +
geom_point(data = dummy, aes(x = x, y = y, colour = direction),
alpha = 0, shape = 18, size = 3) +
# exon boxes (UTR height)
geom_rect(data = ex,
aes(xmin = start/1e3, xmax = end/1e3, ymin = -0.22, ymax = 0.22,
fill = "UTR (exon)"), colour = NA) +
# CDS boxes (full height, drawn over exons)
geom_rect(data = cd,
aes(xmin = start/1e3, xmax = end/1e3, ymin = -0.38, ymax = 0.38,
fill = "CDS"), colour = NA)
# strand direction arrow above the model
arr_y <- 0.62
if (tx$strand == "+") {
p <- p + annotate("segment", x = x0, xend = x1, y = arr_y, yend = arr_y,
colour = "grey55", linewidth = 0.3,
arrow = arrow(length = unit(0.10, "cm"), type = "closed"))
} else {
p <- p + annotate("segment", x = x1, xend = x0, y = arr_y, yend = arr_y,
colour = "grey55", linewidth = 0.3,
arrow = arrow(length = unit(0.10, "cm"), type = "closed"))
}
# DML lollipops
if (nrow(dd) > 0) {
p <- p +
geom_segment(data = dd,
aes(x = pos/1e3, xend = pos/1e3, y = 0.38, yend = ymax_dml,
colour = direction), linewidth = 0.6, show.legend = FALSE) +
geom_point(data = dd,
aes(x = pos/1e3, y = ymax_dml, colour = direction),
size = 3, shape = 18, show.legend = FALSE) +
geom_text(data = dd,
aes(x = pos/1e3, y = ymax_dml + 0.22,
label = sprintf("%+.1f%%", meth_diff), colour = direction),
size = 2.7, fontface = "bold", show.legend = FALSE)
}
lab <- sprintf("%s \u2014 %s (%s strand)",
gid, short_name(g$gene_desc), tx$strand)
# wrap long titles so adjacent column panels don't collide
lab <- paste(strwrap(lab, width = 52), collapse = "\n")
span_kb <- (tx$end - tx$start) / 1e3
p +
scale_fill_manual(values = feat_cols, name = "Gene structure",
breaks = c("CDS","UTR (exon)")) +
scale_colour_manual(values = dml_cols, name = "DML methylation",
drop = FALSE) +
guides(colour = guide_legend(
override.aes = list(alpha = 1, shape = 18, size = 3, linetype = 0))) +
scale_y_continuous(limits = c(-0.7, ymax_dml + 0.45), expand = c(0,0)) +
labs(title = lab,
x = sprintf("%s position (kb) \u2022 transcript span %.1f kb",
g$chr, span_kb)) +
theme_minimal(base_size = 10) +
theme(
plot.title = element_text(size = 9.2, face = "bold"),
axis.title.x = element_text(size = 7.5, colour = "grey30"),
axis.text.x = element_text(size = 7),
axis.title.y = element_blank(),
axis.text.y = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_line(colour = "grey92", linewidth = 0.3),
legend.position = "bottom"
)
}
```
``` r
# order panels by paper functional grouping
gene_order <- c(
# Membrane dynamics and vesicle trafficking
"LOC134725187","LOC134690221","LOC134714536","LOC134695637",
# Cell signaling and regulation
"LOC134707074","LOC134720671",
# Stress response, apoptosis, and nucleic acid metabolism
"LOC134711256","LOC134685297","LOC134687110","LOC134687290",
# Uncharacterized
"LOC134712818","LOC134724475")
panels <- lapply(gene_order, build_panel)
fig <- wrap_plots(panels, ncol = 2) +
plot_layout(guides = "collect") +
plot_annotation(
title = "Gene models harboring differentially methylated loci (DMLs) in Mytilus trossulus mantle",
subtitle = "High- vs low-\u03a316 PAH sites \u00b7 NCBI GCF_036588685.1 \u00b7 exons (boxes), CDS (dark), introns (line); lollipops mark DMLs (\u0394 methylation %)",
caption = "DML positions from methylKit (q<0.01, |\u0394meth|\u226555%). Each panel drawn to its own bp scale.",
theme = theme(plot.title = element_text(face = "bold", size = 13),
plot.subtitle = element_text(size = 9, colour = "grey30"))
) &
theme(legend.position = "bottom")
ggsave(file.path(out_dir, "dml_gene_models.png"), fig,
width = 10, height = 14.4, dpi = 300, bg = "white")
ggsave(file.path(out_dir, "dml_gene_models.pdf"), fig,
width = 10, height = 14.4, bg = "white")
fig
```
# 6 Summary table
``` r
# nearest-gene context for the two intergenic loci (computed from the GFF)
nearest_note <- c(
"NC_086379.1:64017640" = "intergenic; nearest gene LOC134725550 (protein chibby homolog 1-like), ~3.7 kb",
"NC_086375.1:43581688" = "intergenic; nearest gene LOC134711544 (solute carrier family 40 member 1-like), ~1.0 kb"
)
n_exon_map <- exons[, .N, by = gene]
setnames(n_exon_map, "N", "exon_count")
summary_tab <- dml |>
merge(n_exon_map, by.x = "assigned_gene", by.y = "gene", all.x = TRUE, sort = FALSE) |>
merge(primary[, .(assigned_gene = gene, primary_tx = tx)], by = "assigned_gene",
all.x = TRUE, sort = FALSE)
summary_tab[, gene_span := paste0(g_start, "-", g_end)]
summary_tab[, locus := paste0(chr, ":", pos)]
summary_tab[, note := ifelse(in_gene_span, "DML within gene body",
nearest_note[locus])]
summary_out <- summary_tab[order(assigned_gene, pos),
.(gene_id = assigned_gene, gene_description = gene_desc, chr,
gene_span, strand = g_strand, primary_tx, exon_count,
dml_position = pos, qvalue, meth_diff, direction,
status_paper, in_gene_span, note)]
fwrite(summary_out, file.path(out_dir, "dml_gene_model_summary.tsv"), sep = "\t")
fwrite(summary_out, file.path(out_dir, "dml_gene_model_summary.csv"))
knitr::kable(summary_out)
```
| gene\_id | gene\_description | chr | gene\_span | strand | primary\_tx | exon\_count | dml\_position | qvalue | meth\_diff | direction | status\_paper | in\_gene\_span | note |
|:-------------|:--------------------------------------------------------------|:-------------|:--------------------|:-------|:--------------------|------------:|--------------:|-------:|-----------:|:-----------------|:--------------|:---------------|:---------------------|
| LOC134685297 | tumor protein p53-inducible protein 11-like | NC\_086381.1 | 21116727-21261455 | \- | rna-XM\_063544925.1 | 7 | 21212100 | 0 | -56.07 | Hypo-methylated | Hypo | TRUE | DML within gene body |
| LOC134687110 | alpha-ketoglutarate-dependent dioxygenase alkB homolog 3-like | NC\_086382.1 | 25951921-25959192 | \+ | rna-XM\_063547109.1 | 7 | 25952234 | 0 | -55.83 | Hypo-methylated | Hypo | TRUE | DML within gene body |
| LOC134687290 | mitogen-activated protein kinase kinase kinase 5-like | NC\_086382.1 | 36708321-36799106 | \+ | rna-XM\_063547445.1 | 42 | 36708761 | 0 | -56.50 | Hypo-methylated | Hypo | TRUE | DML within gene body |
| LOC134690221 | GRAM domain-containing protein 4-like | NC\_086373.1 | 90602585-90632630 | \+ | rna-XM\_063550200.1 | 18 | 90626338 | 0 | 56.32 | Hyper-methylated | Hyper | TRUE | DML within gene body |
| LOC134695637 | otoferlin-like | NC\_086373.1 | 105380391-105513502 | \- | rna-XM\_063556955.1 | 45 | 105503509 | 0 | -57.86 | Hypo-methylated | Hypo | TRUE | DML within gene body |
| LOC134707074 | receptor-type tyrosine-protein phosphatase N2-like | NC\_086374.1 | 34630047-34756161 | \- | rna-XM\_063566562.1 | 21 | 34742951 | 0 | 58.27 | Hyper-methylated | Hyper | TRUE | DML within gene body |
| LOC134711256 | cancer-related nucleoside-triphosphatase homolog | NC\_086375.1 | 31935064-31941257 | \- | rna-XM\_063571761.1 | 6 | 31938079 | 0 | -60.69 | Hypo-methylated | Hypo | TRUE | DML within gene body |
| LOC134712818 | uncharacterized LOC134712818 | NC\_086375.1 | 90867638-90891015 | \+ | rna-XM\_063574731.1 | 16 | 90876604 | 0 | 55.88 | Hyper-methylated | Hyper | TRUE | DML within gene body |
| LOC134714536 | coatomer subunit epsilon-like | NC\_086376.1 | 5626113-5639140 | \+ | rna-XM\_063575859.1 | 11 | 5631156 | 0 | 59.00 | Hyper-methylated | Hyper | TRUE | DML within gene body |
| LOC134720671 | roundabout homolog 1-like | NC\_086378.1 | 6588729-6697712 | \+ | rna-XM\_063583078.1 | 26 | 6633121 | 0 | -55.24 | Hypo-methylated | Hypo | TRUE | DML within gene body |
| LOC134724475 | uncharacterized LOC134724475 | NC\_086379.1 | 1585149-1617687 | \+ | rna-XM\_063587507.1 | 9 | 1603830 | 0 | -60.82 | Hypo-methylated | Hypo | TRUE | DML within gene body |
| LOC134725187 | membrane protein BRI3-like | NC\_086379.1 | 47959226-47965210 | \- | rna-XM\_063588806.1 | 4 | 47961734 | 0 | 56.45 | Hyper-methylated | Hyper | TRUE | DML within gene body |
# 7 Session info
``` r
sessionInfo()
```
## R version 4.3.2 (2023-10-31)
## Platform: aarch64-apple-darwin20 (64-bit)
## Running under: macOS Sonoma 14.7.6
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.11.0
##
## locale:
## [1] C
##
## time zone: America/Los_Angeles
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] patchwork_1.3.1 ggplot2_3.5.1 dplyr_1.1.4 data.table_1.16.0
## [5] knitr_1.48
##
## loaded via a namespace (and not attached):
## [1] vctrs_0.6.5 cli_3.6.3 rlang_1.1.4 xfun_0.48
## [5] highr_0.11 generics_0.1.3 textshaping_0.4.0 labeling_0.4.3
## [9] glue_1.8.0 colorspace_2.1-1 htmltools_0.5.8.1 ragg_1.3.3
## [13] scales_1.3.0 fansi_1.0.6 rmarkdown_2.28 grid_4.3.2
## [17] munsell_0.5.1 evaluate_1.0.0 tibble_3.2.1 fastmap_1.2.0
## [21] yaml_2.3.10 lifecycle_1.0.4 compiler_4.3.2 pkgconfig_2.0.3
## [25] systemfonts_1.1.0 farver_2.1.2 digest_0.6.37 R6_2.5.1
## [29] tidyselect_1.2.1 utf8_1.2.4 pillar_1.9.0 magrittr_2.0.3
## [33] withr_3.0.1 tools_4.3.2 gtable_0.3.6