Clustering of spatial transcriptomes (Slide-seqV2)

Jialei Duan

2022-01-27


Stickels, R.R., Murray, E., Kumar, P., Li, J., Marshall, J.L., Di Bella, D.J., Arlotta, P., Macosko, E.Z., and Chen, F. (2020). Highly sensitive spatial transcriptomics at near-cellular resolution with Slide-seqV2. Nat. Biotechnol. 39, 313–319.


Rendered at 2022-01-27 12:39:56 America/Chicago.


Load required packages.

[1] "2022-01-27 12:39:57 CST"

Data preparation

Functions loading

source(
    file = file.path(
        SCRIPT_DIR,
        "utilities.R"
    )
)

Data loading

Matrix

PROJECT_DIR <- file.path(
    "/Users/jialei/Dropbox/Data/Projects/UTSW",
    "Spatial_sequencing/datasets/Slide-seqV2"
)
list.files(path = file.path(PROJECT_DIR, "raw/SCP815/other"))
 [1] "Puck_190921_19_bead_locations.csv.gz"    
 [2] "Puck_190921_19.digital_expression.txt.gz"
 [3] "Puck_190921_21_bead_locations.csv.gz"    
 [4] "Puck_190921_21.digital_expression.txt.gz"
 [5] "Puck_190926_01_bead_locations.csv.gz"    
 [6] "Puck_190926_01.digital_expression.txt.gz"
 [7] "Puck_190926_02_bead_locations.csv.gz"    
 [8] "Puck_190926_02.digital_expression.txt.gz"
 [9] "Puck_190926_03_bead_locations.csv.gz"    
[10] "Puck_190926_03.digital_expression.txt.gz"
[11] "Puck_190926_06_bead_locations.csv.gz"    
[12] "Puck_190926_06.digital_expression.txt.gz"
[13] "Puck_191007_07_bead_locations.csv.gz"    
[14] "Puck_191007_07.digital_expression.txt.gz"
[15] "Puck_191204_01_bead_locations.csv.gz"    
[16] "Puck_191204_01.digital_expression.txt.gz"
[17] "Puck_200115_08_bead_locations.csv.gz"    
[18] "Puck_200115_08.digital_expression.txt.gz"

mRNA detection sensitivity

Load matrix and coordinates.

matrix_readcount_use <- load_matrix(
    x = file.path(
        PROJECT_DIR,
        "raw/SCP815/other",
        "Puck_200115_08.digital_expression.txt.gz"
    )
)

barcode_location <- read_csv(
    file = file.path(
        PROJECT_DIR,
        "raw/SCP815/other",
        "Puck_200115_08_bead_locations.csv.gz"
    ),
    col_names = c("barcode", "x_coord", "y_coord"),
    skip = 1
)
Rows: 53208 Columns: 3
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (1): barcode
dbl (2): x_coord, y_coord

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
barcode_location |>
    head()
# A tibble: 6 × 3
  barcode        x_coord y_coord
  <chr>            <dbl>   <dbl>
1 AACGTCATAATCGT    889.   3220.
2 TACTTTAGCGCAGT   4762.   5020.
3 CATGCCTGGGTTCG    886.   3200.
4 TCGATATGGCACAA   2237.   5145.
5 TTATCTGACGAAGC   1032.   2425.
6 GATGCGACTCCTCG   5387    2292.

Create AnnData object.

ad <- reticulate::import(module = "anndata", convert = TRUE)
print(ad$`__version__`)
[1] "0.7.6"
adata <- ad$AnnData(
    X = t(matrix_readcount_use),
    obs = data.frame(
        cell = colnames(matrix_readcount_use),
        num_umis = colSums(matrix_readcount_use),
        mt_percentage = colSums(
            matrix_readcount_use[
                str_detect(
                    string = rownames(matrix_readcount_use),
                    pattern = "mt-"
                ),
            ]
        ) / colSums(matrix_readcount_use),
        row.names = colnames(matrix_readcount_use)
    ),
    var = data.frame(
        feature = rownames(matrix_readcount_use),
        row.names = rownames(matrix_readcount_use)
    )
)

