|
| 1 | +# Cleanup |
| 2 | +rm(list = ls()) |
| 3 | + |
| 4 | +library(Seurat) |
| 5 | +library(ggplot2) |
| 6 | +library(paletteer) |
| 7 | +library(data.table) |
| 8 | +library(dbscan) |
| 9 | +library(pheatmap) |
| 10 | +library(tidyr) |
| 11 | + |
| 12 | +# Set working directory |
| 13 | +wd <- "" |
| 14 | +setwd(wd) |
| 15 | +rm(wd) |
| 16 | + |
| 17 | +# Make folders for output |
| 18 | +plot_dir <- "neighbourhood_plots" |
| 19 | +dir.create(path = plot_dir, showWarnings = F) |
| 20 | + |
| 21 | +data_dir <- "neighbourhood_data" |
| 22 | +dir.create(path = data_dir, showWarnings = F) |
| 23 | + |
| 24 | + |
| 25 | +# Load the Seurat objects with the clustering |
| 26 | +message("Loading data") |
| 27 | +mc_matched_hm <- readRDS("objects/clustered/re_matched_hm_clustered_2.RDS") # Molecular Cartography |
| 28 | +vz_matched_hm <- readRDS("objects/clustered/vz_matched_hm_clustered_2.RDS") # Merscope |
| 29 | +xen_matched_hm <- readRDS("objects/clustered/xen_matched_hm_clustered_2.RDS") # Xenium |
| 30 | + |
| 31 | +# Convert coluns with clusters to numeric and set the resolution |
| 32 | +mc_matched_hm@meta.data[grep("SCT", colnames(mc_matched_hm@meta.data))] <- lapply(mc_matched_hm@meta.data[grep("SCT", colnames(mc_matched_hm@meta.data))], as.numeric) |
| 33 | +vz_matched_hm@meta.data[grep("SCT", colnames(vz_matched_hm@meta.data))] <- lapply(vz_matched_hm@meta.data[grep("SCT", colnames(vz_matched_hm@meta.data))], as.numeric) |
| 34 | +xen_matched_hm@meta.data[grep("SCT", colnames(xen_matched_hm@meta.data))] <- lapply(xen_matched_hm@meta.data[grep("SCT", colnames(xen_matched_hm@meta.data))], as.numeric) |
| 35 | + |
| 36 | +mc_resolution <- "SCT_snn_res.0.55" |
| 37 | +vz_resolution <- "SCT_snn_res.0.55" |
| 38 | +xen_resolution <- "SCT_snn_res.0.55" |
| 39 | + |
| 40 | +# Manually annotated cells types: |
| 41 | +# See: https://www.nature.com/articles/s41467-023-44117-x/figures/7 |
| 42 | +message("Annotating clusters") |
| 43 | + |
| 44 | + |
| 45 | +# Molecular Cartography |
| 46 | +mc_cell_types <- c( |
| 47 | + "Early CGNP-like", "Differentiated neuronal-like", "Early CGNP-like, proliferating", |
| 48 | + "Stromal / Meningeal", "Late CGNP-like", "Stromal / Meningeal (2)", |
| 49 | + "Monocytes", "Migrating CGNP-like" , "Vascular / Endothelial", |
| 50 | + "Migrating CGNP-like (2)", "Other Immune", "TULP1+ cells", |
| 51 | + "Stromal / Meningeal (3)", "Astrocyte / Astrocytic-like") |
| 52 | +mc_matched_hm@meta.data$cell_types <- mc_cell_types[mc_matched_hm@meta.data[[mc_resolution]]] |
| 53 | +mc_resolution <- "cell_types" |
| 54 | + |
| 55 | +# Merscope |
| 56 | +vz_cell_types <- c( |
| 57 | + "Differentiated neuronal-like", "Early CGNP-like", "Early CGNP-like, proliferating", |
| 58 | + "Stromal / Meningeal", "Migrating CGNP-like", "Astrocyte / Astrocytic-like", |
| 59 | + "Differentiated neuronal-like (2)", "Monocytes", "Differentiated neuronal-like (3)", |
| 60 | + "Vascular / Endothelial", "Differentiated neuronal-like (4)", "Other Immune", |
| 61 | + "Other Immune (2)", "Other Immune (3)", "Early CGNP-like (2)") |
| 62 | + |
| 63 | +vz_matched_hm@meta.data$cell_types <- vz_cell_types[vz_matched_hm@meta.data[[vz_resolution]]] |
| 64 | +vz_resolution <- "cell_types" |
| 65 | + |
| 66 | +# Xenium |
| 67 | +xen_cell_types <- c( |
| 68 | + "Differentiated neuronal-like", "Differentiated neuronal-like (2)", "Other Immune", |
| 69 | + "Other Immune (2)", "B Cells", "Oligodendrocyte-like", |
| 70 | + "Differentiated neuronal-like (3)", "Late CGNP-like", "Early CGNP-like", |
| 71 | + "Vascular / Endothelial", "Stromal / Meningeal", "Monocytes", |
| 72 | + "Astrocyte / Astrocytic-like", "Differentiated neuronal-like (4)", |
| 73 | + "Early CGNP-like, proliferating") |
| 74 | + |
| 75 | +xen_matched_hm@meta.data$cell_types <- xen_cell_types[xen_matched_hm@meta.data[[xen_resolution]]] |
| 76 | +xen_resolution <- "cell_types" |
| 77 | + |
| 78 | +# Simplify the heatmaps by merging / excluding certain cell populations |
| 79 | +# Heatmaps with all cell types are also generated |
| 80 | +slimmed_cell_types = c("Astrocyte / Astrocytic-like" = "Astrocyte / Astrocytic-like", |
| 81 | + "Differentiated neuronal-like" = "Differentiated neuronal-like", |
| 82 | + "Differentiated neuronal-like (2)" = "Differentiated neuronal-like", |
| 83 | + "Differentiated neuronal-like (3)" = "Differentiated neuronal-like", |
| 84 | + "Differentiated neuronal-like (4)" = "Differentiated neuronal-like", |
| 85 | + "Oligodendrocyte-like" = "NA", |
| 86 | + "Early CGNP-like" = "CGNP-like", |
| 87 | + "Early CGNP-like (2)" = "CGNP-like", |
| 88 | + "Early CGNP-like, proliferating" = "Early CGNP-like, proliferating", |
| 89 | + "Late CGNP-like" = "CGNP-like", |
| 90 | + "Migrating CGNP-like" = "CGNP-like", |
| 91 | + "Migrating CGNP-like (2)" = "CGNP-like", |
| 92 | + "TULP1+ cells" = "NA", |
| 93 | + "Stromal / Meningeal" = "Stromal / Meningeal", |
| 94 | + "Stromal / Meningeal (2)" = "Stromal / Meningeal", |
| 95 | + "Stromal / Meningeal (3)" = "Stromal / Meningeal", |
| 96 | + "Vascular / Endothelial" = "Vascular / Endothelial", |
| 97 | + "Monocytes" = "Monocytes", |
| 98 | + "Other Immune" = "Other Immune", |
| 99 | + "Other Immune (2)" = "Other Immune", |
| 100 | + "Other Immune (3)" = "Other Immune", |
| 101 | + "Other Immune (4)" = "Other Immune", |
| 102 | + "B Cells" = "Other Immune") |
| 103 | + |
| 104 | +mc_matched_hm@meta.data$cell_types_slim <- slimmed_cell_types[mc_matched_hm@meta.data$cell_types] |
| 105 | +vz_matched_hm@meta.data$cell_types_slim <- slimmed_cell_types[vz_matched_hm@meta.data$cell_types] |
| 106 | +xen_matched_hm@meta.data$cell_types_slim <- slimmed_cell_types[xen_matched_hm@meta.data$cell_types] |
| 107 | + |
| 108 | +# Alphabetically sorted list for plotting |
| 109 | +genes <- sort(rownames(xen_matched_hm@assays$MultiTech@meta.features)) |
| 110 | + |
| 111 | +# Functions for neighbourhood and permutation tests |
| 112 | +############################## |
| 113 | +get_neighbours_all <- function(obj, sample_names, fovs, K = 10, n_perm = 5000, cores = 32) |
| 114 | +{ |
| 115 | + |
| 116 | + cell_list <-lapply(1:length(fovs), function(n){ |
| 117 | + # Get the K nearest neighbours |
| 118 | + knn <- kNN(obj@images[[fovs[[n]]]]$centroids@coords, k = K, sort = FALSE) |
| 119 | + |
| 120 | + # Assign cell types |
| 121 | + obj_cell_types <- obj@meta.data[obj@meta.data$orig.ident == sample_names[[n]],]$cell_types |
| 122 | + us_obj_cell_types <- sort(unique(obj_cell_types)) |
| 123 | + nbs <- vapply(X = knn$id, function(x){obj_cell_types[[x]]}, character(1)) |
| 124 | + dim(nbs) <- dim(knn$id) |
| 125 | + cbind(data.table(cell_type = obj_cell_types), as.data.table(nbs)) |
| 126 | + }) |
| 127 | + cells <- rbindlist(cell_list, use.names = TRUE, fill = FALSE, idcol = FALSE) |
| 128 | + |
| 129 | + # Make the interactions simmetrical and count |
| 130 | + cells <- melt(data = cells, id.vars = "cell_type", value.name = "cell_type2", value.factor = FALSE) |
| 131 | + cells[, variable := NULL] |
| 132 | + counts <- copy(cells) |
| 133 | + counts <- as.data.table(complete(data = counts, cell_type, cell_type2)) |
| 134 | + counts[, interaction := fifelse(cell_type < cell_type2, paste(cell_type, cell_type2, sep = ";"), paste(cell_type2, cell_type, sep = ";"))] |
| 135 | + counts <- unique(counts[, .N, by = interaction]) |
| 136 | + counts[, c("cell_type1", "cell_type2") := tstrsplit(x = interaction, split = ";")] |
| 137 | + counts[, interaction := NULL] |
| 138 | + |
| 139 | + # Make permutations by shuffling the interacting cell types |
| 140 | + permutations <- parallel::mclapply(1:n_perm, function(n){ |
| 141 | + pcells <- copy(cells) |
| 142 | + pcells$cell_type <- sample(x = pcells$cell_type, size = length(pcells$cell_type), replace = FALSE) |
| 143 | + pcells$cell_type2 <- sample(x = pcells$cell_type2, size = length(pcells$cell_type2), replace = FALSE) |
| 144 | + pcells <- as.data.table(complete(data = pcells, cell_type, cell_type2)) |
| 145 | + pcells[, interaction := fifelse(cell_type < cell_type2, paste(cell_type, cell_type2, sep = ";"), paste(cell_type2, cell_type, sep = ";"))] |
| 146 | + pcells <- unique(pcells[, .N, by = interaction]) |
| 147 | + pcells[, c("cell_type1", "cell_type2") := tstrsplit(x = interaction, split = ";")] |
| 148 | + pcells[, interaction := NULL] |
| 149 | + return(pcells) |
| 150 | + }, mc.cores = cores, mc.allow.recursive = TRUE) |
| 151 | + permutations <- rbindlist(permutations, idcol = "permutation") |
| 152 | + |
| 153 | + return(list(cells = cells, counts = counts, permutations = permutations)) |
| 154 | + |
| 155 | +} |
| 156 | + |
| 157 | +get_pvals_all <- function(permutations, counts, n_perm) { |
| 158 | + pvals <- copy(permutations) |
| 159 | + pvals[, difference := counts$N - N, by = permutation] |
| 160 | + pvals[, zeta := mean(difference) / sd(difference), by = c("cell_type1", "cell_type2")] # µ(a - X) = a - µ(X) and sd(a - X) = sd(X) |
| 161 | + pvals[, greater := (sum(difference < 0) + 1) / (n_perm + 1), by = c("cell_type1", "cell_type2")] # https://pubmed.ncbi.nlm.nih.gov/21044043/ |
| 162 | + pvals[, lower := (sum(difference > 0) + 1) / (n_perm + 1), by = c("cell_type1", "cell_type2")] |
| 163 | + pvals[, greater_bh := p.adjust(greater, method = "BH")] |
| 164 | + pvals[, lower_bh := p.adjust(lower, method = "BH")] |
| 165 | + pvals[, pvalue := fifelse(lower < greater, lower, greater)] |
| 166 | + pvals[, pvalue_bh := fifelse(lower_bh < greater_bh, lower_bh, greater_bh)] |
| 167 | + pvals[, score := fifelse(lower < greater, -1 + lower, 1 - greater)] |
| 168 | + pvals[, score := fifelse(pvalue > 0.05, NA, score)] |
| 169 | + pvals[, score_bh := fifelse(lower_bh < greater_bh, -1 + lower_bh, 1 - greater_bh)] |
| 170 | + pvals[, score_bh := fifelse(pvalue_bh > 0.05, NA, score_bh)] |
| 171 | + pvals[, zeta := fifelse(pvalue_bh > 0.05, NA, zeta)] |
| 172 | + pvals <- unique(pvals[, .(cell_type1, cell_type2, zeta, greater, lower, pvalue, score, greater_bh, lower_bh, pvalue_bh, score_bh)]) |
| 173 | + return(pvals) |
| 174 | +} |
| 175 | + |
| 176 | +# Heatmaps drawing functions with p-value / z-score |
| 177 | +################################################## |
| 178 | +nn_heatmapper <- function(pm, title = NULL){ |
| 179 | + ggplot(data = pm[order(cell_type1, cell_type2)], aes(x=cell_type1, y=cell_type2, fill=score_bh)) + |
| 180 | + geom_tile() + theme_minimal() + coord_fixed() + labs(x = NULL, y = NULL, title = title) + |
| 181 | + scale_fill_gradient2(name = NULL, low = "blue", high = "red", mid = "white", |
| 182 | + midpoint = 0.0, limit = c(-1,1), space = "Lab") + |
| 183 | + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) |
| 184 | +} |
| 185 | + |
| 186 | +nn_heatmapper_z <- function(pm, title = NULL){ |
| 187 | + ggplot(data = pm[order(cell_type1, cell_type2)], aes(x=cell_type1, y=cell_type2, fill=zeta)) + |
| 188 | + geom_tile() + theme_minimal() + coord_fixed() + labs(x = NULL, y = NULL, title = title) + |
| 189 | + scale_fill_gradient2(name = NULL, low = "blue", high = "red", mid = "white", |
| 190 | + midpoint = 0.0, space = "Lab") + |
| 191 | + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) |
| 192 | +} |
| 193 | +#################################################### |
| 194 | + |
| 195 | +################################################################### |
| 196 | +n_perm = 10000 # Permutations |
| 197 | +K = 10 # Number of nearest neighbours |
| 198 | + |
| 199 | +message("Subsetting objects") |
| 200 | +xen_nn_obj <- subset(xen_matched_hm, subset = cell_types_slim != "NA") |
| 201 | +mc_nn_obj <- subset(mc_matched_hm, subset = cell_types_slim != "NA") |
| 202 | +vz_nn_obj <- subset(vz_matched_hm, subset = cell_types_slim != "NA") |
| 203 | + |
| 204 | +xen_nn_obj@meta.data$cell_types <- slimmed_cell_types[xen_nn_obj@meta.data$cell_types] |
| 205 | +mc_nn_obj@meta.data$cell_types <- slimmed_cell_types[mc_nn_obj@meta.data$cell_types] |
| 206 | +vz_nn_obj@meta.data$cell_types <- slimmed_cell_types[vz_nn_obj@meta.data$cell_types] |
| 207 | + |
| 208 | +message("Neighbours Xenium all clusters") |
| 209 | +xen_neighbours_all <- get_neighbours_all(xen_matched_hm, c("mb266.Xenium", "mb295.Xenium"), c("mb266.Xenium", "mb295.Xenium"), K = K, n_perm = n_perm) |
| 210 | +message("Pvalues Xenium all clusters") |
| 211 | +xen_pvals_all <- get_pvals_all(xen_neighbours_all$permutations, xen_neighbours_all$counts, n_perm = n_perm) |
| 212 | +message("Saving data") |
| 213 | +fwrite(x = xen_pvals_all, file = file.path(data_dir, "/xen_nn_10-10000_all_pvals.csv")) |
| 214 | +message("Making heatmaps") |
| 215 | +xen_nn_heatmap_all_p <- nn_heatmapper(xen_pvals_all, "Xenium") |
| 216 | +xen_nn_heatmap_all_z <- nn_heatmapper_z(xen_pvals_all, "Xenium") |
| 217 | +message("Saving heatmaps") |
| 218 | +ggsave(plot = xen_nn_heatmap_all_p, filename = file.path(plot_dir, "/xen_nn_10-10000_all_p_bh_heatmap.pdf"), width = 20, height = 20) |
| 219 | +ggsave(plot = xen_nn_heatmap_all_z, filename = file.path(plot_dir, "/xen_nn_10-10000_all_z_bh_heatmap.pdf"), width = 20, height = 20) |
| 220 | +rm(xen_neighbours_all) |
| 221 | +gc() |
| 222 | + |
| 223 | +message("Neighbours Xenium selected clusters") |
| 224 | +xen_neighbours_slim <- get_neighbours_all(xen_nn_obj, c("mb266.Xenium", "mb295.Xenium"), c("mb266.Xenium", "mb295.Xenium"), K = K, n_perm = n_perm) |
| 225 | +message("Pvalues Xenium selected clusters") |
| 226 | +xen_pvals_slim <- get_pvals_all(xen_neighbours_slim$permutations, xen_neighbours_slim$counts, n_perm = n_perm) |
| 227 | +message("Saving data") |
| 228 | +fwrite(x = xen_pvals_slim, file = file.path(data_dir, "/xen_nn_10-10000_slim_pvals.csv")) |
| 229 | +message("Making heatmaps") |
| 230 | +xen_nn_heatmap_slim_p <- nn_heatmapper(xen_pvals_slim, "Xenium") |
| 231 | +xen_nn_heatmap_slim_z <- nn_heatmapper_z(xen_pvals_slim, "Xenium") |
| 232 | +message("Saving heatmaps") |
| 233 | +ggsave(plot = xen_nn_heatmap_slim_p, filename = file.path(plot_dir, "/xen_nn_10-10000_slim_p_bh_heatmap.pdf"), width = 20, height = 20) |
| 234 | +ggsave(plot = xen_nn_heatmap_slim_z, filename = file.path(plot_dir, "/xen_nn_10-10000_slim_z_bh_heatmap.pdf"), width = 20, height = 20) |
| 235 | +rm(xen_neighbours_slim) |
| 236 | +gc() |
| 237 | + |
| 238 | +message("Neighbours MC all clusters") |
| 239 | +mc_neighbours_all <- get_neighbours_all(mc_matched_hm, c("mb266.w5a1.MC", "mb295.w6a1.MC", "mb295.w6a2.MC"), c("mb266.w5a1.Resolve", "mb295.w6a1.Resolve", "mb295.w6a2.Resolve"), K = K, n_perm = n_perm) |
| 240 | +message("Pvalues MC all clusters") |
| 241 | +mc_pvals_all <- get_pvals_all(mc_neighbours_all$permutations, mc_neighbours_all$counts, n_perm = n_perm) |
| 242 | +message("Saving data") |
| 243 | +fwrite(x = mc_pvals_all, file = file.path(data_dir, "/mc_nn_10-10000_all_pvals.csv")) |
| 244 | +message("Making heatmaps") |
| 245 | +mc_nn_heatmap_all_p <- nn_heatmapper(mc_pvals_all, "Molecular Cartography") |
| 246 | +mc_nn_heatmap_all_z <- nn_heatmapper_z(mc_pvals_all, "Molecular Cartography") |
| 247 | +message("Saving heatmaps") |
| 248 | +ggsave(plot = mc_nn_heatmap_all_p, filename = file.path(plot_dir, "/mc_nn_10-10000_all_p_bh_heatmap.pdf"), width = 20, height = 20) |
| 249 | +ggsave(plot = mc_nn_heatmap_all_z, filename = file.path(plot_dir, "/mc_nn_10-10000_all_z_bh_heatmap.pdf"), width = 20, height = 20) |
| 250 | +rm(mc_neighbours_all) |
| 251 | +gc() |
| 252 | + |
| 253 | +message("Neighbours MC selected clusters") |
| 254 | +mc_neighbours_slim <- get_neighbours_all(mc_nn_obj, c("mb266.w5a1.MC", "mb295.w6a1.MC", "mb295.w6a2.MC"), c("mb266.w5a1.Resolve", "mb295.w6a1.Resolve", "mb295.w6a2.Resolve"), K =K, n_perm = n_perm) |
| 255 | +message("Pvalues MC selected clusters") |
| 256 | +mc_pvals_slim <- get_pvals_all(mc_neighbours_slim$permutations, mc_neighbours_slim$counts, n_perm = n_perm) |
| 257 | +message("Saving data") |
| 258 | +fwrite(x = mc_pvals_slim, file = file.path(data_dir, "/mc_nn_10-10000_slim_pvals.csv")) |
| 259 | +message("Making heatmaps") |
| 260 | +mc_nn_heatmap_slim_p <- nn_heatmapper(mc_pvals_slim, "Molecular Cartography") |
| 261 | +mc_nn_heatmap_slim_z <- nn_heatmapper_z(mc_pvals_slim, "Molecular Cartography") |
| 262 | +message("Saving heatmaps") |
| 263 | +ggsave(plot = mc_nn_heatmap_slim_p, filename = file.path(plot_dir, "/mc_nn_10-10000_slim_p_bh_heatmap.pdf"), width = 20, height = 20) |
| 264 | +ggsave(plot = mc_nn_heatmap_slim_z, filename = file.path(plot_dir, "/mc_nn_10-10000_slim_z_bh_heatmap.pdf"), width = 20, height = 20) |
| 265 | +rm(mc_neighbours_slim) |
| 266 | +gc() |
| 267 | + |
| 268 | +message("Neighbours Merscope all clusters") |
| 269 | +vz_neighbours_all <- get_neighbours_all(vz_matched_hm, c("mb266.region1.MERFISH", "mb295.region0.MERFISH"), c("mb266.region1.Vizgen", "mb295.region0.Vizgen"), K = K, n_perm = n_perm) |
| 270 | +message("Pvalues Merscope all clusters") |
| 271 | +vz_pvals_all <- get_pvals_all(vz_neighbours_all$permutations, vz_neighbours_all$counts, n_perm = n_perm) |
| 272 | +message("Saving data") |
| 273 | +fwrite(x = vz_pvals_all, file = file.path(data_dir, "/vz_nn_100-10000_all_pvals.csv")) |
| 274 | +message("Making heatmaps") |
| 275 | +vz_nn_heatmap_all_p <- nn_heatmapper(vz_pvals_all, "Merscope") |
| 276 | +vz_nn_heatmap_all_z <- nn_heatmapper_z(vz_pvals_all, "Merscope") |
| 277 | +message("Saving heatmaps") |
| 278 | +ggsave(plot = vz_nn_heatmap_all_p, filename = file.path(plot_dir, "/vz_nn_10-10000_all_p_bh_heatmap.pdf"), width = 20, height = 20) |
| 279 | +ggsave(plot = vz_nn_heatmap_all_z, filename = file.path(plot_dir, "/vz_nn_10-10000_all_z_bh_heatmap.pdf"), width = 20, height = 20) |
| 280 | +rm(vz_neighbours_all) |
| 281 | +gc() |
| 282 | + |
| 283 | +message("Neighbours Merscope selected clusters") |
| 284 | +vz_neighbours_slim <- get_neighbours_all(vz_nn_obj, c("mb266.region1.MERFISH", "mb295.region0.MERFISH"), c("mb266.region1.Vizgen", "mb295.region0.Vizgen"), K = K, n_perm = n_perm) |
| 285 | +message("Pvalues Merscope selected clusters") |
| 286 | +vz_pvals_slim <- get_pvals_all(vz_neighbours_slim$permutations, vz_neighbours_slim$counts, n_perm = n_perm) |
| 287 | +message("Saving data") |
| 288 | +fwrite(x = vz_pvals_slim, file = file.path(data_dir, "/vz_nn_10-10000_slim_pvals.csv")) |
| 289 | +message("Making heatmaps") |
| 290 | +vz_nn_heatmap_slim_p <- nn_heatmapper(vz_pvals_slim, "Merscope") |
| 291 | +vz_nn_heatmap_slim_z <- nn_heatmapper_z(vz_pvals_slim, "Merscope") |
| 292 | +message("Saving heatmaps") |
| 293 | +ggsave(plot = vz_nn_heatmap_slim_p, filename = file.path(plot_dir, "/vz_nn_10-10000_slim_p_bh_heatmap.pdf"), width = 20, height = 20) |
| 294 | +ggsave(plot = vz_nn_heatmap_slim_z, filename = file.path(plot_dir, "/vz_nn_10-10000_slim_z_bh_heatmap.pdf"), width = 20, height = 20) |
| 295 | +rm(vz_neighbours_slim) |
| 296 | +gc() |
| 297 | + |
0 commit comments