R Notebook: Provides reproducible analysis for Mapping Files in the following manuscript:
Citation: Romanowicz KJ, Resnick C, Hinton SR, Plesa C. (2025) Exploring antibiotic resistance in diverse homologs of the dihydrofolate reductase protein family through broad mutational scanning. Science Advances. https://doi.org/10.1126/sciadv.adw9178
GitHub Repository: https://github.com/PlesaLab/DHFR
NCBI BioProject: https://www.ncbi.nlm.nih.gov/bioproject/1189478
This pipeline processes a library of 1,536 DHFR homologs and their associated mutants, with two-fold redundancy (two codon variants per sequence). Fitness scores are derived from a multiplexed in-vivo assay using a trimethoprim concentration gradient, assessing the ability of these homologs and their mutants to complement functionality in an E. coli knockout strain and their tolerance to trimethoprim treatment. This analysis provides insights into how antibiotic resistance evolves across a range of evolutionary starting points. Sequence data were generated using the Illumina NovaSeq platform with 100 bp paired-end sequencing of amplicons.
The following R packages must be installed prior to loading into the R session. See the Reproducibility tab for a complete list of packages and their versions used in this workflow.
# Load the latest version of python (3.10.14) for downstream use:
library(reticulate)
use_python("/Users/krom/miniforge3/bin/python3")
# Make a vector of required packages
required.packages <- c("ape", "bio3d", "Biostrings", "castor", "cowplot", "devtools", "dplyr", "ggExtra", "ggnewscale", "ggplot2", "ggridges", "ggtree", "ggtreeExtra", "glmnet", "gridExtra","igraph", "knitr", "matrixStats", "patchwork", "pheatmap", "purrr", "pscl", "RColorBrewer", "reshape","reshape2", "ROCR", "seqinr", "scales", "stringr", "stringi", "tidyr", "tidytree", "viridis")
# Load required packages with error handling
loaded.packages <- lapply(required.packages, function(package) {
if (!require(package, character.only = TRUE)) {
install.packages(package, dependencies = TRUE)
if (!require(package, character.only = TRUE)) {
message("Package ", package, " could not be installed and loaded.")
return(NULL)
}
}
return(package)
})
# Remove NULL entries from loaded packages
loaded.packages <- loaded.packages[!sapply(loaded.packages, is.null)]
Loaded packages: ape, bio3d, Biostrings, castor, cowplot, devtools, dplyr, ggExtra, ggnewscale, ggplot2, ggridges, ggtree, ggtreeExtra, glmnet, gridExtra, igraph, knitr, matrixStats, patchwork, pheatmap, purrr, pscl, RColorBrewer, reshape, reshape2, ROCR, seqinr, scales, stringr, stringi, tidyr, tidytree, viridis
This section is based on the R file: “R_load_data.R”. It describes how to load all of the pre-existing barcode mapping data necessary for downstream analysis.
Pre-Existing Data Files to Import
Begin the analysis by loading in the barcode information for
each codon-version library. This data represents each
barcode [BC] recovered from the
complementation process, linked to each homolog or
mutant [mutID], the number of
mutations observed in the sequence relative to its designed
homolog [mutations], a list of where the mutations
occurred along the protein sequence[cigar], and
the number of reads associated with each barcode
[reads]:
# Library 15 (Codon 1)
BCinfo15 = read.csv("Mapping/map_files_raw/15_HiFi_BC_mutID_all.csv", head=TRUE) # read csv file
# Library 16 (Codon 2)
BCinfo16 = read.csv("Mapping/map_files_raw/16_HiFi_BC_mutID_all.csv", head=TRUE) # read csv file
Filter each dataset to ensure each mutant has >=0 mutations
## Make sure each mutant has >=0 mutations by removing rows with negative values
BCinfo15 <- BCinfo15 %>%
filter(mutations >= 0)
# Check mutate count for Lib15 (should be "0"):
min(BCinfo15$mutations)
[1] 0
## Make sure each mutant has >=0 mutations by removing rows with negative values
BCinfo16 <- BCinfo16 %>%
filter(mutations >= 0)
# Check mutate count for Lib16 (should be "0"):
min(BCinfo16$mutations)
[1] 0
Preview of BCinfo
Total BC Read Counts: Summarize the total number of reads associated with all BCs for both libraries:
#Lib15
BCinfo15.read.count <- sum(BCinfo15$reads)
format(BCinfo15.read.count, big.mark = ",")
[1] "7,379,482"
#Lib16
BCinfo16.read.count <- sum(BCinfo16$reads)
format(BCinfo16.read.count, big.mark = ",")
[1] "7,635,281"
Total BCs: Count the number of unique barcodes for each library
# Count the number of unique barcodes for Library 15
BCinfo15.count <- length(unique(BCinfo15$BC))
format(BCinfo15.count, big.mark = ",")
[1] "1,545,469"
# Count the number of unique barcodes for Library 16
BCinfo16.count <- length(unique(BCinfo16$BC))
format(BCinfo16.count, big.mark = ",")
[1] "1,801,773"
Perfects BCs: Count the number of unique barcodes that have zero mutations (i.e., BCs associated with perfects). Note that many of these barcodes are likely associated with the same protein sequence and do not represent the total number of perfects recovered from the dataset.
# Count the number of rows containing zero (0) mutations for Library 15
BCinfo15.count.zeros <- sum(BCinfo15$mutations == 0)
format(BCinfo15.count.zeros, big.mark = ",")
[1] "417,540"
# Count the number of rows containing zero (0) mutations for Library 16
BCinfo16.count.zeros <- sum(BCinfo16$mutations == 0)
format(BCinfo16.count.zeros, big.mark = ",")
[1] "382,312"
Mutant BCs: Count the number of unique unique barcodes that have at least 1 mutation (i.e., BCs associated with mutants). Note that many of these barcodes are likely associated with the same protein sequence and do not represent the total number of mutants recovered from the dataset.
# Count the number of rows containing >=1 mutation for Library 15
BCinfo15.count.nonzeros <- sum(BCinfo15$mutations != 0)
format(BCinfo15.count.nonzeros, big.mark = ",")
[1] "1,127,929"
# Count the number of rows containing >=1 mutation for Library 16
BCinfo16.count.nonzeros <- sum(BCinfo16$mutations != 0)
format(BCinfo16.count.nonzeros, big.mark = ",")
[1] "1,419,461"
Load in the mutant information for each codon-version
library. This data represents each mutant
sequence [mutID] from the dataset, the designed
homolog it mutated from [IDalign], the
number of barcodes associated with each mutant
[numBCs], the number of mutations in the
sequence relative to the designed homolog [mutations], the
full sequence of the mutant [seq], the
percent identity of the mutant to the designed homolog
[pct_ident], a list of all barcodes
associated with the mutant [BCs], and the barcode
code [BCcode]:
# Library 15 (Codon 1)
mutIDinfo15 = read.csv("Mapping/map_files_raw/15_HiFi_mutID_info_all.csv", head=TRUE) # read csv file
# Library 16 (Codon 2)
mutIDinfo16 = read.csv("Mapping/map_files_raw/16_HiFi_mutID_info_all.csv", head=TRUE) # read csv file
Filter each dataset to ensure each mutant has >=0 mutations
## Make sure each mutant has >=0 mutations by removing rows with negative values
mutIDinfo15 <- mutIDinfo15 %>%
filter(mutations >= 0)
# Check mutate count for Lib15 (should be "0"):
min(mutIDinfo15$mutations)
[1] 0
## Make sure each mutant has >=0 mutations by removing rows with negative values
mutIDinfo16 <- mutIDinfo16 %>%
filter(mutations >= 0)
# Check mutate count for Lib16 (should be "0"):
min(mutIDinfo16$mutations)
[1] 0
Preview of mutIDinfo
Total Sequences: Count the number of unique protein sequences in each library
# Count the number of unique protein sequences for Library 15
mutIDinfo15.count <- length(unique(mutIDinfo15$seq))
format(mutIDinfo15.count, big.mark = ",")
[1] "473,854"
# Count the number of unique protein sequences for Library 16
mutIDinfo16.count <- length(unique(mutIDinfo16$seq))
format(mutIDinfo16.count, big.mark = ",")
[1] "469,672"
Perfect Sequences: Count the number of unique protein sequences that have zero mutations (i.e., sequences associated with perfects). These values designate the number of true homologs (“perfects”) that match the designed homologs without mutations.
# Count the number of rows containing zero (0) mutations for Library 15
mutIDinfo15.count.zeros <- sum(mutIDinfo15$mutations == 0)
format(mutIDinfo15.count.zeros, big.mark = ",")
[1] "1,048"
# Count the number of rows containing zero (0) mutations for Library 16
mutIDinfo16.count.zeros <- sum(mutIDinfo16$mutations == 0)
format(mutIDinfo16.count.zeros, big.mark = ",")
[1] "904"
Mutant Sequences: Count the number of unique protein sequences that have at least 1 mutation (i.e., sequences associated with mutants). These values designate the number of mutants derived from the designed homologs.
# Count the number of rows containing >=1 mutation for Library 15
mutIDinfo15.count.nonzeros <- sum(mutIDinfo15$mutations != 0)
format(mutIDinfo15.count.nonzeros, big.mark = ",")
[1] "472,806"
# Count the number of rows containing >=1 mutation for Library 16
mutIDinfo16.count.nonzeros <- sum(mutIDinfo16$mutations != 0)
format(mutIDinfo16.count.nonzeros, big.mark = ",")
[1] "468,768"
Count the number of shared perfect protein sequences between libraries (mutations == 0).
# Merge the mutIDinfo datasets but keep only the mutIDs shared between libraries
mutIDinfo.15.16.zeros.shared <- merge(mutIDinfo15, mutIDinfo16, by = "mutID", all = FALSE)
# Count the number of perfects (mutations == 0) shared between both libraries
mutIDinfo.15.16.zeros.shared.count <- sum(mutIDinfo.15.16.zeros.shared$mutations.x == 0)
format(mutIDinfo.15.16.zeros.shared.count, big.mark = ",")
[1] "744"
Also count the number of perfect sequences unique to one or the other library (mutations == 0).
# Merge the mutIDinfo datasets but retain only the mutIDs unique to one library or the other
mutIDinfo.15.16.zeros.unique <- bind_rows(
anti_join(mutIDinfo15, mutIDinfo16, by = "mutID"),
anti_join(mutIDinfo16, mutIDinfo15, by = "mutID"))
# Count the number of perfects (mutations == 0) unique to one library or the other
mutIDinfo.15.16.zeros.unique.count <- sum(mutIDinfo.15.16.zeros.unique$mutations == 0)
format(mutIDinfo.15.16.zeros.unique.count, big.mark = ",")
[1] "464"
Count the total number of shared and unique perfects between libraries:
mutIDinfo.15.16.zeros.all.count <- sum(mutIDinfo.15.16.zeros.shared.count + mutIDinfo.15.16.zeros.unique.count)
format(mutIDinfo.15.16.zeros.all.count, big.mark = ",")
[1] "1,208"
Add the IDalign column to the “BCinfo” objects based on shared “mutID” values with the “mutIDinfo” objects:
# Lib 15
BCinfo15$IDalign <- mutIDinfo15$IDalign[match(BCinfo15$mutID, mutIDinfo15$mutID)]
# Lib 16
BCinfo16$IDalign <- mutIDinfo16$IDalign[match(BCinfo16$mutID, mutIDinfo16$mutID)]
Add “Lib” column with value==1 for each BC present in the “BCinfo” object
# Add a new column "NewColumn" with every row value set to 1
# Lib 15
BCinfo15 <- BCinfo15 %>% mutate(Lib15 = 1)
# Lib 16
BCinfo16 <- BCinfo16 %>% mutate(Lib16 = 1)
Merge the “BCinfo” and “mutIDinfo” mapping files by shared “mutID” values for each library
# Lib15
# Merge mapping files by "mutID"
BCs_mutID_15 <- inner_join(BCinfo15,
mutIDinfo15 %>% select(-BCs),
by = "mutID")
# Select columns of interest to remove duplicates
BCs_mutID_15 <- BCs_mutID_15 %>%
select(BC, mutID, IDalign.x, mutations.x, cigar, numBCs, seq, pct_ident)
# Rename columns
names(BCs_mutID_15) <- c("BC","mutID","IDalign","mutations","cigar","numBCs","seq","pct_ident")
# Lib16
# Merge mapping files by "mutID"
BCs_mutID_16 <- inner_join(BCinfo16,
mutIDinfo16 %>% select(-BCs),
by = "mutID")
# Select columns of interest to remove duplicates
BCs_mutID_16 <- BCs_mutID_16 %>%
select(BC, mutID, IDalign.x, mutations.x, cigar, numBCs, seq, pct_ident)
# Rename columns
names(BCs_mutID_16) <- c("BC","mutID","IDalign","mutations","cigar","numBCs","seq","pct_ident")
Save the formatted mapping files to import for downstream analyses
# BCinfo15 (185.4 MB)
write.csv(BCinfo15, "Mapping/map_files_formatted/BCinfo15.csv", row.names = FALSE)
# BCinfo16 (225.7 MB)
write.csv(BCinfo16, "Mapping/map_files_formatted/BCinfo16.csv", row.names = FALSE)
###------------------------------------
# mutIDinfo15 (140 MB)
write.csv(mutIDinfo15, "Mapping/map_files_formatted/mutIDinfo15.csv", row.names = FALSE)
# mutIDinfo16 (144.1 MB)
write.csv(mutIDinfo16, "Mapping/map_files_formatted/mutIDinfo16.csv", row.names = FALSE)
###------------------------------------
# BCs_mutID_15 (367.8 MB | Previously 53.13 GB when including "BCs" column)
write.csv(BCs_mutID_15, "Mapping/map_files_formatted/BCs_mutID_15.csv", row.names = FALSE)
# BCs_mutID_16 (416.8 MB | Previously 211.83 GB when including "BCs" column)
write.csv(BCs_mutID_16, "Mapping/map_files_formatted/BCs_mutID_16.csv", row.names = FALSE)
###------------------------------------
# mutIDinfo.15.16.zeros.shared (19.4 MB)
write.csv(mutIDinfo.15.16.zeros.shared, "Mapping/map_files_formatted/mutIDinfo.15.16.zeros.shared.csv",
row.names = FALSE)
# mutIDinfo.15.16.zeros.unique (264.3 MB)
write.csv(mutIDinfo.15.16.zeros.unique, "Mapping/map_files_formatted/mutIDinfo.15.16.zeros.unique.csv",
row.names = FALSE)
The session information is provided for full reproducibility.
devtools::session_info()
─ Session info ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
setting value
version R version 4.3.2 (2023-10-31)
os macOS 15.5
system aarch64, darwin20
ui RStudio
language (EN)
collate en_US.UTF-8
ctype en_US.UTF-8
tz America/Los_Angeles
date 2025-08-14
rstudio 2024.09.0+375 Cranberry Hibiscus (desktop)
pandoc 3.2 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/aarch64/ (via rmarkdown)
quarto 1.6.42 @ /usr/local/bin/quarto
─ Packages ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
package * version date (UTC) lib source
ade4 1.7-23 2025-02-14 [1] CRAN (R 4.3.3)
ape * 5.8-1 2024-12-16 [1] CRAN (R 4.3.3)
aplot 0.2.5 2025-02-27 [1] CRAN (R 4.3.3)
bio3d * 2.4-5 2024-10-29 [1] CRAN (R 4.3.3)
BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor
Biostrings * 2.68.1 2023-05-21 [1] Bioconductor
bitops 1.0-9 2024-10-03 [1] CRAN (R 4.3.3)
bslib 0.9.0 2025-01-30 [1] CRAN (R 4.3.3)
cachem 1.1.0 2024-05-16 [1] CRAN (R 4.3.3)
castor * 1.8.3 2024-11-17 [1] CRAN (R 4.3.3)
cli 3.6.4 2025-02-13 [1] CRAN (R 4.3.3)
codetools 0.2-20 2024-03-31 [1] CRAN (R 4.3.1)
colorspace 2.1-1 2024-07-26 [1] CRAN (R 4.3.3)
cowplot * 1.1.3 2024-01-22 [1] CRAN (R 4.3.1)
crayon 1.5.3 2024-06-20 [1] CRAN (R 4.3.3)
devtools * 2.4.5 2022-10-11 [1] CRAN (R 4.3.0)
digest 0.6.37 2024-08-19 [1] CRAN (R 4.3.3)
dplyr * 1.1.4 2023-11-17 [1] CRAN (R 4.3.1)
ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0)
evaluate 1.0.3 2025-01-10 [1] CRAN (R 4.3.3)
farver 2.1.2 2024-05-13 [1] CRAN (R 4.3.3)
fastmap 1.2.0 2024-05-15 [1] CRAN (R 4.3.3)
foreach 1.5.2 2022-02-02 [1] CRAN (R 4.3.0)
fs 1.6.5 2024-10-30 [1] CRAN (R 4.3.3)
generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0)
GenomeInfoDb * 1.36.4 2023-10-08 [1] Bioconductor
GenomeInfoDbData 1.2.10 2023-09-13 [1] Bioconductor
ggExtra * 0.10.1 2023-08-21 [1] CRAN (R 4.3.0)
ggfun 0.1.8 2024-12-03 [1] CRAN (R 4.3.3)
ggnewscale * 0.5.1 2025-02-24 [1] CRAN (R 4.3.3)
ggplot2 * 3.5.1 2024-04-23 [1] CRAN (R 4.3.1)
ggplotify 0.1.2 2023-08-09 [1] CRAN (R 4.3.0)
ggridges * 0.5.6 2024-01-23 [1] CRAN (R 4.3.1)
ggtree * 3.8.2 2023-07-30 [1] Bioconductor
ggtreeExtra * 1.10.0 2023-04-25 [1] Bioconductor
glmnet * 4.1-8 2023-08-22 [1] CRAN (R 4.3.0)
glue 1.8.0 2024-09-30 [1] CRAN (R 4.3.3)
gridExtra * 2.3 2017-09-09 [1] CRAN (R 4.3.0)
gridGraphics 0.5-1 2020-12-13 [1] CRAN (R 4.3.0)
gtable 0.3.6 2024-10-25 [1] CRAN (R 4.3.3)
htmltools 0.5.8.1 2024-04-04 [1] CRAN (R 4.3.1)
htmlwidgets 1.6.4 2023-12-06 [1] CRAN (R 4.3.1)
httpuv 1.6.15 2024-03-26 [1] CRAN (R 4.3.1)
igraph * 2.1.4 2025-01-23 [1] CRAN (R 4.3.3)
IRanges * 2.34.1 2023-07-02 [1] Bioconductor
iterators 1.0.14 2022-02-05 [1] CRAN (R 4.3.0)
jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0)
jsonlite 1.9.1 2025-03-03 [1] CRAN (R 4.3.3)
knitr * 1.50 2025-03-16 [1] CRAN (R 4.3.3)
later 1.4.1 2024-11-27 [1] CRAN (R 4.3.3)
lattice 0.22-6 2024-03-20 [1] CRAN (R 4.3.1)
lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0)
lifecycle 1.0.4 2023-11-07 [1] CRAN (R 4.3.1)
magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0)
MASS 7.3-60.0.1 2024-01-13 [1] CRAN (R 4.3.1)
Matrix * 1.6-5 2024-01-11 [1] CRAN (R 4.3.1)
matrixStats * 1.5.0 2025-01-07 [1] CRAN (R 4.3.3)
memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0)
mime 0.13 2025-03-17 [1] CRAN (R 4.3.3)
miniUI 0.1.1.1 2018-05-18 [1] CRAN (R 4.3.0)
munsell 0.5.1 2024-04-01 [1] CRAN (R 4.3.1)
naturalsort 0.1.3 2016-08-30 [1] CRAN (R 4.3.0)
nlme 3.1-167 2025-01-27 [1] CRAN (R 4.3.3)
patchwork * 1.3.0 2024-09-16 [1] CRAN (R 4.3.3)
pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0)
pillar 1.10.1 2025-01-07 [1] CRAN (R 4.3.3)
pkgbuild 1.4.6 2025-01-16 [1] CRAN (R 4.3.3)
pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0)
pkgload 1.4.0 2024-06-28 [1] CRAN (R 4.3.3)
plyr 1.8.9 2023-10-02 [1] CRAN (R 4.3.1)
png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0)
profvis 0.4.0 2024-09-20 [1] CRAN (R 4.3.3)
promises 1.3.2 2024-11-28 [1] CRAN (R 4.3.3)
pscl * 1.5.9 2024-01-31 [1] CRAN (R 4.3.1)
purrr * 1.0.4 2025-02-05 [1] CRAN (R 4.3.3)
R6 2.6.1 2025-02-15 [1] CRAN (R 4.3.3)
RColorBrewer * 1.1-3 2022-04-03 [1] CRAN (R 4.3.0)
Rcpp * 1.0.14 2025-01-12 [1] CRAN (R 4.3.3)
RCurl 1.98-1.17 2025-03-22 [1] CRAN (R 4.3.3)
remotes 2.5.0 2024-03-17 [1] CRAN (R 4.3.1)
reshape * 0.8.9 2022-04-12 [1] CRAN (R 4.3.0)
reshape2 * 1.4.4 2020-04-09 [1] CRAN (R 4.3.0)
reticulate * 1.41.0.1 2025-03-09 [1] CRAN (R 4.3.3)
rlang 1.1.5 2025-01-17 [1] CRAN (R 4.3.3)
rmarkdown 2.29 2024-11-04 [1] CRAN (R 4.3.3)
ROCR * 1.0-11 2020-05-02 [1] CRAN (R 4.3.0)
RSpectra 0.16-2 2024-07-18 [1] CRAN (R 4.3.3)
rstudioapi 0.17.1 2024-10-22 [1] CRAN (R 4.3.3)
S4Vectors * 0.38.2 2023-09-24 [1] Bioconductor
sass 0.4.9 2024-03-15 [1] CRAN (R 4.3.1)
scales * 1.3.0 2023-11-28 [1] CRAN (R 4.3.1)
seqinr * 4.2-36 2023-12-08 [1] CRAN (R 4.3.1)
sessioninfo 1.2.3 2025-02-05 [1] CRAN (R 4.3.3)
shape 1.4.6.1 2024-02-23 [1] CRAN (R 4.3.1)
shiny 1.10.0 2024-12-14 [1] CRAN (R 4.3.3)
stringi * 1.8.4 2024-05-06 [1] CRAN (R 4.3.3)
stringr * 1.5.1 2023-11-14 [1] CRAN (R 4.3.1)
survival 3.8-3 2024-12-17 [1] CRAN (R 4.3.3)
tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0)
tidyr * 1.3.1 2024-01-24 [1] CRAN (R 4.3.1)
tidyselect 1.2.1 2024-03-11 [1] CRAN (R 4.3.1)
tidytree * 0.4.6 2023-12-12 [1] CRAN (R 4.3.1)
treeio 1.24.3 2023-07-30 [1] Bioconductor
urlchecker 1.0.1 2021-11-30 [1] CRAN (R 4.3.0)
usethis * 3.1.0 2024-11-26 [1] CRAN (R 4.3.3)
vctrs 0.6.5 2023-12-01 [1] CRAN (R 4.3.1)
viridis * 0.6.5 2024-01-29 [1] CRAN (R 4.3.1)
viridisLite * 0.4.2 2023-05-02 [1] CRAN (R 4.3.0)
withr 3.0.2 2024-10-28 [1] CRAN (R 4.3.3)
xfun 0.51 2025-02-19 [1] CRAN (R 4.3.3)
xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0)
XVector * 0.40.0 2023-05-08 [1] Bioconductor
yaml 2.3.10 2024-07-26 [1] CRAN (R 4.3.3)
yulab.utils 0.2.0 2025-01-29 [1] CRAN (R 4.3.3)
zlibbioc 1.46.0 2023-05-08 [1] Bioconductor
[1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library
* ── Packages attached to the search path.
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────