file_name <- file.path(
    PROJECT_DIR,
    "matrix",
    "puck_200115_08.h5ad"
)
cat(file_name, "\n")
/Users/jialei/Dropbox/Data/Projects/UTSW/Spatial_sequencing/datasets/Slide-seqV2/matrix/puck_200115_08.h5ad 
if (!file.exists(file_name)) {
    adata$write_h5ad(
        filename = file_name,
        compression = "gzip",
        compression_opts = 9
    )
}
adata
AnnData object with n_obs × n_vars = 53208 × 23264
    obs: 'cell', 'num_umis', 'mt_percentage'
    var: 'feature'
adata$obs |> head()
                         cell num_umis mt_percentage
AACGTCATAATCGT AACGTCATAATCGT    23772    0.04029951
TACTTTAGCGCAGT TACTTTAGCGCAGT    19661    0.08031128
CATGCCTGGGTTCG CATGCCTGGGTTCG    15999    0.04419026
TCGATATGGCACAA TCGATATGGCACAA    15069    0.03610060
TTATCTGACGAAGC TTATCTGACGAAGC    14013    0.04859773
GATGCGACTCCTCG GATGCGACTCCTCG    12722    0.03049835
barcode_location <- barcode_location |>
    mutate(
        num_umis = colSums(matrix_readcount_use[, barcode]),
        num_features = colSums(matrix_readcount_use[, barcode] > 0),
        num_umis_mt = colSums(
            matrix_readcount_use[
                stringr::str_detect(
                    string = rownames(matrix_readcount_use),
                    pattern = "mt-"
                ),
                barcode
            ]
        ),
        mt_ratio = num_umis_mt / num_umis
    )

barcode_location |>
    summarise(
        num_cells = n(),
        median_umis = median(num_umis),
        median_features = median(num_features),
        median_mt_ratio = median(mt_ratio)
    ) |>
    gt::gt()
num_cells median_umis median_features median_mt_ratio
53208 302 235 0.08514392
purrr::map(seq(0, 1, 0.25), function(x) {
    cat(x, "\n")

    barcode_location |>
        summarise(
            num_umis = quantile(num_umis, x),
            num_features = quantile(num_features, x),
            mt_ratio = quantile(mt_ratio, x)
        ) |>
        mutate(
            quantile = x
        ) |>
        select(quantile, everything())
}) |>
    bind_rows() |>
    gt::gt() |>
    # gt::cols_label(n = "num_cells") |>
    gt::tab_options(table.font.size = "median")
0 
0.25 
0.5 
0.75 
1 
quantile num_umis num_features mt_ratio
0.00 10.00 6 0.00000000
0.25 118.00 98 0.04605263
0.50 302.00 235 0.08514392
0.75 736.25 553 0.15544586
1.00 23772.00 8557 0.68421053

Spatial visualization

GEOM_POINT_SIZE <- 0.5
RASTERISED <- TRUE

p_spatial_UMI <- plot_embedding(
    embedding = barcode_location |>
        dplyr::select(x_coord, y_coord),
    color_values = barcode_location$num_umis |> log10(),
    show_color_legend = TRUE,
    geom_point_size = GEOM_POINT_SIZE,
    sort_values = TRUE,
    rasterise = RASTERISED
) +
    ggplot2::coord_fixed(
        xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
        ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
    ) +
    theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
    theme_customized_void() +
    ggplot2::guides(
        color = ggplot2::guide_colourbar(
            title = expression(paste("log"[10], " (UMI)"))
        )
    ) +
    ggplot2::scale_color_gradientn(
        colors = colorRampPalette(
            colors = rev(
                x = RColorBrewer::brewer.pal(n = 11, name = "Spectral")
            )
        )(n = 100)
    )

p_spatial_features <- plot_embedding(
    embedding = barcode_location |>
        dplyr::select(x_coord, y_coord),
    color_values = barcode_location$num_features |> log10(),
    show_color_legend = TRUE,
    geom_point_size = GEOM_POINT_SIZE,
    sort_values = TRUE,
    rasterise = RASTERISED
) +
    ggplot2::coord_fixed(
        xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
        ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
    ) +
    theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
    theme_customized_void() +
    ggplot2::guides(
        color = ggplot2::guide_colourbar(
            title = expression(paste("log"[10], " (Genes)"))
        )
    ) +
    scale_color_gradientn(
        colors = colorRampPalette(
            colors = rev(
                x = RColorBrewer::brewer.pal(n = 11, name = "Spectral")
            )
        )(n = 100)
    )


Fig. 1a

