{"metadata":{"kernelspec":{"name":"ir","display_name":"R","language":"R"},"language_info":{"name":"R","codemirror_mode":"r","pygments_lexer":"r","mimetype":"text/x-r-source","file_extension":".r","version":"4.0.5"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<h3>What we do here:</h3>\n<div style=\"line-height:24px; font-size:16px\">\n    <ul style=\"list-style:circle\">\n<li>Examine data for the <a href=\"https://www.kaggle.com/competitions/open-problems-single-cell-perturbations\">Open Problems – Single-Cell Perturbations competition</a>\n<li>Perform Multidimensional Scaling (MDS) on DE values\n<li>Investigate how many genes are significantly affected by the compounds in each cell type\n<li>Plot the number of significantly affected genes vs the number of cells per compound by cell types <strong>(new)</strong>\n<li>Compute circular fingerprints for the chemical structures to generate a hierarchical clustering\n    </ul>\n</div>","metadata":{}},{"cell_type":"markdown","source":"<hr>\n\n<h3>Data</h3> \n\n<div style=\"line-height:24px; font-size:14px\">\n    .parquet files for the main and supplemental train data, csv files with metadata and test ids.  \n</div>\n<hr>","metadata":{}},{"cell_type":"code","source":"library(arrow)\nlibrary(data.table)\nlibrary(pheatmap)\nlibrary(ggplot2)\nlibrary(patchwork)\nlibrary(vegan) # NMDS\nlibrary(dplyr) # subset data from arrow object\nlibrary(qs)\n\n# the package factoextra useful for MDS is not compatible with the kagge R version, so...\nR.version.string\npackageurl <- \"https://cran.r-project.org/src/contrib/Archive/pbkrtest/pbkrtest_0.4-4.tar.gz\"\ninstall.packages(packageurl, repos=NULL, type=\"source\")\npackageurl <- \"https://cran.r-project.org/src/contrib/Archive/emmeans/emmeans_1.5.5-1.tar.gz\"\ninstall.packages(packageurl, repos=NULL, type=\"source\")\n\ninstall.packages(\"factoextra\")\nlibrary(factoextra)\n# The same issue is with ggpubr (needs car, so load it at the end)\nlibrary(ggpubr)","metadata":{"_uuid":"051d70d956493feee0c6d64651c6a088724dca2a","_execution_state":"idle","execution":{"iopub.status.busy":"2023-11-05T07:03:25.479494Z","iopub.execute_input":"2023-11-05T07:03:25.518939Z","iopub.status.idle":"2023-11-05T07:06:01.869121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig <- function(width, heigth){\n  options(repr.plot.width = width, repr.plot.height = heigth)\n}\n\ndata.summary <- function(dt) {\n    \n    cat(\"\\nShape: \", ncol(dt), \" columns x \",\n        nrow(dt), \" rows\", sep = \"\")  \n    \n    non_num_cols <- names(dt)[!unlist(lapply(dt, is.numeric))]\n    unique_counts <- data.table(\n        \"column\" = non_num_cols,\n        \"data_type\" = unlist(lapply(dt[, ..non_num_cols], class),\n                             use.names = FALSE),\n        \"unique_count\" = lapply(dt[, ..non_num_cols], uniqueN),\n        \"is_NA?\" = lapply(dt[, ..non_num_cols], function(x) any(is.na(x)))\n        )\n    cat(\"\\nNon-numeric columns:\\n\\n\")\n    print(unique_counts)\n}","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:06:16.239174Z","iopub.execute_input":"2023-11-05T07:06:16.240973Z","iopub.status.idle":"2023-11-05T07:06:16.604263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <p style=\"background-color:#435334;font-family:Verdana;color:white;font-size:100%;text-align:left;border-radius: 15px;padding:10px 15px\">Main train data</p>","metadata":{}},{"cell_type":"markdown","source":"From the competition [description](https://www.kaggle.com/competitions/open-problems-single-cell-perturbations/data):\nThe **de_train.parquet** file comprises the main competition data. It contains values for a number of cell_type / sm_name pairs.\n\n- cell_type - The annotated cell type of each cell based on RNA expression.\n- sm_name - The primary name for the (parent) compound (in a standardized representation) as chosen by LINCS. This is provided to map the data in this experiment to the LINCS Connectivity Map data.\n- sm_lincs_id - The global LINCS ID (parent) compound (in a standardized representation). This is provided to map the data in this experiment to the [LINCS Connectivity Map data](https://maayanlab.cloud/Harmonizome/resource/LINCS+L1000+Connectivity+Map).\n- SMILES - Simplified molecular-input line-entry system (SMILES) representations of the compounds used in the experiment. This is a 1D representation of molecular structure. These SMILES are provided by Cellarity based on the specific compounds ordered for this experiment.\n- control - Boolean indicating whether this instance was used as a control.\n- genes A1BG, A1BG-AS1, …, ZZEF1 (numbering 18,211 in all) - Differential expression value **(-log10(p-value) * sign(LFC))** for each gene.","metadata":{}},{"cell_type":"code","source":"de_train <- read_parquet('/kaggle/input/open-problems-single-cell-perturbations/de_train.parquet')\nde_train <- setDT(de_train)\n\nhead(de_train)\ndata.summary(de_train)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:45:00.286190Z","iopub.execute_input":"2023-11-05T05:45:00.287221Z","iopub.status.idle":"2023-11-05T05:45:07.707605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Number of compounds per cell type:","metadata":{}},{"cell_type":"code","source":"de_train[, .N, by = \"cell_type\"]","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:45:07.709468Z","iopub.execute_input":"2023-11-05T05:45:07.710465Z","iopub.status.idle":"2023-11-05T05:45:07.735676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Number of rows with data (= number of cell types) per compounds:","metadata":{}},{"cell_type":"code","source":"de_train[, .(num_cell_types = .N), by = \"sm_name\"][\n    , .(num_compounds = .N), by = \"num_cell_types\"]","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:45:07.737934Z","iopub.execute_input":"2023-11-05T05:45:07.738887Z","iopub.status.idle":"2023-11-05T05:45:07.759012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cat(\"Drugs with data for 3 cell types only\")\nde_train[, .N, by = \"sm_name\"][N == 3]\ncat(\"\\nDrugs with data for 5 cell types\")\nde_train[, .N, by = \"sm_name\"][N == 5]\ncat(\"\\nDrugs with data for all 6 cell types\")\nde_train[, .N, by = \"sm_name\"][N == 6]","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:45:07.761966Z","iopub.execute_input":"2023-11-05T05:45:07.763004Z","iopub.status.idle":"2023-11-05T05:45:07.832859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# - Differential expression (DE)","metadata":{}},{"cell_type":"markdown","source":"Differential expression (DE) values in the data, as indicated in the description, are calculated as (-log10(p-value) * sign(LFC)), where:\n- -log10(p-value) represents the transformation of the p-value into a more interpretable scale\n- sign(LFC) represents the direction of the expression change (positive or negative)  \nThus, for each DE value (x) we can back-calculate the p-value (10^x) of the significance of the expression change and determine the direction of the change (sign(x)). Let's see the range of the given DE values.","metadata":{}},{"cell_type":"code","source":"cat(\"For all compounds, cell types, genes:\\n\")\nval_range <- de_train[,\n         .(min_value = apply(de_train[, 6:ncol(de_train)], 1, min),\n           max_value = apply(de_train[, 6:ncol(de_train)], 1, max))]\n\ncat(\"Min DE value = \", min(val_range[, min_value]), \"\\n\",\n    \"Max DE value = \", max(val_range[, max_value]), sep = \"\")","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:45:07.835395Z","iopub.execute_input":"2023-11-05T05:45:07.836655Z","iopub.status.idle":"2023-11-05T05:45:09.772982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Multidimensional Scaling (MDS)**","metadata":{}},{"cell_type":"markdown","source":" NMDS (Non-Metric Multidimensional Scaling) is a technique used for reducing the dimensionality (here - to 2 coordinates) and visualizing the dissimilarity between samples.","metadata":{}},{"cell_type":"code","source":"dist_matrix <- dist(as.matrix(de_train[, 6:ncol(de_train)]),\n                    method = \"euclidean\")\nnmds_result <- metaMDS(dist_matrix)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:45:09.774737Z","iopub.execute_input":"2023-11-05T05:45:09.775830Z","iopub.status.idle":"2023-11-05T05:46:02.919811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(20, 10)\n\nplot_data <- data.frame(\n  NMDS1 = nmds_result$points[, 1],\n  NMDS2 = nmds_result$points[, 2],\n  Cell_Type = de_train$cell_type,\n  Color = factor(de_train$cell_type)\n)\n\ncolors <- rainbow(length(unique(de_train$cell_type)))\n\nggplot(plot_data, aes(x = NMDS1, y = NMDS2)) +\n  geom_point(aes(fill = Color), shape = 21, size = 4) +\n  ggtitle(\"Multidimensional Scaling (MDS) of DE values using Euclidean distance\") +\n  scale_fill_manual(values = colors) +\n  theme_bw(base_size = 22) +\n  theme(legend.position = \"right\")","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:46:02.921503Z","iopub.execute_input":"2023-11-05T05:46:02.922553Z","iopub.status.idle":"2023-11-05T05:46:03.622375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"line-height:24px; font-size:16px;border-left: 5px solid silver; padding-left: 26px;\"> \n    💡 Note: \n    <ul style=\"list-style:circle\">\n<li>NMDS is a dimensionality reduction technique, so NMDS1 and NMDS2 are the two axes that best represent the dissimilarity between samples \n<li>Colors show how different cell types are distributed in this space\n<li>There are plenty of outliers\n<li>The separation between clusters is weak, indicating that the differences in the gene expression profiles (to be  precise, in (-log10(p-value) * sign(LFC)) values) are not captured\n    </ul>\n</div>","metadata":{}},{"cell_type":"markdown","source":"**Significant differential expression**","metadata":{}},{"cell_type":"markdown","source":"First, we calculate p-values, and also multiply them by the sign of the DE value (to keeep the direction of the expression change).","metadata":{}},{"cell_type":"code","source":"num_cols <- names(de_train)[unlist(lapply(de_train, is.numeric))]\npval_train <- copy(de_train)\npval_train <- pval_train[, (num_cols) := \n                lapply(.SD, function(x) sign(x) * 10^(-1 * abs(x)) ),\n                .SDcols = num_cols                    \n            ] \nhead(pval_train)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:46:03.624249Z","iopub.execute_input":"2023-11-05T05:46:03.625228Z","iopub.status.idle":"2023-11-05T05:46:11.531953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_range <- pval_train[,\n         .(min_value = apply(pval_train[, 6:ncol(pval_train)], 1, min),\n           max_value = apply(pval_train[, 6:ncol(pval_train)], 1, max))]\n\ncat(\"Min p-value = \", min(val_range[, min_value]), \"\\n\",\n    \"Max p-value = \", max(val_range[, max_value]), sep = \"\")","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:46:11.533707Z","iopub.execute_input":"2023-11-05T05:46:11.535356Z","iopub.status.idle":"2023-11-05T05:46:12.938243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next, we check if there are genes, that does not significantly change with any of the compounds tested (undependent of the cell types)","metadata":{}},{"cell_type":"code","source":"all_non_sign <- \n    unlist(pval_train[,\n                      lapply(.SD, function(x) all(abs(x) >= 0.05)),\n                      .SDcols = num_cols\n                      ])\nany(all_non_sign)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:46:12.939990Z","iopub.execute_input":"2023-11-05T05:46:12.940949Z","iopub.status.idle":"2023-11-05T05:46:15.228372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"line-height:24px; font-size:16px;border-left: 5px solid silver; padding-left: 26px;\"> \n    💡 Note: The expression of all genes was significantly affected by at least one compound\n</div>","metadata":{}},{"cell_type":"markdown","source":"**Multidimensional Scaling (MDS) of p-values**","metadata":{}},{"cell_type":"markdown","source":"- Correlation based distance","metadata":{}},{"cell_type":"code","source":"pval_mat <- as.matrix(pval_train[, 6:ncol(pval_train)])\n#pval_mat <- abs(pval_mat)\n\ndist_matrix <- get_dist(x = pval_mat,\n                        method = \"pearson\")\ncat(\"Pearson correlation based distance\", \"\\n\")\nnmds_result_pear <- metaMDS(dist_matrix)\n\ndist_matrix <- get_dist(x = pval_mat,\n                        method = \"spearman\")\ncat(\"\\n\", \"Spearman correlation based distance\", \"\\n\")\nnmds_result_spear <- metaMDS(dist_matrix)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:46:15.230155Z","iopub.execute_input":"2023-11-05T05:46:15.231122Z","iopub.status.idle":"2023-11-05T05:47:15.915100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(25, 10)\n\nplot_data <- data.frame(\n  NMDS1 = nmds_result_pear$points[, 1],\n  NMDS2 = nmds_result_pear$points[, 2],\n  Cell_Type = de_train$cell_type,\n  Color = factor(de_train$cell_type)\n)\n\np1 <- ggplot(plot_data, aes(x = NMDS1, y = NMDS2)) +\n  geom_point(aes(fill = Color), shape = 21, size = 4) +\n  ggtitle(\"Pearson correlation based distance\") +\n  scale_fill_manual(values = colors) +\n  theme_bw(base_size = 22) +\n  theme(legend.position = \"right\")\n\nplot_data <- data.frame(\n  NMDS1 = nmds_result_spear$points[, 1],\n  NMDS2 = nmds_result_spear$points[, 2],\n  Cell_Type = de_train$cell_type,\n  Color = factor(de_train$cell_type)\n)\n\np2 <- ggplot(plot_data, aes(x = NMDS1, y = NMDS2)) +\n  geom_point(aes(fill = Color), shape = 21, size = 4) +\n  ggtitle(\"Spearman correlation based distance\") +\n  scale_fill_manual(values = colors) +\n  theme_bw(base_size = 22) +\n  theme(legend.position = \"right\")\n\np1 + p2 + plot_annotation(\n    title = \"Multidimensional Scaling (MDS) of p-values\") & \ntheme(text = element_text(size = 22) )","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:15.916897Z","iopub.execute_input":"2023-11-05T05:47:15.917847Z","iopub.status.idle":"2023-11-05T05:47:16.781215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Euclidean distance","metadata":{}},{"cell_type":"code","source":"pval_mat <- as.matrix(pval_train[, 6:ncol(pval_train)])\ndist_matrix <- dist(pval_mat,\n                    method = \"euclidean\")\nnmds_result <- metaMDS(dist_matrix)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:16.783286Z","iopub.execute_input":"2023-11-05T05:47:16.784374Z","iopub.status.idle":"2023-11-05T05:47:54.838526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(20, 10)\n\nplot_data <- data.frame(\n  NMDS1 = nmds_result$points[, 1],\n  NMDS2 = nmds_result$points[, 2],\n  Cell_Type = de_train$cell_type,\n  Color = factor(de_train$cell_type)\n)\ncolors <- rainbow(length(unique(de_train$cell_type)))\n\nggplot(plot_data, aes(x = NMDS1, y = NMDS2)) +\n  geom_point(aes(fill = Color), shape = 21, size = 4) +\n  ggtitle(\"Multidimensional Scaling (MDS) of p-values using Euclidean distance\") +\n  scale_fill_manual(values = colors) +\n  theme_bw(base_size = 22) +\n  theme(legend.position = \"right\")","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:54.840430Z","iopub.execute_input":"2023-11-05T05:47:54.841444Z","iopub.status.idle":"2023-11-05T05:47:55.332123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"line-height:24px; font-size:16px;border-left: 5px solid silver; padding-left: 26px;\"> \n    💡 Note: \n    <ul style=\"list-style:circle\">\n<li>NMDS is a dimensionality reduction technique, so NMDS1 and NMDS2 are the two axes that best represent the dissimilarity between samples \n<li>Colors show how different cell types are distributed in this space\n<li>The separation between clusters indicates that there are differences in the significance of alteration of the gene expression profiles. E.g. T cells CD8+ and T regulatory cells are closer to each other than to other cell types, suggesting some similarities between these two types of T cells\n    </ul>\n</div>\n","metadata":{}},{"cell_type":"markdown","source":"Now let's see how many genes are significantly affected (p value < 0.05) by the compounds in each cell type.","metadata":{}},{"cell_type":"code","source":"sign_pval_train <- melt(pval_train,\n                        id.vars = names(pval_train)[!names(pval_train) %in% num_cols],\n                       variable.name = \"gene\",\n                       value.name = \"p_value\")\nsign_pval_train <- sign_pval_train[abs(p_value) < 0.05]\n\nsign_pval_train <- \n    sign_pval_train[, .(n_affected_genes = uniqueN(gene)),\n                    by = c(\"cell_type\", \"sm_name\")]\n\ncat(\"Top 10 drug*cell type pairs by the amount of significantly affected genes\")\nhead(sign_pval_train[order(-n_affected_genes)],10)\n\ncat(\"Bottom 10 drug*cell type pairs by the amount of significantly affected genes\")\nhead(sign_pval_train[order(n_affected_genes)],10)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:55.334967Z","iopub.execute_input":"2023-11-05T05:47:55.336383Z","iopub.status.idle":"2023-11-05T05:47:56.383315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sign_pval_train_wide <- dcast(sign_pval_train,\n                         cell_type ~ sm_name,\n                         value.var = \"n_affected_genes\",\n                         fill = 0\n                        )\nsign_pval_train_wide","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:56.385889Z","iopub.execute_input":"2023-11-05T05:47:56.386847Z","iopub.status.idle":"2023-11-05T05:47:56.456919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mat <- as.matrix(sign_pval_train_wide[, 2:ncol(sign_pval_train_wide)])\nrownames(mat) <- sign_pval_train_wide$cell_type\n\nmat_perc <- mat/length(num_cols)*100","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:56.458628Z","iopub.execute_input":"2023-11-05T05:47:56.459527Z","iopub.status.idle":"2023-11-05T05:47:56.470928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(25, 10)\n\nbreaksList = seq(min(mat_perc), max(mat_perc), by = 10)\nmyColors <- c(\n    colorRampPalette(c(\"white\",\"darkred\"))(length(breaksList))\n             )\n\nheat <- pheatmap(mat_perc, fontsize = 16, fontsize_row = 16, fontsize_col = 12,\n                 color = myColors,\n                 breaks = breaksList,\n                 angle_col = 90,\n                 main = \"Percent of significantly affected genes by cell type, color step = 10%\")\n#Re-order original data (genes) to match ordering in heatmap (top-to-bottom)\n#rownames(mat[heat$tree_row[[\"order\"]],])","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:56.472638Z","iopub.execute_input":"2023-11-05T05:47:56.473533Z","iopub.status.idle":"2023-11-05T05:47:56.811457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"line-height:24px; font-size:16px;border-left: 5px solid silver; padding-left: 26px;\"> \n    💡 Note: \n    <ul style=\"list-style:circle\">\n<li>Some compounds affect the majority of genes in all cell types, like MLN 2238 and belinostat\n<li>A large proportion of drugs affect very little amount of genes\n    </ul>\n</div>\n","metadata":{}},{"cell_type":"markdown","source":"**Active and weak compounds**","metadata":{}},{"cell_type":"code","source":"cat(\"The number of drugs per cluster (at the level shown by the red line)\")\nlvl = 35\nsort(cutree(heat$tree_col, h = lvl)) %>% table\n\nfig(30, 10)\nplot(heat$tree_col)\nabline(h = lvl, col = \"red\", lty = 3, lwd = 1)\n\n# made a subset of drugs without the biggest empty cluster\nfilt_dr <- cutree(heat$tree_col, h = lvl)\nfilt_dr <-  filt_dr[filt_dr != 2] #%>% length\n\nactive_dr_plot <- mat_perc[, names(filt_dr)]\nweak_dr_plot <- mat_perc[, !colnames(mat_perc) %in% names(filt_dr) ]","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:56.813303Z","iopub.execute_input":"2023-11-05T05:47:56.814313Z","iopub.status.idle":"2023-11-05T05:47:57.099196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(20, 10)\nheat <- pheatmap(active_dr_plot, fontsize = 16, fontsize_row = 16, fontsize_col = 12,\n                 color = myColors,\n                 breaks = breaksList,\n                 angle_col = 90,\n                 main = \"Percent of significantly affected genes by cell type (active compounds), color step = 10%\")","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:57.101198Z","iopub.execute_input":"2023-11-05T05:47:57.102277Z","iopub.status.idle":"2023-11-05T05:47:57.317606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(25, 7)\nheat <- pheatmap(weak_dr_plot, fontsize = 16, fontsize_row = 16, fontsize_col = 12,\n                 color = myColors,\n                 breaks = breaksList,\n                 angle_col = 90,\n                 main = \"Percent of significantly affected genes by cell type (weak compounds), color step = 10%\")","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:57.334199Z","iopub.execute_input":"2023-11-05T05:47:57.335206Z","iopub.status.idle":"2023-11-05T05:47:57.555764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# - Smiles","metadata":{}},{"cell_type":"markdown","source":"Simplified molecular-input line-entry system (SMILES), which represent the chemical structure of the compounds can be used in several ways. Now we will compute circular fingerprints for the chemical structures. They are designed to capture the structural features and connectivity patterns of atoms within a molecule. You can think of the fingerprint as a binary or bitvector representation of a molecule's structural features, and the primary purpose of the fingerprint is to enable efficient comparison and analysis of chemical structures.","metadata":{}},{"cell_type":"code","source":"# if (!requireNamespace(\"BiocManager\", quietly=TRUE))\n#      install.packages(\"BiocManager\", verbose = FALSE)\n#  BiocManager::install(\"ChemmineR\", verbose = FALSE)\n#  library(\"ChemmineR\")\n\ninstall.packages(\"rcdk\", verbose = FALSE)\nlibrary(rcdk)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:47:57.557866Z","iopub.execute_input":"2023-11-05T05:47:57.558913Z","iopub.status.idle":"2023-11-05T05:48:33.221011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mols <- parse.smiles(unique(de_train$SMILES))\nfps <- lapply(mols, get.fingerprint, type='circular')\nnames(fps) <- unique(de_train$sm_name)\n\ncat(\"An example fingerprint of the first compound - Clotrimazole\\n\")\nfps[[1]]","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:48:33.222845Z","iopub.execute_input":"2023-11-05T05:48:33.224146Z","iopub.status.idle":"2023-11-05T05:48:33.753060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fp.sim <- fingerprint::fp.sim.matrix(fps, method='tanimoto')\nfp.dist <- 1 - fp.sim","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:48:33.754986Z","iopub.execute_input":"2023-11-05T05:48:33.756016Z","iopub.status.idle":"2023-11-05T05:48:33.770331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(27, 10)\ncls <- hclust(as.dist(fp.dist))\nplot(cls, main = 'Clustering of the compounds based on their molecular fingerprints and the Tanimoto similarity metric',\n    labels = names(fps))","metadata":{"execution":{"iopub.status.busy":"2023-11-05T05:50:08.791497Z","iopub.execute_input":"2023-11-05T05:50:08.792818Z","iopub.status.idle":"2023-11-05T05:50:09.063040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"line-height:24px; font-size:16px;border-left: 5px solid silver; padding-left: 26px;\"> \n    💡 Note: The resulting dendrogram shows how the compounds are grouped together based on their structural characteristics.\n</div>","metadata":{}},{"cell_type":"code","source":"gc()","metadata":{"_kg_hide-input":false,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-10-13T10:36:07.778895Z","iopub.execute_input":"2023-10-13T10:36:07.784944Z","iopub.status.idle":"2023-10-13T10:36:08.270964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <p style=\"background-color:#7A9D54;font-family:Verdana;color:white;font-size:100%;text-align:left;border-radius: 15px;padding:10px 15px\">Unaggregated counts</p>","metadata":{}},{"cell_type":"markdown","source":"The **adata_train.parquet** file - is a supplement to de_train, it conntains unaggregated count and normalized data in COO sparse-array format. Columns:\n- obs_id - This is a unique identifier assigned to each cell in the raw dataset.\n- gene - Corresponds to the columns of de_train.\n- count - The raw molecular counts for the gene expression data measured in the experiment as output by 10x CellRanger.\n- normalized_count - These counts have been library size normalized and log(X+1) transformed.\n\n","metadata":{}},{"cell_type":"code","source":"adata_train <- read_parquet(\"/kaggle/input/open-problems-single-cell-perturbations/adata_train.parquet\",\n                           as_data_frame = FALSE) %>%\n              slice_head(n = 10) %>%\n              collect()\nadata_train\nrm(adata_train) ; g <- gc()","metadata":{"execution":{"iopub.status.busy":"2023-10-09T10:04:04.145023Z","iopub.execute_input":"2023-10-09T10:04:04.146441Z","iopub.status.idle":"2023-10-09T10:06:11.949336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This dataset is a superset to de_train and contains additional genes. In my PC (the RAM limits on Kagge do not allow to handle this) I read this file, filtered only genes from the de_train, and saved it in qs format. I used this exact code below. ","metadata":{}},{"cell_type":"code","source":"# for(col in c(\"obs_id\", \"gene\", \"count\", \"normalized_count\") ) {\n  \n#     read_parquet('data/adata_train.parquet',\n#                       col_select = all_of(col),\n#                       as_data_frame = FALSE) %>% \n#     collect() %>%\n#     qsave(paste0(\"adata_train_\", col, \".qs\"))\n#     g <- gc()\n# }\n\n# lapply(c(\"obs_id\", \"gene\", \"count\", \"normalized_count\"),\n#        function(col) {\n#          read_parquet('data/adata_train.parquet',\n#                       col_select = all_of(col),\n#                       as_data_frame = FALSE) %>%\n#            collect() %>%\n#            qsave(paste0(\"data/adata_train_\", col, \".qs\"))\n#            g <- gc()\n         \n#        })\n\n# adata_train <- data.table(\n#   \"obs_id\" = qread(\"data/adata_train_obs_id.qs\"),\n#   \"gene\" = qread(\"data/adata_train_gene.qs\"),\n#   \"count\" = qread(\"data/adata_train_count.qs\")\n# )\n# head(adata_train)\n# setnames(adata_train, names(adata_train), c(\"obs_id\", \"gene\", \"count\"))\n\n# adata_train <- adata_train[gene %chin% names(de_train)]\n# qsave(adata_train, \"adata_train_genes_counts.qs\")\n\n# rm(adata_train) ; g <- gc()\n# # may be helpful: https://hbs-rcs.github.io/large_data_in_R/#read-and-count-lyft-records-with-arrow","metadata":{"execution":{"iopub.status.busy":"2023-10-09T10:06:11.951853Z","iopub.execute_input":"2023-10-09T10:06:11.953161Z","iopub.status.idle":"2023-10-09T10:06:11.964437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There are 416,442,312 rows, 240,090 observation ids (~1200-3300 rows per id, not shown), 21255 genes.","metadata":{}},{"cell_type":"markdown","source":"There is also a **adata_obs_meta.csv** file with observation metadata for adata_train:\n- library_id - A unique identifier for each library, which is a measurement made on pooled samples from each row of the plate. All cells from wells on the same row of the same plate will share a - library_id.\n- plate_name - A unique ID for all samples from the same plate.\n- well - The well location of the sample on each plate (this is standard across 96 well plate experiments). It is a concatenation of row and col.\n- row - Which row on the plate the sample came from.\n- col - Which column on the plate the sample came from.\n- donor_id - Identifies the donor source of the sample, one of three.\n- cell_type - The annotated cell type of each cell based on RNA expression. This matches the cell_type in the de_train.parquet.\n- cell_id - This is included for consistency with LINCS Connectivity Map metadata, which denotes a cell_id for each cell line.\n- sm_name - The primary name for the (parent) compound (in a standardized representation) as chosen by LINCS. This is provided to map the data in this experiment to the LINCS Connectivity Map data.\n- sm_lincs_id - The global LINCS ID (parent) compound (in a standardized representation). This is provided to map the data in this experiment to the LINCS Connectivity Map data.\n- SMILES - Simplified molecular-input line-entry system (SMILES) representations of the compounds used in the experiment. This is a 1D representation of molecular structure. These SMILES are provided by Cellarity based on the specific compounds ordered for this experiment.\n- dose_uM - Dose of the compound in on a micro-molar scale. This maps to the pert_idose field in LINCS.\n- timepoint_hr - Duration of treatment in hours. This maps to the pert_itime field in LINCS.\n- control - Whether this observation was used as a control, True or False.","metadata":{}},{"cell_type":"code","source":"adata_obs_meta <- fread(\"/kaggle/input/open-problems-single-cell-perturbations/adata_obs_meta.csv\")\n\nhead(adata_obs_meta)\ndata.summary(adata_obs_meta)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:06:24.601097Z","iopub.execute_input":"2023-11-05T07:06:24.603790Z","iopub.status.idle":"2023-11-05T07:06:25.613336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Plot the experimental setup**","metadata":{}},{"cell_type":"code","source":"plt <- copy(adata_obs_meta)\nplt[, sm_name := stringr::str_wrap(sm_name, width = 10)]\n#plt[nchar(sm_name) > 10 & !grepl(\"\\\\\\n\", sm_name), unique(sm_name)]\n\nplt[sm_name == \"5-(9-Isopropyl-8-methyl-2-morpholino-9H-purin-6-yl)pyrimidin-2-amine\",\n    sm_name := \"5-(9-Isopropyl-8-methyl\\n-2-morpholino-9H-purin\\n-6-yl)pyrimidin-2-amine\"]\n\nplt[, n_cell_types := uniqueN(cell_type), by = c(\"well\", \"plate_name\")]\nplt[, n_cells := uniqueN(obs_id), by = c(\"well\", \"plate_name\")]\n\nplt[, info := paste0(sm_name,\n                        \"\\nn cell types = \", n_cell_types,\n                        \"\\nn cells = \", n_cells\n                        )]\nplt <- unique(plt[, .(plate_name, col, row, sm_name, info)])","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:40:47.349271Z","iopub.execute_input":"2023-11-05T07:40:47.351602Z","iopub.status.idle":"2023-11-05T07:41:00.074087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(30, 70)\n\nggplot(plt, aes(x = factor(col), y = row, label = info,\n                fill = sm_name)) +\n  geom_tile(alpha = 0.3) +\n  geom_text(size = 6) +\n  facet_wrap(~ plate_name, ncol = 1, scales = \"free_x\") +\n  labs(x = \"Column\", y = \"Row\") +\n  scale_colour_hue(l = 70, c = 30) + \n  theme_bw(base_size = 22) +\n  theme(panel.grid = element_blank()) +\n  guides(fill = guide_legend(ncol = 1)) #\"none\"","metadata":{"execution":{"iopub.status.busy":"2023-11-05T08:11:54.562099Z","iopub.execute_input":"2023-11-05T08:11:54.564513Z","iopub.status.idle":"2023-11-05T08:12:01.456480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Number of cells from which the data were collected by cell type**","metadata":{}},{"cell_type":"code","source":"sum_by_ct <- adata_obs_meta[, .N, by = \"cell_type\"][order(-N)]\ncat(\"Number of obs_ids ( = cells) in each cell type\")\nsum_by_ct\n\nsum_by_ct <- adata_obs_meta[, .N, by = \"cell_type\"][order(-N)]\ncat(\"Number of obs_ids ( = cells) in each cell type (cells treated with controls are excluded)\")\n\nadata_obs_meta[!sm_name %in% c(\"Dabrafenib\", \"Belinostat\", \"Dimethyl Sulfoxide\"),\n               .N, by = \"cell_type\"][order(-N)]    ","metadata":{"execution":{"iopub.status.busy":"2023-10-31T05:43:05.202254Z","iopub.execute_input":"2023-10-31T05:43:05.205563Z","iopub.status.idle":"2023-10-31T05:43:05.800696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Number of cells from which the data were collected by compounds**","metadata":{}},{"cell_type":"code","source":"sum_by_drug <- adata_obs_meta[, .N, by = \"sm_name\"][order(-N)]\ncat(\"Top componds by number of obs_ids ( = cells)\")\nhead(sum_by_drug, 10)\ncat(\"\\nBottom componds by number of obs_ids ( = cells)\")\ntail(sum_by_drug, 10)","metadata":{"execution":{"iopub.status.busy":"2023-10-15T16:49:26.656889Z","iopub.execute_input":"2023-10-15T16:49:26.658562Z","iopub.status.idle":"2023-10-15T16:49:26.722178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(30, 10)\n\nggplot(sum_by_drug, aes(x = sm_name, y = N) ) +\n    geom_bar(stat = 'identity', col=\"grey\", fill = \"#BF9039\") + \n    xlab(\"\") +\n    #facet_wrap(~variable, scales = \"free\", ncol = 4) +\n    ggtitle(paste0(\"Number of cell per compond\")) +\n    theme_bw(base_size = 14) +\n    theme(axis.text.x = element_text(angle = 45, hjust=1),\n         panel.grid.major = element_blank())   ","metadata":{"execution":{"iopub.status.busy":"2023-10-15T16:49:30.697166Z","iopub.execute_input":"2023-10-15T16:49:30.698800Z","iopub.status.idle":"2023-10-15T16:49:31.477551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"line-height:24px; font-size:16px;border-left: 5px solid silver; padding-left: 26px;\"> \n    💡 Note: Here we see three controls - data for these were collected from a much larger number of cells than for the other compounds.\n</div>","metadata":{}},{"cell_type":"code","source":"fig(30, 10)\n\nggplot(sum_by_drug[!sm_name %in% c(\n    \"Dabrafenib\", \"Belinostat\", \"Dimethyl Sulfoxide\"\n)], aes(x = sm_name, y = N) ) +\n    geom_bar(stat = 'identity', col=\"grey\", fill = \"#BF9039\") + \n    xlab(\"\") +\n    #facet_wrap(~variable, scales = \"free\", ncol = 4) +\n    ggtitle(paste0(\"Number of cell per compond (3 controls are excluded)\")) +\n    theme_bw(base_size = 14) +\n    theme(axis.text.x = element_text(angle = 45, hjust=1),\n         panel.grid.major = element_blank())  ","metadata":{"execution":{"iopub.status.busy":"2023-10-15T16:49:35.566085Z","iopub.execute_input":"2023-10-15T16:49:35.567960Z","iopub.status.idle":"2023-10-15T16:49:36.386549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"line-height:24px; font-size:16px;border-left: 5px solid silver; padding-left: 26px;\"> \n    💡 Note: If exclude the controls, it appears, that there are about 3 outliers, for which the data were collected from a much smaller number of cells than for the other compounds.\n</div>","metadata":{}},{"cell_type":"markdown","source":"**Number of cells from which the data were collected by compounds and compounds-cell type pairs**","metadata":{}},{"cell_type":"code","source":"sum_by_drug_and_cell <- adata_obs_meta[, .(n_cells = .N), by = c(\"sm_name\", \"cell_type\")][order(-n_cells)]\n\ncat(\"Top compounds-cell type pairs by number of obs_ids ( = cells)\")\nhead(sum_by_drug_and_cell, 20)\ncat(\"\\nBottom compounds-cell type pairs by number of obs_ids ( = cells)\")\ntail(sum_by_drug_and_cell, 10)","metadata":{"execution":{"iopub.status.busy":"2023-10-15T16:49:40.705193Z","iopub.execute_input":"2023-10-15T16:49:40.706910Z","iopub.status.idle":"2023-10-15T16:49:40.781063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cat(\"Descriptive statistics for the number of cells per drug by cell type (controls excluded)\")\nsum_stats <- sum_by_drug_and_cell[\n    !sm_name %in% c(\"Dabrafenib\", \"Belinostat\", \"Dimethyl Sulfoxide\"),\n    .(Min = min(n_cells),\n      Mean = mean(n_cells),\n      Median = median(n_cells),\n      Max = max(n_cells)),\n    by = \"cell_type\"]\nsum_stats","metadata":{"execution":{"iopub.status.busy":"2023-10-15T16:50:02.977280Z","iopub.execute_input":"2023-10-15T16:50:02.979187Z","iopub.status.idle":"2023-10-15T16:50:03.027534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#sum_by_drug_and_cell <- sum_stats[sum_by_drug_and_cell, on = \"cell_type\"]\ncontrols <- c(\"Dabrafenib\", \"Belinostat\", \"Dimethyl Sulfoxide\")\nplt <- sum_by_drug_and_cell[!sm_name %in% controls]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(20, 10)\n\nggplot(plt[cell_type %in% c(\"B cells\", \"Myeloid cells\")], aes(x = sm_name, y = n_cells) ) +\n    geom_bar(stat = 'identity', col=\"grey\", fill = \"#BF9039\") +\n    xlab(\"\") +\n    facet_wrap(~cell_type, scales = \"free\", ncol = 2) +\n    ggtitle(paste0(\"Number of cell of different type per compond (3 controls are excluded)\")) +\n    theme_bw(base_size = 20) +\n    theme(axis.text.x = element_text(angle = 45, hjust=1),\n         panel.grid.major = element_blank())  ","metadata":{"execution":{"iopub.status.busy":"2023-10-15T16:50:10.316955Z","iopub.execute_input":"2023-10-15T16:50:10.318765Z","iopub.status.idle":"2023-10-15T16:50:11.022904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Examples of compounds with data collected from just 1-2 cells**","metadata":{}},{"cell_type":"code","source":"adata_obs_meta[sm_name == \"MLN 2238\" & cell_type == \"B cells\"]","metadata":{"execution":{"iopub.status.busy":"2023-10-13T11:02:37.847666Z","iopub.execute_input":"2023-10-13T11:02:37.849818Z","iopub.status.idle":"2023-10-13T11:02:37.892942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"adata_obs_meta[sm_name == \"Alvocidib\" & cell_type == \"Myeloid cells\"]","metadata":{"execution":{"iopub.status.busy":"2023-10-13T11:02:43.747163Z","iopub.execute_input":"2023-10-13T11:02:43.748875Z","iopub.status.idle":"2023-10-13T11:02:43.780664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"line-height:24px; font-size:16px;border-left: 5px solid silver; padding-left: 26px;\"> \n    💡 Note: Here are the number of B and Myeloid cells cells from which were collected the data for 15 compounds (train data). We are supposed to predict the impact of other compounds on these cells. But it seems that there as at least three outliers, for wchich the data were collected from just a few cells (unreliable?)\n</div>","metadata":{}},{"cell_type":"code","source":"fig(30, 40)\n\nggplot(plt[!cell_type %in% c(\"B cells\", \"Myeloid cells\")], aes(x = sm_name, y = n_cells) ) +\n    geom_bar(stat = 'identity', col=\"grey\", fill = \"#BF9039\") + \n    xlab(\"\") +\n    facet_wrap(~cell_type, scales = \"free\", ncol = 1) +\n    ggtitle(paste0(\"Number of cell of different type per compond (3 controls are excluded)\")) +\n    theme_bw(base_size = 14) +\n    theme(axis.text.x = element_text(angle = 45, hjust=1),\n         panel.grid.major = element_blank())","metadata":{"execution":{"iopub.status.busy":"2023-10-13T14:06:29.969487Z","iopub.execute_input":"2023-10-13T14:06:29.971587Z","iopub.status.idle":"2023-10-13T14:06:32.293421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"line-height:24px; font-size:16px;border-left: 5px solid silver; padding-left: 26px;\"> \n    💡 Note: Finally, the number of cells of the remaining 4 types per the drugs. There seems to be a huge difference in the number of CD8+ T cells and T regulatory cells compared to CD4+ T cells and NK cells. We have already seen in the charts above that these two pairs are somewhat different from each other. From this a rough conclusion is that the effect may depend on the number of cells in which it is measured. \n</div>","metadata":{}},{"cell_type":"code","source":"sum_data <- dcast(sum_by_drug_and_cell, cell_type ~ sm_name, value.var = \"n_cells\", fill = 0)\nsum_data","metadata":{"execution":{"iopub.status.busy":"2023-10-15T16:50:33.048087Z","iopub.execute_input":"2023-10-15T16:50:33.050942Z","iopub.status.idle":"2023-10-15T16:50:33.146192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mat <- as.matrix(sum_data[, !..controls][, 2:(ncol(sum_data)-3)])\nrownames(mat) <- sum_data$cell_type","metadata":{"execution":{"iopub.status.busy":"2023-10-15T16:54:11.769871Z","iopub.execute_input":"2023-10-15T16:54:11.771525Z","iopub.status.idle":"2023-10-15T16:54:11.792751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(25, 10)\n\nbreaksList = seq(min(mat), max(mat), by = 10)\nmyColors <- c(\n    colorRampPalette(c(\"white\",\"darkred\"))(length(breaksList))\n             )\n\nheat <- pheatmap(mat, fontsize = 16, fontsize_row = 16, fontsize_col = 12,\n                 color = myColors,\n                 breaks = breaksList,\n                 angle_col = 90,\n                 main = \"Number of cells per compound by cell type (3 controls excluded), color step = 10 cells\")","metadata":{"execution":{"iopub.status.busy":"2023-10-15T17:43:19.534280Z","iopub.execute_input":"2023-10-15T17:43:19.536370Z","iopub.status.idle":"2023-10-15T17:43:19.897179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Number of cells per coumpound-cell type pair vs number of significantly affected cells** ","metadata":{}},{"cell_type":"code","source":"# Remove DMSO and combine n_affected_genes and n_cells\nsum_by_drug_and_cell <- sum_by_drug_and_cell[!sm_name == \"Dimethyl Sulfoxide\"]\nsum_dat <- sign_pval_train[sum_by_drug_and_cell, on = c(\"cell_type\", \"sm_name\")]\nhead(sum_dat)","metadata":{"execution":{"iopub.status.busy":"2023-10-15T17:44:30.833566Z","iopub.execute_input":"2023-10-15T17:44:30.835217Z","iopub.status.idle":"2023-10-15T17:44:30.872444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(20, 10)\nggscatter(sum_dat[!sm_name %in% c(\n    \"Dabrafenib\", \"Belinostat\", \"Dimethyl Sulfoxide\"\n                            )],\n          x = \"n_affected_genes\", y = \"n_cells\", color = \"cell_type\",\n          shape = 20, size = 3,\n          #label = \"labels\",repel = TRUE,\n          #font.label = c(20, \"plain\"),\n          title = paste0(\"Number of cells per coumpound\\nvs number of significantly affected cells by cell type\"),\n          ggtheme = theme_bw(base_size = 22)  + theme(aspect.ratio = 1) )","metadata":{"execution":{"iopub.status.busy":"2023-10-15T17:44:43.893356Z","iopub.execute_input":"2023-10-15T17:44:43.895227Z","iopub.status.idle":"2023-10-15T17:44:44.574740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig(20, 12)\nggscatter(sum_dat[!sm_name %in% c(\n    \"Dabrafenib\", \"Belinostat\", \"Dimethyl Sulfoxide\"\n                            )],\n          x = \"n_affected_genes\", y = \"n_cells\", color = \"#033E8C\", #\"cell_type\",\n          shape = 20, size = 3,\n          add = \"reg.line\", conf.int = TRUE, \n          cor.coef = TRUE, cor.coef.size = 8,\n          cor.coeff.args = list(method = \"spearman\", label.sep = \"\\n\"),\n          add.params = list(fill = \"lightgray\"),\n          facet.by = \"cell_type\",\n          title = \"Number of cells per coumpound\\nvs number of significantly affected cells by cell type (3 controls are excluded)\",\n          ggtheme = theme_bw(base_size = 22)  + theme(aspect.ratio = 1) )","metadata":{"execution":{"iopub.status.busy":"2023-10-15T17:44:55.881437Z","iopub.execute_input":"2023-10-15T17:44:55.883605Z","iopub.status.idle":"2023-10-15T17:44:57.149118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <p style=\"background-color:#7A9D54;font-family:Verdana;color:white;font-size:100%;text-align:left;border-radius: 15px;padding:10px 15px\">Multiome (in progress)</p>","metadata":{}},{"cell_type":"markdown","source":"**multiome_train.parquet** contains optional additional 10x Multiome data for each sample at baseline.\n\n- obs_id - Unique identifier for each observation. (Distinct from identifiers used in adata.)\n- location - This is a feature ID. If the feature_type in multiome_var_meta.csv is Gene Expression then this is a gene symbol. If feature_type is Peaks, then this is the genomic interval of the peak.\n- count - This is the raw molecular counts of the transcript for accessible DNA measurement as output by Cellranger-Arc.\n- normalized_count - If the feature_type in multiome_var_meta.csv is Gene Expression then this is library size normalized and log(X+1) transformed counts. If feature_type is Peaks, then this is ATAC-seq peak counts transformed with TF-IDF using the default log(TF) * log(IDF).","metadata":{}},{"cell_type":"code","source":"multiome_train <- read_parquet('/kaggle/input/open-problems-single-cell-perturbations/multiome_train.parquet')\nmultiome_train <- setDT(multiome_train)\n\nhead(multiome_train)\ndata.summary(multiome_train)\nrm(multiome_train) ; gc()","metadata":{"execution":{"iopub.status.busy":"2023-10-09T10:31:40.374063Z","iopub.execute_input":"2023-10-09T10:31:40.376598Z","iopub.status.idle":"2023-10-09T10:34:57.832584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**multiome_obs_meta.csv**:\n\n- obs_id - Identifier corresponding to that in multiome_train.parquet.\n- cell_type - The annotated cell type of each cell based on RNA expression.\n- donor_id - Identifies the donor source of the sample, one of three.","metadata":{}},{"cell_type":"code","source":"multiome_obs_meta <- fread(\"/kaggle/input/open-problems-single-cell-perturbations/multiome_obs_meta.csv\")\n\nhead(multiome_obs_meta)\ndata.summary(multiome_obs_meta)","metadata":{"execution":{"iopub.status.busy":"2023-10-09T10:36:41.096904Z","iopub.execute_input":"2023-10-09T10:36:41.098239Z","iopub.status.idle":"2023-10-09T10:36:41.177817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**multiome_var_meta.csv**:\n\n- location - This is a feature ID. If the feature_type is Gene Expression then this is a gene symbol. If feature_type is Peaks, then this is the genomic interval of the peak.\n- gene_id - This is an alternative unique feature ID. If the feature_type is Gene Expression then this is an Ensembl Stable Gene ID. If feature_type is Peaks, then this is the genomic interval of the peak.\n- feature_type - Denotes whether the feature is an RNA expression measurement or a Chromatin Accessibility measurement.\n- genome - The genome version used when running CellRanger-Arc\n- interval - The genomic coordinates of each feature on reference genome GRCh38. Genomic coordinates are directly related to the reference genome and include the chromosome name, start position, - and end position in the following format: chr1:1234570-1234870.","metadata":{}},{"cell_type":"code","source":"multiome_var_meta <- fread(\"/kaggle/input/open-problems-single-cell-perturbations/multiome_var_meta.csv\")\n\nhead(multiome_var_meta)\ndata.summary(multiome_var_meta)","metadata":{"execution":{"iopub.status.busy":"2023-10-09T10:36:41.222037Z","iopub.execute_input":"2023-10-09T10:36:41.223492Z","iopub.status.idle":"2023-10-09T10:36:41.796043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# multiome_var_meta <- multiome_var_meta[feature_type == \"Gene Expression\" &\n#                                       location %chin% names(de_train)]\n# multiome_var_meta[, uniqueN(location)]\n\n# multiome_train <- multiome_train[location %chin% names(de_train)]\n# multiome_train[, uniqueN(location)]","metadata":{"execution":{"iopub.status.busy":"2023-10-09T10:37:13.423446Z","iopub.execute_input":"2023-10-09T10:37:13.425444Z","iopub.status.idle":"2023-10-09T10:37:13.481885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# length(setdiff(names(de_train),\n#        multiome_train[, unique(location)]))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <p style=\"background-color:#BF5841;font-family:Verdana;color:white;font-size:100%;text-align:left;border-radius: 15px;padding:10px 15px\">Test data</p>","metadata":{}},{"cell_type":"markdown","source":"Our goal is to predict corresponding differential expression value (-log10(p-value) * sign(LFC)) for the cell_type / sm_name pairs given in id_map.csv. The p-value is a score for the perturbation effect output from a linear model used by competition hosts (Limma), that takes into account various factors such as gene expression, experimental covariates, and Bayesian priors. So, it apppears, we have to predict the statistical significance of the change, and its direction, not the DE itself.","metadata":{}},{"cell_type":"code","source":"id_map <- fread(\"/kaggle/input/open-problems-single-cell-perturbations/id_map.csv\")\n\nhead(id_map)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.summary(id_map)\n\ncat(\"\\nCell types in the test set:\", paste0(unique(id_map[, cell_type]), collapse = \", \"))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"So, there are 129 different compounds in the test set. We have to predict their impact on gene expression in cells of 2 types: B cells and Myeloid cells.\n- Public Test includes 50 randomly selected compounds\n- Private Test - 79 randomly selected compounds","metadata":{}},{"cell_type":"markdown","source":"Number of compounds per cell type:","metadata":{}},{"cell_type":"code","source":"id_map[, .N, by = \"cell_type\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The input to your model will be a tuple of cell_type and sm_name and the output of your model will be predicted signed -log10(p-values) for all 18211 genes.","metadata":{}},{"cell_type":"code","source":"#","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}