diff --git a/analyses/transcriptomic-dimension-reduction/01-dimension-reduction.sh b/analyses/transcriptomic-dimension-reduction/01-dimension-reduction.sh old mode 100644 new mode 100755 index e35acc36a8..79b143d472 --- a/analyses/transcriptomic-dimension-reduction/01-dimension-reduction.sh +++ b/analyses/transcriptomic-dimension-reduction/01-dimension-reduction.sh @@ -74,6 +74,44 @@ Rscript --vanilla scripts/run-dimension-reduction.R \ --low_count_threshold ${COUNT_THRESHOLD} \ --log2_transform + + +#### TPM stranded, with and without mitochondrial genes and skipping t-sne ------------------------------------ +# Note that these results are only used for exploration in `05-seq_center-mitochondrial-genes.Rmd` + +# First, we'll need to create this input file, which contains filtered and re-normalied TPM, if it is missing: +NOMITO_TPM_FILE=../../scratch/transcriptomic-dimension-reduction/tpm-nomito-stranded.rds +if [ ! -f ${NOMITO_TPM_FILE} ]; then + Rscript --vanilla scripts/prepare-tpm-for-umap.R +fi + +# Perform dimension reduction on all TPM +Rscript --vanilla scripts/run-dimension-reduction.R \ + --expression ../../data/pbta-gene-expression-rsem-tpm.stranded.rds \ + --metadata ${METADATA} \ + --filename_lead tpm_stranded_all_log \ + --output_directory ${OUTPUT} \ + --seed ${SEED} \ + --perplexity ${PERPLEXITY} \ + --neighbors ${NEIGHBORS} \ + --low_count_threshold ${COUNT_THRESHOLD} \ + --skip_tsne \ + --log2_transform + +# Perform dimension reduction on nomito TPM +Rscript --vanilla scripts/run-dimension-reduction.R \ + --expression ${NOMITO_TPM_FILE} \ + --metadata ${METADATA} \ + --filename_lead tpm_stranded_nomito_log \ + --output_directory ${OUTPUT} \ + --seed ${SEED} \ + --perplexity ${PERPLEXITY} \ + --neighbors ${NEIGHBORS} \ + --low_count_threshold ${COUNT_THRESHOLD} \ + --skip_tsne \ + --log2_transform + + #### kallisto ------------------------------------------------------------------ Rscript --vanilla scripts/run-dimension-reduction.R \ @@ -118,3 +156,5 @@ Rscript --vanilla scripts/run-dimension-reduction.R \ --low_count_threshold ${COUNT_THRESHOLD} \ --log2_transform + + diff --git a/analyses/transcriptomic-dimension-reduction/05-seq-center-mitochondrial-genes.Rmd b/analyses/transcriptomic-dimension-reduction/05-seq-center-mitochondrial-genes.Rmd new file mode 100644 index 0000000000..97edde813f --- /dev/null +++ b/analyses/transcriptomic-dimension-reduction/05-seq-center-mitochondrial-genes.Rmd @@ -0,0 +1,240 @@ +--- +title: "Explore mitochondrial gene effect on UMAP plots" +author: "S. Spielman for CCDL" +date: "2023" +output: + html_notebook: + toc: TRUE + toc_float: TRUE +--- + +This notebook aims to explore some potential sequencing center biases that were raised in this OpenPBTA issue: https://github.com/AlexsLemonade/OpenPBTA-analysis/issues/1601 +This issues notes that some of the samples sequenced at `BGI@CHOP` had higher-than-expected expression for certain mitochondrial genes, specifically RNR1 and RNR2, and somewhat lower-than-expected expression for other mitochondrial genes. + +To ensure appropriate normalization, the UMAPs here were created from TPM data rather than FPKM, such that mitochondrial genes were removed from the TPM results themselves. + +## Setup + +```{r setup, include=FALSE} +library(magrittr) +library(ggplot2) + +set.seed(2023) + +# set overall theme +theme_set(ggpubr::theme_pubr() + + # Legend tweaks for legibility + theme(legend.position = "right", + legend.direction = "vertical", + legend.text = element_text(size = rel(0.5)), + legend.title = element_text(size = rel(0.5)), + legend.key.size = unit(0.25, "cm") + )) + +# figure settings +knitr::opts_chunk$set(fig.width = 8) +``` + + +Define directories and file names: +```{r} +# Directories +root_dir <- rprojroot::find_root(rprojroot::has_dir(".git")) +data_dir <- file.path(root_dir, "data") +tumor_dir <- file.path(root_dir, "analyses", "tumor-purity-exploration") +umap_dir <- file.path( + root_dir, + "analyses", + "transcriptomic-dimension-reduction", + "results" +) +palette_dir <- file.path(root_dir, "figures", "palettes") + +# UMAP files with different samples: +tpm_umap <- file.path(umap_dir, "tpm_stranded_all_log_umap_scores_aligned.tsv") +tpm_no_mito_umap <- file.path(umap_dir, "tpm_stranded_nomito_log_umap_scores_aligned.tsv") + +# palette mapping file +pal_file <- file.path(palette_dir, "broad_histology_cancer_group_palette.tsv") + +# FPKM +expression_file <- file.path(data_dir, "pbta-gene-expression-rsem-fpkm-collapsed.stranded.rds") + +metadata_file <- file.path(data_dir, "pbta-histologies.tsv") +``` + +```{r} +# Read in palette data +palette_mapping_df <- readr::read_tsv(pal_file) %>% + dplyr::select(broad_histology, broad_histology_display, broad_histology_hex, + cancer_group, cancer_group_display, cancer_group_hex) + +# Read in and prep UMAP data +# helper function +readr_prep_umap <- function(filename, + pal_df = palette_mapping_df) { + readr::read_tsv(filename) %>% + dplyr::rename(UMAP1 = X1, UMAP2 = X2) %>% + dplyr::inner_join(pal_df) %>% + dplyr::mutate(seq_center = forcats::fct_relevel(seq_center, + "BGI", "BGI@CHOP Genome Center", "NantOmics")) +} + +umap_all <- readr_prep_umap(tpm_umap) +umap_no_mito <- readr_prep_umap(tpm_no_mito_umap) + +# Read in expression and convert to data frame +expression_df <- readr::read_rds(expression_file) %>% + tibble::as_tibble(rownames = "gene_symbol") + +# Read in metadata +metadata_df <- readr::read_tsv(metadata_file) +``` + + +## Explore mitochondrial genes + +For mitochondrial genes, do we see expression patterns for BGI@CHOP samples consistent with those posted in the issue linked above? + +```{r} +# First, which diagnoses are sequenced at BGI@CHOP? +relevant_groups <- metadata_df %>% + dplyr::filter(RNA_library == "stranded", + stringr::str_starts(seq_center, "BGI")) %>% + tidyr::drop_na(broad_histology) %>% + dplyr::pull(broad_histology) %>% + unique() + +# Data frame of log2(FPKM) of mitochondrial genes for relevant diagnoses +mito_seq_center_df <- expression_df %>% + dplyr::filter(stringr::str_starts(gene_symbol, "MT-")) %>% + tidyr::gather("Kids_First_Biospecimen_ID", + "fpkm", + tidyselect::starts_with("BS_")) %>% + dplyr::mutate(log2_fpkm = log2(fpkm+1)) %>% + # get diagnoses across samples + dplyr::inner_join( + dplyr::select(metadata_df, + Kids_First_Biospecimen_ID, + broad_histology, + seq_center) + ) %>% + # filter to only relevant groups + dplyr::filter(broad_histology %in% relevant_groups) %>% + # get display version of diagnosis + dplyr::inner_join( + dplyr::select(palette_mapping_df, + broad_histology, + broad_histology_display) + ) + + +ggplot(mito_seq_center_df) + + aes(x = gene_symbol, y = log2_fpkm, color = seq_center, size = seq_center) + + geom_jitter(width = 0.15) + + # emphasize the BGI points! + scale_size_manual(values = c(2, 2, 0.5)) + + facet_wrap(~broad_histology_display) + + theme(axis.text.x = element_text(angle = 30, hjust = 1, size = 4)) + +``` + +We see a couple trends in the plot above that are consistent with the posted issue: + +- `BGI@CHOP Genome Center` samples have dramatically higher RNR1 and RNR2, but substantially lower expression for the other mitochondrial genes, across all diagnoses. +- `BGI` samples tend to have lower RNR1 and RNR2 expression, and have lower expression for other genes specifically for embryonal tumors. + +Thus, `BIG@CHOP` (not `BGI`) samples are the main "concern" here. + + +## UMAP + +How do UMAPs with and without mitochondrial genes compare? +We might expect particular changes in embryonal, ependymal, and HGG since BGI is mostly those dianogses. + +```{r} +# Function to plot UMAP and set up color palettes. +plot_umap <- function(df, color_group, color_palette, title) { + ggplot(df) + + aes(x = UMAP1, y = UMAP2, + shape = seq_center, + fill = {{color_group}}, + color = seq_center, + alpha = seq_center) + + geom_point(size = 2.5) + + scale_shape_manual(values = c(22, 24, 21)) + + scale_fill_manual(values = color_palette, + # This "shape" override is needed for legend fill colors to actually work + guide = guide_legend(override.aes = list(shape = 21, size = 2))) + + scale_color_manual(values = c("grey70", "black", "black"), + # These overrides ensure shapes appear all in same alpha/color in legend + guide = guide_legend(override.aes = list(color = "black", alpha = 1, size = 2))) + + scale_alpha_manual(values = c(0.3, 0.5, 0.5)) + + ggtitle(title) + + # tweaks for legibility + theme(legend.position = "bottom", + legend.text = element_text(size = rel(0.5)), + legend.title = element_text(size = rel(0.5)), + legend.key.size = unit(0.25, "cm") + ) +} + +# Another plotting helper function to cowplot some plots with a shared legend +combine_plots <- function(p1, p2) { + p_legend <- cowplot::get_legend(p1) + + plot_row <- cowplot::plot_grid(p1 + theme(legend.position = "none"), + p2 + theme(legend.position = "none"), + nrow = 1, + rel_widths = 0.95) + + full_grid <- cowplot::plot_grid(plot_row, p_legend, nrow = 2, rel_heights = c(1, 0.2)) + + full_grid +} + + +# set up color palettes +bh_df <- palette_mapping_df %>% + dplyr::select(broad_histology_display, broad_histology_hex) %>% + dplyr::distinct() +pal_bh<- bh_df$broad_histology_hex +names(pal_bh) <- bh_df$broad_histology_display + +cg_df <- palette_mapping_df %>% + dplyr::select(cancer_group_display, cancer_group_hex) %>% + dplyr::distinct() %>% + tidyr::drop_na() +pal_cg<- cg_df$cancer_group_hex +names(pal_cg) <- cg_df$cancer_group_display +``` + + +Let's plot some UMAPs! + +```{r, fig.width = 14, fig.height = 8} +p1 <- plot_umap(umap_all, broad_histology_display, pal_bh, "Includes all genes. Colored by broad histology.") +p2 <- plot_umap(umap_no_mito, broad_histology_display, pal_bh, "Includes only non-mito genes. Colored by broad histology.") +combine_plots(p1, p2) + +p1 <- plot_umap(umap_all, cancer_group_display, pal_cg, "Includes all genes. Colored by cancer group.") +p2 <- plot_umap(umap_no_mito, cancer_group_display, pal_cg, "Includes only non-mito genes. Colored by cancer group.") +combine_plots(p1, p2) +``` + +## Conclusions + +- Samples from `BIG@CHOP` sequencing center have unique mitochondrial gene distributions. +- Removing mitochondrial genes from the UMAP does not have a strong qualitiative effect on whether broad histologies or cancer groups tend to cluster together. +The UMAPs created here also look broadly similar to those made with FPKM. +Visually, it seems the "mixed histology" groupings identified in `04-explore-sequencing-center-effects.Rmd` +notebook still are grouped together in these UMAPs. + +Overall, this suggests that mitochondrial genes alone will not have a strong influence on UMAP visualizations. +However, there may still be protocol differences associated with BIG@CHOP samples that influence expression values more generally, and can not be corrected by removing only mitochondrial genes. + +## sessionInfo + +```{r print session info} +sessionInfo() +``` diff --git a/analyses/transcriptomic-dimension-reduction/05-seq-center-mitochondrial-genes.nb.html b/analyses/transcriptomic-dimension-reduction/05-seq-center-mitochondrial-genes.nb.html new file mode 100644 index 0000000000..5dc7e27e2b --- /dev/null +++ b/analyses/transcriptomic-dimension-reduction/05-seq-center-mitochondrial-genes.nb.html @@ -0,0 +1,3326 @@ + + + + +
+ + + + + + + + + + +This notebook aims to explore some potential sequencing center biases that were raised in this OpenPBTA issue: https://github.com/AlexsLemonade/OpenPBTA-analysis/issues/1601 This issues notes that some of the samples sequenced at BGI@CHOP
had higher-than-expected expression for certain mitochondrial genes, specifically RNR1 and RNR2, and somewhat lower-than-expected expression for other mitochondrial genes.
To ensure appropriate normalization, the UMAPs here were created from TPM data rather than FPKM, such that mitochondrial genes were removed from the TPM results themselves.
+Define directories and file names:
+ + + +# Directories
+root_dir <- rprojroot::find_root(rprojroot::has_dir(".git"))
+data_dir <- file.path(root_dir, "data")
+tumor_dir <- file.path(root_dir, "analyses", "tumor-purity-exploration")
+umap_dir <- file.path(
+ root_dir,
+ "analyses",
+ "transcriptomic-dimension-reduction",
+ "results"
+)
+palette_dir <- file.path(root_dir, "figures", "palettes")
+
+# UMAP files with different samples:
+tpm_umap <- file.path(umap_dir, "tpm_stranded_all_log_umap_scores_aligned.tsv")
+tpm_no_mito_umap <- file.path(umap_dir, "tpm_stranded_nomito_log_umap_scores_aligned.tsv")
+
+# palette mapping file
+pal_file <- file.path(palette_dir, "broad_histology_cancer_group_palette.tsv")
+
+# FPKM
+expression_file <- file.path(data_dir, "pbta-gene-expression-rsem-fpkm-collapsed.stranded.rds")
+
+metadata_file <- file.path(data_dir, "pbta-histologies.tsv")
+
+
+
+
+
+
+# Read in palette data
+palette_mapping_df <- readr::read_tsv(pal_file) %>%
+ dplyr::select(broad_histology, broad_histology_display, broad_histology_hex,
+ cancer_group, cancer_group_display, cancer_group_hex)
+
+
+Parsed with column specification:
+cols(
+ broad_histology = col_character(),
+ cancer_group = col_character(),
+ broad_histology_display = col_character(),
+ cancer_group_display = col_character(),
+ broad_histology_hex = col_character(),
+ cancer_group_abbreviation = col_character(),
+ cancer_group_hex = col_character(),
+ broad_histology_order = col_double(),
+ oncoprint_group = col_character(),
+ oncoprint_main = col_logical()
+)
+
+
+# Read in and prep UMAP data
+# helper function
+readr_prep_umap <- function(filename,
+ pal_df = palette_mapping_df) {
+ readr::read_tsv(filename) %>%
+ dplyr::rename(UMAP1 = X1, UMAP2 = X2) %>%
+ dplyr::inner_join(pal_df) %>%
+ dplyr::mutate(seq_center = forcats::fct_relevel(seq_center,
+ "BGI", "BGI@CHOP Genome Center", "NantOmics"))
+}
+
+umap_all <- readr_prep_umap(tpm_umap)
+
+
+Parsed with column specification:
+cols(
+ .default = col_character(),
+ X1 = col_double(),
+ X2 = col_double(),
+ OS_days = col_double(),
+ age_last_update_days = col_double(),
+ normal_fraction = col_logical(),
+ tumor_fraction = col_logical(),
+ tumor_ploidy = col_logical()
+)
+
+
+See spec(...) for full column specifications.
+
+
+Joining, by = c("broad_histology", "cancer_group")
+
+
+umap_no_mito <- readr_prep_umap(tpm_no_mito_umap)
+
+
+Parsed with column specification:
+cols(
+ .default = col_character(),
+ X1 = col_double(),
+ X2 = col_double(),
+ OS_days = col_double(),
+ age_last_update_days = col_double(),
+ normal_fraction = col_logical(),
+ tumor_fraction = col_logical(),
+ tumor_ploidy = col_logical()
+)
+
+
+See spec(...) for full column specifications.
+
+
+Joining, by = c("broad_histology", "cancer_group")
+
+
+# Read in expression and convert to data frame
+expression_df <- readr::read_rds(expression_file) %>%
+ tibble::as_tibble(rownames = "gene_symbol")
+
+# Read in metadata
+metadata_df <- readr::read_tsv(metadata_file)
+
+
+Parsed with column specification:
+cols(
+ .default = col_character(),
+ OS_days = col_double(),
+ age_last_update_days = col_double(),
+ normal_fraction = col_double(),
+ tumor_fraction = col_double(),
+ tumor_ploidy = col_double()
+)
+
+
+See spec(...) for full column specifications.
+
+
+
+For mitochondrial genes, do we see expression patterns for BGI@CHOP samples consistent with those posted in the issue linked above?
+ + + +# First, which diagnoses are sequenced at BGI@CHOP?
+relevant_groups <- metadata_df %>%
+ dplyr::filter(RNA_library == "stranded",
+ stringr::str_starts(seq_center, "BGI")) %>%
+ tidyr::drop_na(broad_histology) %>%
+ dplyr::pull(broad_histology) %>%
+ unique()
+
+# Data frame of log2(FPKM) of mitochondrial genes for relevant diagnoses
+mito_seq_center_df <- expression_df %>%
+ dplyr::filter(stringr::str_starts(gene_symbol, "MT-")) %>%
+ tidyr::gather("Kids_First_Biospecimen_ID",
+ "fpkm",
+ tidyselect::starts_with("BS_")) %>%
+ dplyr::mutate(log2_fpkm = log2(fpkm+1)) %>%
+ # get diagnoses across samples
+ dplyr::inner_join(
+ dplyr::select(metadata_df,
+ Kids_First_Biospecimen_ID,
+ broad_histology,
+ seq_center)
+ ) %>%
+ # filter to only relevant groups
+ dplyr::filter(broad_histology %in% relevant_groups) %>%
+ # get display version of diagnosis
+ dplyr::inner_join(
+ dplyr::select(palette_mapping_df,
+ broad_histology,
+ broad_histology_display)
+ )
+
+
+Joining, by = "Kids_First_Biospecimen_ID"
+
+
+Joining, by = "broad_histology"
+
+
+ggplot(mito_seq_center_df) +
+ aes(x = gene_symbol, y = log2_fpkm, color = seq_center, size = seq_center) +
+ geom_jitter(width = 0.15) +
+ # emphasize the BGI points!
+ scale_size_manual(values = c(2, 2, 0.5)) +
+ facet_wrap(~broad_histology_display) +
+ theme(axis.text.x = element_text(angle = 30, hjust = 1, size = 4))
+
+
+We see a couple trends in the plot above that are consistent with the posted issue:
+BGI@CHOP Genome Center
samples have dramatically higher RNR1 and RNR2, but substantially lower expression for the other mitochondrial genes, across all diagnoses.BGI
samples tend to have lower RNR1 and RNR2 expression, and have lower expression for other genes specifically for embryonal tumors.Thus, BIG@CHOP
(not BGI
) samples are the main “concern” here.
How do UMAPs with and without mitochondrial genes compare? We might expect particular changes in embryonal, ependymal, and HGG since BGI is mostly those dianogses.
+ + + +# Function to plot UMAP and set up color palettes.
+plot_umap <- function(df, color_group, color_palette, title) {
+ ggplot(df) +
+ aes(x = UMAP1, y = UMAP2,
+ shape = seq_center,
+ fill = {{color_group}},
+ color = seq_center,
+ alpha = seq_center) +
+ geom_point(size = 2.5) +
+ scale_shape_manual(values = c(22, 24, 21)) +
+ scale_fill_manual(values = color_palette,
+ # This "shape" override is needed for legend fill colors to actually work
+ guide = guide_legend(override.aes = list(shape = 21, size = 2))) +
+ scale_color_manual(values = c("grey70", "black", "black"),
+ # These overrides ensure shapes appear all in same alpha/color in legend
+ guide = guide_legend(override.aes = list(color = "black", alpha = 1, size = 2))) +
+ scale_alpha_manual(values = c(0.3, 0.5, 0.5)) +
+ ggtitle(title) +
+ # tweaks for legibility
+ theme(legend.position = "bottom",
+ legend.text = element_text(size = rel(0.5)),
+ legend.title = element_text(size = rel(0.5)),
+ legend.key.size = unit(0.25, "cm")
+ )
+}
+
+# Another plotting helper function to cowplot some plots with a shared legend
+combine_plots <- function(p1, p2) {
+ p_legend <- cowplot::get_legend(p1)
+
+ plot_row <- cowplot::plot_grid(p1 + theme(legend.position = "none"),
+ p2 + theme(legend.position = "none"),
+ nrow = 1,
+ rel_widths = 0.95)
+
+ full_grid <- cowplot::plot_grid(plot_row, p_legend, nrow = 2, rel_heights = c(1, 0.2))
+
+ full_grid
+}
+
+
+# set up color palettes
+bh_df <- palette_mapping_df %>%
+ dplyr::select(broad_histology_display, broad_histology_hex) %>%
+ dplyr::distinct()
+pal_bh<- bh_df$broad_histology_hex
+names(pal_bh) <- bh_df$broad_histology_display
+
+cg_df <- palette_mapping_df %>%
+ dplyr::select(cancer_group_display, cancer_group_hex) %>%
+ dplyr::distinct() %>%
+ tidyr::drop_na()
+pal_cg<- cg_df$cancer_group_hex
+names(pal_cg) <- cg_df$cancer_group_display
+
+
+
+Let’s plot some UMAPs!
+ + + +p1 <- plot_umap(umap_all, broad_histology_display, pal_bh, "Includes all genes. Colored by broad histology.")
+p2 <- plot_umap(umap_no_mito, broad_histology_display, pal_bh, "Includes only non-mito genes. Colored by broad histology.")
+combine_plots(p1, p2)
+
+
+p1 <- plot_umap(umap_all, cancer_group_display, pal_cg, "Includes all genes. Colored by cancer group.")
+p2 <- plot_umap(umap_no_mito, cancer_group_display, pal_cg, "Includes only non-mito genes. Colored by cancer group.")
+combine_plots(p1, p2)
+
+
+BIG@CHOP
sequencing center have unique mitochondrial gene distributions.04-explore-sequencing-center-effects.Rmd
notebook still are grouped together in these UMAPs.Overall, this suggests that mitochondrial genes alone will not have a strong influence on UMAP visualizations. However, there may still be protocol differences associated with BIG@CHOP samples that influence expression values more generally, and can not be corrected by removing only mitochondrial genes.
+sessionInfo()
+
+
+R version 3.6.0 (2019-04-26)
+Platform: x86_64-pc-linux-gnu (64-bit)
+Running under: Debian GNU/Linux 9 (stretch)
+
+Matrix products: default
+BLAS/LAPACK: /usr/lib/libopenblasp-r0.2.19.so
+
+locale:
+ [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
+ [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
+ [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=C
+ [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
+ [9] LC_ADDRESS=C LC_TELEPHONE=C
+[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
+
+attached base packages:
+[1] stats graphics grDevices utils datasets methods base
+
+other attached packages:
+[1] ggplot2_3.2.0 magrittr_1.5
+
+loaded via a namespace (and not attached):
+ [1] Rcpp_1.0.1 pillar_1.4.2 compiler_3.6.0 ggpubr_0.2.1
+ [5] forcats_0.4.0 base64enc_0.1-3 tools_3.6.0 digest_0.6.20
+ [9] jsonlite_1.6 evaluate_0.14 tibble_2.1.3 gtable_0.3.0
+[13] pkgconfig_2.0.2 rlang_0.4.0 yaml_2.2.0 xfun_0.8
+[17] withr_2.1.2 dplyr_0.8.3 stringr_1.4.0 knitr_1.23
+[21] hms_0.4.2 cowplot_0.9.4 rprojroot_1.3-2 grid_3.6.0
+[25] tidyselect_0.2.5 glue_1.3.1 R6_2.4.0 rmarkdown_1.13
+[29] tidyr_0.8.3 purrr_0.3.2 readr_1.3.1 scales_1.0.0
+[33] backports_1.1.4 htmltools_0.3.6 assertthat_0.2.1 colorspace_1.4-1
+[37] ggsignif_0.5.0 labeling_0.3 stringi_1.4.3 lazyeval_0.2.2
+[41] munsell_0.5.0 crayon_1.3.4
+
+
+