purrr::map2(
    c("num_umis", "num_features"),
    c(
        expression(paste("log"[10], " (UMI)")),
        expression(paste("log"[10], " (Genes)"))
    ), function(x, y) {
        plot_embedding(
            embedding = barcode_location |>
                dplyr::select(x_coord, y_coord),
            color_values = barcode_location[[x]] |> log10(),
            show_color_legend = TRUE,
            geom_point_size = GEOM_POINT_SIZE,
            sort_values = TRUE,
            rasterise = RASTERISED
        ) +
            ggplot2::coord_fixed(
                xlim = quantile(barcode_location$x_coord,
                    probs = c(0.01, 0.99)
                ),
                ylim = quantile(barcode_location$y_coord,
                    probs = c(0.01, 0.99)
                )
            ) +
            theme_customized(
                x = 0.02, legend_key_size = 2, legend_text_size = 5
            ) +
            theme_customized_void() +
            ggplot2::guides(
                color = ggplot2::guide_colourbar(
                    title = y
                )
            ) +
            ggplot2::scale_color_gradientn(
                colors = colorRampPalette(
                    colors = rev(
                        x = RColorBrewer::brewer.pal(
                            n = 11,
                            name = "Spectral"
                        )
                    )
                )(n = 100)
            )
    }
) |>
    purrr::reduce(`+`) +
    patchwork::plot_layout(
        ncol = 2
    ) +
    patchwork::plot_annotation(
        theme = ggplot2::theme(plot.margin = ggplot2::margin())
    )

plot_embedding(
    embedding = barcode_location |>
        dplyr::select(x_coord, y_coord),
    color_values = barcode_location$mt_ratio,
    show_color_legend = TRUE,
    geom_point_size = GEOM_POINT_SIZE,
    sort_values = TRUE,
    rasterise = RASTERISED
) +
    ggplot2::coord_fixed(
        xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
        ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
    ) +
    theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
    theme_customized_void() +
    ggplot2::guides(
        color = ggplot2::guide_colourbar(
            title = "MT %"
        )
    ) +
    scale_color_gradientn(
        colors = colorRampPalette(
            colors = rev(
                x = RColorBrewer::brewer.pal(n = 11, name = "Spectral")
            )
        )(n = 100)
    )

Visualize cells with different numbers of genes detected.

purrr::map(c(200, 500, 1000, 2000), function(x) {
    plot_embedding(
        embedding = barcode_location |>
            dplyr::select(x_coord, y_coord),
        color_values = as.numeric(barcode_location$num_features >= x) |>
            as.factor(),
        show_color_legend = TRUE,
        geom_point_size = GEOM_POINT_SIZE / 1.5,
        sort_values = TRUE,
        rasterise = RASTERISED,
        dpi = 300
    ) +
        ggplot2::coord_fixed(
            xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
            ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
        ) +
        theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
        theme_customized_void() +
        scale_color_manual(
            values = c("grey70", "salmon"),
            labels = paste(c("<", ">="), x)
        )
}) |>
    purrr::reduce(`+`) +
    patchwork::plot_layout(
        ncol = 2
    ) +
    patchwork::plot_annotation(
        theme = ggplot2::theme(plot.margin = ggplot2::margin())
    )


Fig. 1c

purrr::map(c("Gapdh", "Atp2b1", "Ociad2", "Slc17a7"), function(x) {
    plot_embedding(
        embedding = barcode_location |>
            dplyr::select(x_coord, y_coord),
        color_values = log10(
            matrix_readcount_use[x, barcode_location$barcode] + 1
        ),
        show_color_legend = TRUE,
        geom_point_size = GEOM_POINT_SIZE,
        sort_values = TRUE,
        rasterise = RASTERISED,
        dpi = 600
    ) +
        ggplot2::coord_fixed(
            xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
            ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
        ) +
        theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
        theme_customized_void() +
        ggplot2::guides(
            color = ggplot2::guide_colourbar(
                title = x
            )
        ) +
        ggplot2::scale_color_gradientn(
            colors = colorRampPalette(
                colors = rev(
                    x = RColorBrewer::brewer.pal(n = 11, name = "Spectral")
                )
            )(n = 100)
        )
}) |>
    purrr::reduce(`+`) +
    patchwork::plot_layout(
        ncol = 2
    ) +
    patchwork::plot_annotation(
        theme = ggplot2::theme(plot.margin = ggplot2::margin())
    )

Clustering

embedding <- read_csv(
    file = file.path(
        PROJECT_DIR,
        "clustering/puck_200115_08/exploring",
        "embedding_ncomponents32_ccc1_seed20200416.csv.gz"
    )
)
Rows: 27680 Columns: 16
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (1): cell
dbl (14): louvain, leiden, x_tsne, y_tsne, x_umap, y_umap, x_fitsne, y_fitsn...
lgl  (1): batch

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
dim(embedding)
[1] 27680    16
embedding <- embedding |>
    dplyr::mutate(
        num_umis = colSums(matrix_readcount_use[, cell]),
        num_features = colSums(matrix_readcount_use[, cell] > 0),
        mt_ratio = colSums(
            matrix_readcount_use[
                stringr::str_detect(
                    string = rownames(matrix_readcount_use), pattern = "mt-"
                ),
                cell
            ]
        ) / num_umis
    )

embedding |>
    head() |>
    knitr::kable()
cell batch louvain leiden x_tsne y_tsne x_umap y_umap x_fitsne y_fitsne x_phate y_phate x_umap_min_dist=0.1 y_umap_min_dist=0.1 x_multicoretsne y_multicoretsne num_umis num_features mt_ratio
AAAAAATTTACAAC NA 3 2 -15.08988 80.86089 8.180862 12.681457 -26.663474 -38.30694 -0.0072554 -0.0072473 8.337963 12.029632 -0.7960197 -1.6586841 283 244 0.0777385
AAAAACACGGTGGT NA 5 3 12.26837 29.86188 2.751835 6.606259 6.250895 11.37395 0.0059024 -0.0029451 2.909990 7.214894 -0.2892767 -0.1141422 234 205 0.0470085
AAAAACCCCGTTAG NA 3 12 -22.61128 24.27204 6.830804 9.945548 -38.301001 9.58504 -0.0091227 -0.0084254 7.313702 8.334121 -0.7425821 -1.0912394 677 503 0.0487445
AAAAACGCTCCACA NA 15 16 -22.22501 -11.74047 2.259175 10.879986 -16.115118 -84.07885 -0.0053393 -0.0013187 3.089149 9.882877 -1.5145455 0.6562469 355 290 0.0704225
AAAAACTCTCTATT NA 0 0 15.82639 -91.21259 -2.902669 9.756977 38.563696 -55.52631 0.0141227 -0.0123033 -1.651397 8.959843 0.2110805 2.0115610 1592 1132 0.0188442
AAAAAGACATCACA NA 10 9 56.72704 -28.31702 -1.619180 6.661331 -1.730514 -53.68672 0.0032096 -0.0050529 -1.551058 6.617124 0.2128970 1.0833045 432 372 0.0486111
library(formattable)

embedding |>
    dplyr::group_by(leiden) |>
    dplyr::summarise(
        num_cells = n(),
        median_umis = median(num_umis),
        median_features = median(num_features),
        median_mt_ratio = median(mt_ratio)
    ) |>
    formattable::formattable(
        list(
            num_cells = formattable::color_bar("Lightpink"),
            median_umis = formattable::color_bar("lightgreen"),
            median_features = formattable::color_bar("lightblue"),
            median_mt_ratio = formattable::color_tile("transparent", "lightgrey")
        ),
        full_width = FALSE,
        caption = "Clustering"
    )
Clustering
leiden num_cells median_umis median_features median_mt_ratio
0 3791 979.0 737.0 0.04683728
1 3268 587.0 426.0 0.05598757
2 3205 451.0 351.0 0.09631148
3 2822 382.0 302.0 0.10734285
4 2074 1183.0 866.5 0.04478874
5 1729 968.0 724.0 0.03016241
6 1432 1070.0 781.0 0.03886781
7 1424 1236.0 924.0 0.02750982
8 1259 826.0 638.0 0.06024096
9 1247 796.0 612.0 0.05173913
10 1141 560.0 409.0 0.08976378
11 963 820.0 627.0 0.06049822
12 897 588.0 443.0 0.08113590
13 746 1159.5 892.0 0.03335862
14 551 1324.0 995.0 0.03610060
15 542 1282.0 785.5 0.05035454
16 362 479.5 359.5 0.09965678
17 227 567.0 445.0 0.08333333
EMBEDDING_TITLE_PREFIX <- "UMAP"
x_column <- "x_umap_min_dist=0.1"
y_column <- "y_umap_min_dist=0.1"

p_embedding_leiden <- plot_embedding(
    embedding = embedding[, c(x_column, y_column)],
    color_values = embedding$leiden |> as.factor(),
    label = paste(EMBEDDING_TITLE_PREFIX, "Leiden", sep = "; "),
    label_position = NULL,
    show_color_value_labels = TRUE,
    show_color_legend = FALSE,
    geom_point_size = GEOM_POINT_SIZE / 1.5,
    geom_point_alpha = 1,
    sort_values = FALSE,
    shuffle_values = TRUE,
    label_size = 6,
    label_hjust = 0,
    label_vjust = 0,
    rasterise = RASTERISED,
    dpi = 600,
    legend_size = 3,
    legend_ncol = 2
) +
    theme_customized()

p_embedding_UMI <- plot_embedding(
    embedding = embedding[, c(x_column, y_column)],
    color_values = embedding$num_umis |> log10(),
    label = paste(EMBEDDING_TITLE_PREFIX, "UMI", sep = "; "),
    show_color_legend = TRUE,
    geom_point_size = GEOM_POINT_SIZE / 1.5,
    sort_values = FALSE,
    shuffle_values = TRUE,
    rasterise = RASTERISED,
    dpi = 600
) +
    theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5)

p_embedding_MT <- plot_embedding(
    embedding = embedding[, c(x_column, y_column)],
    color_values = embedding$mt_ratio,
    label = paste0(EMBEDDING_TITLE_PREFIX, "; MT %"),
    show_color_legend = TRUE,
    geom_point_size = GEOM_POINT_SIZE,
    sort_values = TRUE,
    rasterise = RASTERISED,
    dpi = 600
) +
    theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5)

list(
    p_embedding_leiden,
    p_embedding_UMI,
    p_embedding_MT
) |>
    purrr::reduce(`+`) +
    patchwork::plot_layout(nrow = 1) +
    patchwork::plot_annotation(
        theme = theme(plot.margin = margin())
    )

barcode_location <- barcode_location |>
    left_join(
        embedding |> select(cell, leiden),
        by = c("barcode" = "cell")
    )
p_spatial_na <- plot_embedding(
    embedding = barcode_location |>
        dplyr::select(x_coord, y_coord),
    color_values = as.numeric(is.na(barcode_location$leiden)) |> as.factor(),
    show_color_legend = TRUE,
    geom_point_size = GEOM_POINT_SIZE / 1.5,
    sort_values = TRUE,
    rasterise = RASTERISED,
    dpi = 600
) +
    ggplot2::coord_fixed(
        xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
        ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
    ) +
    ggplot2::guides(
        colour = ggplot2::guide_legend(
            override.aes = list(size = 2),
            nrow = 2, title = NULL
        )
    ) +
    theme_customized(x = 0.02, legend_key_size = 1, legend_text_size = 5) +
    theme_customized_void() %+replace%
    ggplot2::theme(
        legend.justification = 0.5,
        legend.position = "bottom"
    ) +
    ggplot2::scale_color_manual(
        values = c("grey70", "salmon"),
        labels = c("incl.", "not incl.")
    )
p_spatial_cluster <- plot_embedding(
    embedding = barcode_location |>
        dplyr::select(x_coord, y_coord),
    color_values = barcode_location$leiden |> as.factor(),
    show_color_legend = TRUE,
    geom_point_size = GEOM_POINT_SIZE / 1.5,
    sort_values = FALSE,
    rasterise = RASTERISED,
    dpi = 600
) +
    coord_fixed(
        xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
        ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
    ) +
    guides(colour = guide_legend(override.aes = list(size = 2), nrow = 2, title = NULL)) +
    theme_customized(legend_key_size = 1, legend_text_size = 5) %+replace%
    theme_customized_void() %+replace%
    theme(
        legend.justification = 0.5,
        legend.position = "bottom"
    )


Clustering; Cells with fewer UMI and higher MT percentages are discarded.

list(
    p_spatial_na,
    p_spatial_cluster
) |>
    purrr::reduce(`+`) +
    patchwork::plot_layout(ncol = 2) +
    patchwork::plot_annotation(
        theme = theme(plot.margin = margin())
    )

purrr::map(sort(unique(embedding$leiden)), function(x) {
    values <- barcode_location$leiden == x
    # values <- values[! is.na(values)]
    values[is.na(values)] <- FALSE

    plot_embedding(
        embedding = barcode_location |>
            # dplyr::filter(! is.na(leiden)) |>
            dplyr::select(x_coord, y_coord),
        color_values = as.numeric(values) |> as.factor(),
        show_color_legend = TRUE,
        geom_point_size = GEOM_POINT_SIZE / 1.5,
        sort_values = TRUE,
        rasterise = RASTERISED,
        dpi = 300
    ) +
        ggplot2::coord_fixed(
            xlim = quantile(barcode_location$x_coord, probs = c(0.01, 0.99)),
            ylim = quantile(barcode_location$y_coord, probs = c(0.01, 0.99))
        ) +
        theme_customized(x = 0.02, legend_key_size = 2, legend_text_size = 5) +
        theme_customized_void() +
        ggplot2::scale_color_manual(
            values = c("grey70", "salmon"),
            labels = c("Other", x)
        )
}) |>
    purrr::reduce(`+`) +
    patchwork::plot_layout(ncol = 3) +
    patchwork::plot_annotation(
        theme = ggplot2::theme(plot.margin = ggplot2::margin())
    )


R session info

devtools::session_info()
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.1.2 (2021-11-01)
 os       macOS Monterey 12.2
 system   aarch64, darwin20.6.0
 ui       unknown
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/Chicago
 date     2022-01-27
 pandoc   2.17.0.1 @ /opt/homebrew/bin/ (via rmarkdown)

─ Packages ───────────────────────────────────────────────────────────────────
 package       * version     date (UTC) lib source
 assertthat      0.2.1       2019-03-21 [1] CRAN (R 4.1.1)
 backports       1.4.1       2021-12-13 [1] CRAN (R 4.1.2)
 beeswarm        0.4.0       2021-06-01 [1] CRAN (R 4.1.2)
 bit             4.0.4       2020-08-04 [1] CRAN (R 4.1.1)
 bit64           4.0.5       2020-08-30 [1] CRAN (R 4.1.1)
 brio            1.1.3       2021-11-30 [1] CRAN (R 4.1.2)
 broom           0.7.11      2022-01-03 [1] CRAN (R 4.1.2)
 cachem          1.0.6       2021-08-19 [1] CRAN (R 4.1.1)
 callr           3.7.0       2021-04-20 [1] CRAN (R 4.1.1)
 cellranger      1.1.0       2016-07-27 [1] CRAN (R 4.1.1)
 checkmate       2.0.0       2020-02-06 [1] CRAN (R 4.1.1)
 cli             3.1.1       2022-01-20 [1] CRAN (R 4.1.2)
 colorspace      2.0-2       2021-06-24 [1] CRAN (R 4.1.1)
 crayon          1.4.2       2021-10-29 [1] CRAN (R 4.1.1)
 data.table    * 1.14.2      2021-09-27 [1] CRAN (R 4.1.1)
 DBI             1.1.2       2021-12-20 [1] CRAN (R 4.1.2)
 dbplyr          2.1.1       2021-04-06 [1] CRAN (R 4.1.1)
 desc            1.4.0       2021-09-28 [1] CRAN (R 4.1.1)
 devtools        2.4.3.9000  2022-01-27 [1] Github (r-lib/devtools@41280ac)
 digest          0.6.29      2021-12-01 [1] CRAN (R 4.1.2)
 dplyr         * 1.0.7.9000  2022-01-27 [1] Github (tidyverse/dplyr@0501335)
 dtplyr          1.2.1.9000  2022-01-27 [1] Github (tidyverse/dtplyr@8542cf1)
 ellipsis        0.3.2       2021-04-29 [1] CRAN (R 4.1.1)
 evaluate        0.14        2019-05-28 [1] CRAN (R 4.1.1)
 extrafont     * 0.17        2014-12-08 [1] CRAN (R 4.1.1)
 extrafontdb     1.0         2012-06-11 [1] CRAN (R 4.1.1)
 fansi           1.0.2       2022-01-14 [1] CRAN (R 4.1.2)
 farver          2.1.0       2021-02-28 [1] CRAN (R 4.1.1)
 fastmap         1.1.0       2021-01-25 [1] CRAN (R 4.1.1)
 forcats       * 0.5.1.9000  2022-01-27 [1] Github (tidyverse/forcats@b4dade0)
 formattable   * 0.2.1       2021-01-07 [1] CRAN (R 4.1.2)
 fs              1.5.2.9000  2022-01-27 [1] Github (r-lib/fs@6d1182f)
 gargle          1.2.0       2021-07-02 [1] CRAN (R 4.1.1)
 generics        0.1.1       2021-10-25 [1] CRAN (R 4.1.1)
 ggbeeswarm      0.6.0       2017-08-07 [1] CRAN (R 4.1.2)
 ggplot2       * 3.3.5.9000  2022-01-27 [1] Github (tidyverse/ggplot2@c89c265)
 ggrastr         1.0.1       2021-12-08 [1] Github (VPetukhov/ggrastr@7aed9af)
 glue            1.6.1.9000  2022-01-27 [1] Github (tidyverse/glue@3da70df)
 googledrive     2.0.0       2021-07-08 [1] CRAN (R 4.1.1)
 googlesheets4   1.0.0       2021-07-21 [1] CRAN (R 4.1.1)
 gt              0.3.1       2021-08-07 [1] CRAN (R 4.1.2)
 gtable          0.3.0.9000  2022-01-27 [1] Github (r-lib/gtable@a0bd272)
 haven           2.4.3       2021-08-04 [1] CRAN (R 4.1.1)
 highr           0.9         2021-04-16 [1] CRAN (R 4.1.1)
 hms             1.1.1       2021-09-26 [1] CRAN (R 4.1.1)
 htmltools       0.5.2       2021-08-25 [1] CRAN (R 4.1.1)
 htmlwidgets     1.5.4       2021-09-08 [1] CRAN (R 4.1.1)
 httr            1.4.2       2020-07-20 [1] CRAN (R 4.1.1)
 jsonlite        1.7.3       2022-01-17 [1] CRAN (R 4.1.2)
 knitr           1.37        2021-12-16 [1] CRAN (R 4.1.2)
 labeling        0.4.2       2020-10-20 [1] CRAN (R 4.1.1)
 lattice         0.20-45     2021-09-22 [2] CRAN (R 4.1.2)
 lifecycle       1.0.1       2021-09-24 [1] CRAN (R 4.1.1)
 lubridate       1.8.0       2022-01-27 [1] Github (tidyverse/lubridate@566590f)
 magrittr        2.0.2       2022-01-26 [1] CRAN (R 4.1.2)
 Matrix        * 1.4-0       2021-12-08 [2] CRAN (R 4.1.2)
 memoise         2.0.1       2021-11-26 [1] CRAN (R 4.1.2)
 modelr          0.1.8.9000  2022-01-27 [1] Github (tidyverse/modelr@16168e0)
 munsell         0.5.0       2018-06-12 [1] CRAN (R 4.1.1)
 patchwork     * 1.1.0.9000  2022-01-27 [1] Github (thomasp85/patchwork@79223d3)
 pillar          1.6.5       2022-01-25 [1] CRAN (R 4.1.2)
 pkgbuild        1.3.1       2021-12-20 [1] CRAN (R 4.1.2)
 pkgconfig       2.0.3       2019-09-22 [1] CRAN (R 4.1.1)
 pkgload         1.2.4       2021-11-30 [1] CRAN (R 4.1.2)
 png             0.1-7       2013-12-03 [1] CRAN (R 4.1.1)
 prettyunits     1.1.1.9000  2022-01-27 [1] Github (r-lib/prettyunits@8706d89)
 processx        3.5.2       2021-04-30 [1] CRAN (R 4.1.1)
 ps              1.6.0       2021-02-28 [1] CRAN (R 4.1.1)
 purrr         * 0.3.4.9000  2022-01-27 [1] Github (tidyverse/purrr@5aca9df)
 R.cache         0.15.0      2021-04-30 [1] CRAN (R 4.1.1)
 R.methodsS3     1.8.1       2020-08-26 [1] CRAN (R 4.1.1)
 R.oo            1.24.0      2020-08-26 [1] CRAN (R 4.1.1)
 R.utils         2.11.0      2021-09-26 [1] CRAN (R 4.1.1)
 R6              2.5.1.9000  2022-01-27 [1] Github (r-lib/R6@1b05b89)
 ragg            1.2.1.9000  2022-01-27 [1] Github (r-lib/ragg@c68c666)
 RColorBrewer    1.1-2       2014-12-07 [1] CRAN (R 4.1.1)
 Rcpp            1.0.8       2022-01-13 [1] CRAN (R 4.1.2)
 readr         * 2.1.1.9000  2022-01-27 [1] Github (tidyverse/readr@718c42c)
 readxl          1.3.1.9000  2022-01-27 [1] Github (tidyverse/readxl@2ccb82c)
 remotes         2.4.2       2022-01-27 [1] Github (r-lib/remotes@9355549)
 reprex          2.0.1       2021-08-05 [1] CRAN (R 4.1.1)
 reticulate      1.24        2022-01-26 [1] CRAN (R 4.1.2)
 rlang           1.0.0.9000  2022-01-27 [1] Github (r-lib/rlang@27bcb65)
 rmarkdown       2.11.12     2022-01-27 [1] Github (rstudio/rmarkdown@b53a7ce)
 rprojroot       2.0.2       2020-11-15 [1] CRAN (R 4.1.1)
 rstudioapi      0.13.0-9000 2022-01-27 [1] Github (rstudio/rstudioapi@5d0f087)
 Rttf2pt1        1.3.9       2021-07-22 [1] CRAN (R 4.1.1)
 rvest           1.0.2       2021-10-16 [1] CRAN (R 4.1.1)
 sass            0.4.0       2021-05-12 [1] CRAN (R 4.1.1)
 scales          1.1.1       2020-05-11 [1] CRAN (R 4.1.1)
 sessioninfo     1.2.2       2021-12-06 [1] CRAN (R 4.1.2)
 stringi         1.7.6       2021-11-29 [1] CRAN (R 4.1.2)
 stringr       * 1.4.0.9000  2022-01-27 [1] Github (tidyverse/stringr@85f6140)
 styler        * 1.6.2.9000  2022-01-27 [1] Github (r-lib/styler@9274aed)
 systemfonts     1.0.3       2021-10-13 [1] CRAN (R 4.1.2)
 testthat        3.1.2.9000  2022-01-27 [1] Github (r-lib/testthat@54b9db2)
 textshaping     0.3.6       2021-10-13 [1] CRAN (R 4.1.1)
 tibble        * 3.1.6.9001  2022-01-27 [1] Github (tidyverse/tibble@64fefd5)
 tidyr         * 1.1.4.9000  2022-01-27 [1] Github (tidyverse/tidyr@d46d22a)
 tidyselect      1.1.1       2021-04-30 [1] CRAN (R 4.1.1)
 tidyverse     * 1.3.1.9000  2022-01-27 [1] Github (tidyverse/tidyverse@6186fbf)
 tzdb            0.2.0       2021-10-27 [1] CRAN (R 4.1.1)
 usethis         2.1.5.9000  2022-01-27 [1] Github (r-lib/usethis@57b109a)
 utf8            1.2.2       2021-07-24 [1] CRAN (R 4.1.1)
 vctrs           0.3.8       2021-04-29 [1] CRAN (R 4.1.1)
 vipor           0.4.5       2017-03-22 [1] CRAN (R 4.1.2)
 viridisLite     0.4.0       2021-04-13 [1] CRAN (R 4.1.1)
 vroom           1.5.7.9000  2022-01-27 [1] Github (r-lib/vroom@59261e3)
 withr           2.4.3       2021-11-30 [1] CRAN (R 4.1.2)
 xfun            0.29        2021-12-14 [1] CRAN (R 4.1.2)
 xml2            1.3.3       2021-11-30 [1] CRAN (R 4.1.2)
 yaml            2.2.2       2022-01-25 [1] CRAN (R 4.1.2)

 [1] /opt/homebrew/lib/R/4.1/site-library
 [2] /opt/homebrew/Cellar/r/4.1.2/lib/R/library

─ Python configuration ───────────────────────────────────────────────────────
 python:         /Users/jialei/.pyenv/shims/python
 libpython:      /Users/jialei/.pyenv/versions/miniforge3-4.10.1-5/lib/libpython3.9.dylib
 pythonhome:     /Users/jialei/.pyenv/versions/miniforge3-4.10.1-5:/Users/jialei/.pyenv/versions/miniforge3-4.10.1-5
 version:        3.9.5 | packaged by conda-forge | (default, Jun 19 2021, 00:24:55)  [Clang 11.1.0 ]
 numpy:          /Users/jialei/.pyenv/versions/miniforge3-4.10.1-5/lib/python3.9/site-packages/numpy
 numpy_version:  1.20.3
 anndata:        /Users/jialei/.pyenv/versions/miniforge3-4.10.1-5/lib/python3.9/site-packages/anndata
 
 NOTE: Python version was forced by RETICULATE_PYTHON

──────────────────────────────────────────────────────────────────────────────