From 549dcb03a87254ca334aafae863003fccfaf14ad Mon Sep 17 00:00:00 2001 From: Joselyn Chavez Date: Tue, 8 Aug 2023 20:16:25 -0400 Subject: [PATCH] render --- docs/clustering.html | 4 ++-- docs/control-de-calidad.html | 4 ++-- "docs/normalizaci\303\263n-de-datos.html" | 4 ++-- "docs/reducci\303\263n-de-dimensiones.html" | 4 ++-- docs/search_index.json | 2 +- "docs/selecci\303\263n-de-genes-altamente-variables.html" | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/clustering.html b/docs/clustering.html index abdc8f7..d55398b 100644 --- a/docs/clustering.html +++ b/docs/clustering.html @@ -936,10 +936,10 @@

6.11 Dónde estamos6.12 Detalles de la sesión de R

## Información de la sesión de R
 Sys.time()
-
## [1] "2023-08-08 17:30:11 EDT"
+
## [1] "2023-08-08 17:46:48 EDT"
proc.time()
##      user    system   elapsed 
-##  1267.839   107.667 95260.648
+## 1760.635 128.666 96258.125
options(width = 120)
 sessioninfo::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
diff --git a/docs/control-de-calidad.html b/docs/control-de-calidad.html
index f787edd..8ca34fc 100644
--- a/docs/control-de-calidad.html
+++ b/docs/control-de-calidad.html
@@ -1192,10 +1192,10 @@ 

2.14 Visualización de los datos

2.15 Detalles de la sesión de R

## Información de la sesión de R
 Sys.time()
-
## [1] "2023-08-08 17:25:22 EDT"
+
## [1] "2023-08-08 17:41:55 EDT"
proc.time()
##      user    system   elapsed 
-##   996.461    97.738 94971.378
+## 1485.533 117.620 95964.475
options(width = 120)
 sessioninfo::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
diff --git "a/docs/normalizaci\303\263n-de-datos.html" "b/docs/normalizaci\303\263n-de-datos.html"
index 2865922..236ae01 100644
--- "a/docs/normalizaci\303\263n-de-datos.html"
+++ "b/docs/normalizaci\303\263n-de-datos.html"
@@ -812,10 +812,10 @@ 

3.10 Agradecimientos3.11 Detalles de la sesión de R

## Información de la sesión de R
 Sys.time()
-
## [1] "2023-08-08 17:25:52 EDT"
+
## [1] "2023-08-08 17:42:24 EDT"
proc.time()
##      user    system   elapsed 
-##  1022.206   100.158 95001.934
+## 1511.348 119.377 95994.018
options(width = 120)
 sessioninfo::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
diff --git "a/docs/reducci\303\263n-de-dimensiones.html" "b/docs/reducci\303\263n-de-dimensiones.html"
index ee122a1..e5b7b12 100644
--- "a/docs/reducci\303\263n-de-dimensiones.html"
+++ "b/docs/reducci\303\263n-de-dimensiones.html"
@@ -975,10 +975,10 @@ 

5.8 Dónde estamos5.9 Detalles de la sesión de R

## Información de la sesión de R
 Sys.time()
-
## [1] "2023-08-08 17:28:51 EDT"
+
## [1] "2023-08-08 17:45:27 EDT"
proc.time()
##      user    system   elapsed 
-##  1191.645   104.838 95181.086
+## 1683.500 125.169 96176.687
options(width = 120)
 sessioninfo::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
diff --git a/docs/search_index.json b/docs/search_index.json
index 0ec4358..f41f092 100644
--- a/docs/search_index.json
+++ b/docs/search_index.json
@@ -1 +1 @@
-[["index.html", "Workshop CDSB 2023: Creando paquetes de R/Bioconductor para análisis transcriptómicos de célula única. Bienvenida 0.1 Instructores 0.2 Ponentes invitados 0.3 Ayudantes 0.4 Temario 0.5 Patrocinadores 0.6 Licencia", " Workshop CDSB 2023: Creando paquetes de R/Bioconductor para análisis transcriptómicos de célula única. Dra. Joselyn Cristina Chávez-Fuentes, Dr. Leonardo Collado-Torres, Dra. Yalbi Balderas-Martínez, M.C. Erick Cuevas-Fernández, Dra. Mirna Vázquez Rosas-Landa, Dra. Alejandra Medina-Rivera, Bienvenida Les damos la bienvenida al Workshop Creando paquetes de R/Bioconductor para análisis transcriptómicos de célula única! En los últimos años, la generación de datos transcriptómicos de célula única ha cobrado gran relevancia en la investigación biomédica; sin embargo, las herramientas necesarias para su análisis continúan en desarrollo. En este taller haremos un repaso a las herramientas estadísticas existentes para analizar datos transcriptómicos de célula única usando Bioconductor, cómo documentar tu análisis y revisaremos algunas herramientas para la interpretación de resultados. A la par, aprenderás cuáles son los pasos cruciales para desarrollar un paquete de R y algunas buenas prácticas para la generación de código. Con la integración de estas herramientas, tendrás la oportunidad de crear tu primer paquete y contribuir a la comunidad de desarrolladores. 0.1 Instructores Dra. Joselyn Cristina Chávez Fuentes: Estancia Postdoctoral en Icahn School of Medicine at Mount Sinai. Dr. Leonardo Collado-Torres: Investigador en Lieber Institute for Brain Development. Dra. Yalbi Balderas Martínez: Investigadora en el Instituto Nacional de Enfermedades Respiratorias Ismael Cosío Villegas. M.C. Erick Cuevas Fernández: Estudiante de Doctorado en la Universidad Nacional Autónoma de México. Dra. Mirna Vázquez Rosas Landa: Investigadora en el Instituto de Ciencias de Mar y Limnología de la UNAM. Dra. Alejandra Medina Rivera: Investigadora Asociada en el Laboratorio Internacional de Investigación de Medicina Genómica, UNAM. 0.2 Ponentes invitados Dra. Evelia Coss Dra Laura Lucila Gómez Romero M.C. José Antonio Ovando M.C. Andrés Arredondo Cruz 0.3 Ayudantes Dra. Evelia Coss M.C. José Antonio Ovando M.C. Andrés Arredondo Cruz M.C. Diego Ramírez M.C. Luis Alberto Meza 0.4 Temario Consulta el calendario de este curso en: https://bit.ly/calendarcdsb2023 Día 1: Flujo de análisis de datos transcriptómicos de célula única Parte I Presentación de la CDSB. Estructura e importe de datos. Control de calidad. Normalización. Día 2: Flujo de análisis de datos transcriptómicos de célula única Parte II Selección de genes altamente variables. Reducción de dimensiones. Clustering. Genes marcadores. Anotación de tipos celulares. Día 3: Creación de paquetes de R/Bioconductor Parte I Nuevas funcionalidades de RStudio, Quarto. Control de versiones con GitHub y RStudio. Solución de problemas con las versiones de paquetes de Rstudio. Infraestructura de un paquete de R/Bioconductor. Plática: Convirtiendo tu flujo de análisis en un paquete de R/Bioconductor. Documentación de funciones. Sesión social: Conociendo a la comunidad. Día 4: Creación de paquetes de R/Bioconductor Parte II Diseño de pruebas. Creación de viñetas. Compilación e instalación de paquetes. Proyectos colaborativos Parte I. Día 5: Proyectos colaborativos Proyectos colaborativos Parte II. Presentación de proyectos. Clausura. 0.5 Patrocinadores Agradecemos a nuestros patrocinadores: 0.6 Licencia Este material posee una licencia tipo Creative Commons Attribution-ShareAlike 4.0 International License. Para conocer más sobre esta licencia, visite http://creativecommons.org/licenses/by-sa/4.0/ "],["estructura-e-importe-de-datos.html", "1 Estructura e importe de datos 1.1 Diapositivas 1.2 Bulk RNAseq vs single-cell RNAseq 1.3 Consideraciones experimentales 1.4 Generación de la matriz de cuentas 1.5 Nombres de los genes 1.6 Importando los datos 1.7 Actividad 1.8 Actividad 1.9 El objeto SingleCellExperiment 1.10 Construyendo un objeto SingleCellExperiment 1.11 Accediendo a los elementos del objeto 1.12 Agregando más assays 1.13 Un vistazo al flujo de trabajo", " 1 Estructura e importe de datos Joselyn Cristina Chávez Fuentes 07 de agosto de 2023 1.1 Diapositivas 1.2 Bulk RNAseq vs single-cell RNAseq Tomado de Yu X, et al. Bulk RNAseq Tomado de Hyeongseon Jeon, et al. scRNAseq 1.3 Consideraciones experimentales 1.3.1 Tecnologías de scRNAseq Droplet-based: Son las tecnologías más usadas debido a su buen rendimiento con un relativo bajo costo. 10X Genomics inDrop seq Drop-seq Plate-based Tienen la capacidad de capturar información adicional, como la morfología. Tienen más opciones para personalizar el diseño de experimento. Con UMIs: CEL-seq MARS-seq Con reads: Smart-seq2 Otros sciRNA-seq 1.3.2 ¿UMIs o Reads? Los métodos basados en reads proveen una cobertura de transcriptoma completo, lo que puede ser útil para ciertas aplicaciones, como el análisis de splicing o mutaciones en exones. Los métodos basados en UMIs suelen ser más populares, ya que eliminan el ruido causado por la amplificación durante el PCR. 1.3.3 ¿Cuántas células y profundidad de secuenciación necesito? Depende… Si tu objetivo es el estudio de subgrupos raros o poco abundantes de células, necesitarás un mayor número de células por muestra. Si tu objetivo es estudiar diferencias sutiles en la expresión de genes, necesitarás una mayor profundidad de secuenciación. Hasta el momento, las tecnologías basadas en droplets capturan entre 10,000 y 100,000 células, con un aproximado de 1,000 a 10,000 UMIs por célula. Existen algunas variaciones entre el rendimiento y la tasa de doublets que pueden afectar la eficiencia real de secuenciación. Encontrar un balance entre el número de células por muestra, la profundidad de secuenciación, el número de condiciones y réplicas a secuenciar depende mucho de la aplicación y el presupuesto. 1.4 Generación de la matriz de cuentas El método para generar la matriz depende de la tecnología utilizada. 10X Genomics: Cellranger es el programa más popular. Utiliza STAR para alinear los reads con el genoma de referencia y después cuenta el número de UMIs únicos mapeados con cada gene. Como alternativa, métodos de pseudo-alineamiento como alevin pueden ser usados. No requiere un alineamiento con genoma de referencia, lo que reduce el tiempo de cómputo y los requerimientos de memoria. El paquete scPipe provee un análisis general. Utiliza Rsubread para alinear los reads y después cuenta reads o UMIs por gene. CEL-seq o CEL-seq2 El paquete scruff provee un pipeline para la cuantificación. De manera general, los protocolos basados en reads pueden reusar los métodos desarrollados para bulk RNA-seq. Si el grupo de datos involucra transcritos spike-in, las secuencias spike-in deben proveerse junto al genoma de referencia durante el alineamiento y cuantificación. 1.5 Nombres de los genes En todos los casos, los identificadores de genes deben definirse considerando los nombres de Ensembl o Entrez. Esto mantiene un mapeo sin lugar a errores para la identificación de genes en la matriz. Estos identificadores pueden ser reemplazados por el nombre común del gene durante el análisis, pero considera que estos nombres pueden cambiar con el tiempo. Consideraciones adicionales: Algunas herramientas de conteo, como HTSeq, incluyen un reporte dentro de la matriz de cuentas con el número lecturas sin alinear. Estos valores pueden ser útiles para el control de calidad, pero deben ser removidas de la matriz de cuentas y guardadas en otro lugar antes de continuar con el análisis para que no sean confundidas con los valores de expresión de genes. Generalmente, las secuencias spike-ins son desarrolladas por el External RNA Controls Consortium (ERCC) y suelen tener nombres como ERCC-00002. En las muestra de humano, debemos evitar confundir estos identificadores con los genes de la familia ERCC, que suelen tener nombres similares ERCC1. Podemos evitar estos problemas si usamos los identificadores de Ensembl. 1.6 Importando los datos 1.6.1 Datos tabulares Descarguemos los datos de cáncer de páncreas de Muraro et al (2016) GSE85241. Solamente necesitamos el archivo “GSE85241_cellsystems_dataset_4donors_updated.csv” Una forma sencilla mat <- read.delim( "GSE85241_cellsystems_dataset_4donors_updated.csv") mat <- as.matrix(mat) dim(mat) mat[1:3,1:3] Una opción más eficiente. Solamente se leen los datos diferentes a cero. sparse.mat <- scuttle::readSparseCounts( "GSE85241_cellsystems_dataset_4donors_updated.csv") dim(sparse.mat) sparse.mat[1:3,1:3] 1.7 Actividad Comparemos la clase y la cantidad de memoria que utiliza cada opción. Utiliza las funciones class() y lobstr::obj_size() para comparar mat y sparse.mat 1.7.1 Datos de cellRanger Cuando usamos datos de 10X Genomics, Cellranger genera un directorio que contiene 3 archivos: cuentas, anotaciones de features y barcodes. Podemos usar la ruta a este directorio y la función read10xCounts() del paquete DropletUtils. Utilicemos como ejemplo un dataset de células sanguíneas periféricas. sce <- DropletUtils::read10xCounts( "raw_gene_bc_matrices/GRCh38/") 1.8 Actividad Evalúa la clase de sce. ¿Habías escuchado antes sobre este tipo de objeto? Imprime el objeto sce en la consola. ¿Cómo se ve el resultado? 1.8.1 Datos con formato HDF5 El formato Hierarchical Data Format version 5 (HDF5) permite guardar tanto los valores de expresión asociados a los genes, como la anotación de los tipos celulares dentro de un mismo archivo. Podemos leer este archivo con un objeto SingleCellExperiment utilizando el paquete zellkonverter. library(zellkonverter) demo <- system.file("extdata", "krumsiek11.h5ad", package = "zellkonverter") sce <- readH5AD(demo) 1.8.2 Datos con formato loom Los archivos con formato Loom son una variante de HDF5, pueden ser leídos como un objeto SingleCellLoomExperiment usando el paquete LoomExperiment. Este objeto es una extensión del SingleCellExperiment. library(LoomExperiment) demo <- system.file("extdata", "L1_DRG_20_example.loom", package = "LoomExperiment") scle <- import(demo, type="SingleCellLoomExperiment") 1.9 El objeto SingleCellExperiment 1.10 Construyendo un objeto SingleCellExperiment Para crear un SingleCellExperiment rudimentario, solamente necesitamos el slot assays. Este slot necesita la matriz de cuentas, donde los renglones corresponden a los genes (features) y las columnas corresponden a las células. mat <- read.delim( "GSE85241_cellsystems_dataset_4donors_updated.csv") mat <- as.matrix(mat) sce <- SingleCellExperiment::SingleCellExperiment( assays = list(counts = mat)) 1.11 Accediendo a los elementos del objeto Para poder ver el contenido del slot assays tenemos dos opciones: Forma general, usando el nombre del assay que queremos ver: m <- assay(sce, "counts") Una opción más corta, pero sólo funciona cuando el assay se llama “counts” m <- counts(sce) 1.12 Agregando más assays Se pueden guardar varias versiones de los datos de cuentas. sce <- scuttle::logNormCounts(sce) sce Observa el slot assays, notas algo diferente? También se pueden conocer los assays disponibles: assayNames(sce) 1.13 Un vistazo al flujo de trabajo "],["control-de-calidad.html", "2 Control de calidad 2.1 Material y Diapositivas 2.2 Enfoques o Ideas principales 2.3 ¿Por qué hay problemas con los datos? 2.4 Preguntas Básicas en Control de Calidad 2.5 La mala calidad en los datos puede ser debida a varios factores 2.6 Recomendaciones 2.7 Tipos de filtros 2.8 Parámetros empleados para evaluar la calidad con la función addPerCellQC 2.9 Ejemplo: linea celular 416 en ratón 2.10 ¿Cómo funciona isOutlier()? 2.11 Consideran el Batch 2.12 Visualización gráfica de las células de buena calidad 2.13 Identificando droplets vacíos con datos de PBMC 2.14 Visualización de los datos con ISEE 2.15 Detalles de la sesión de R", " 2 Control de calidad Dra. Evelia Coss 07 de agosto de 2023 2.1 Material y Diapositivas Diapositivas de Peter Hickey: Ve las diapositivas aquí. Curso 2021 impartido por Leonardo Collado Torres: Ver información aquí 2.2 Enfoques o Ideas principales Detectar células verdaderas y de alta calidad ✅🍪, de modo que cuando agrupemos nuestras células sea más fácil identificar poblaciones de tipos celulares distintos. Identificar las muestras fallidas e intentar salvar los datos o eliminarlas del análisis, además de intentar comprender por qué falló la muestra. 2.3 ¿Por qué hay problemas con los datos? Problemas con el rompimiento de las células. Fallos en la preparación de las bibliotecas (ineficiencias en la transcripción inversa, amplificacion por PCR, etc). Más de una célula durante la secuenciación (douplets o multiplets). Problemas en el alineamiento. 2.4 Preguntas Básicas en Control de Calidad Se responden durante el análisis de SingleCell RNA-Seq. ¿Cuántos droplets traen más de una célula? (douplets 🍪🍪 o multiplets 🍪🍪🍪). ¿Cuántas células murieron durante el proceso de secuenciacion? Cada droplets debe contener una sola célula 🍪. Figura obtenida de Single-Cell best practices. 2.5 La mala calidad en los datos puede ser debida a varios factores Una o varias células podemos encontrar: ⚠️ Baja cantidad de cuentas totales ⚠️ Baja cantidad de genes expresados ⚠️ Alta proporción de cuentas (reads) provenientes de la mitocondria ⚠️ Alta proporción de cuentas provenientes de las secuencias control (ERCC spike-in control transcripts) Mas informacion sobre ERCC spike-in control transcripts. 2.6 Recomendaciones Tener un correcto diseño experimental (evitar efecto bash). 👾 Correcta preparación de las muestras. 🎮 Analizar la calidad de los datos. 🍪 2.7 Tipos de filtros Fixed thresholds: Valores de corte fijos y estrictos (FDR < 0.5) ♠️ Adaptative thresholds: Valores de cortes adaptados al comportamiento de nuestros datos.♦️ 2.8 Parámetros empleados para evaluar la calidad con la función addPerCellQC La función addPerCellQC provenie del paquete scater. Agrega las siguientes métricas en cada célula y por cada gen dentro del mismo archivo. sum: Número de cuentas (lecturas) totales de cada célula. detected: Genes expresados con al menos una cuenta. altexps_ERCC_percent: Porcentaje de cuentas mapeadas de las secuencias control (ERCC spike-in control transcripts). subsets_Mito_percent: Porcentaje de cuentas mapeadas provenientes de la mitocondria. 2.9 Ejemplo: linea celular 416 en ratón Realizaremos las siguientes actividades con este ejemplo: Eliminar células de baja calidad. Comparar entre los tipos de filtros (Fixed thresholds y Adaptative thresholds). Filtrar células baja calidad. Visualización de datos crudos y filtrados. Línea celular de células mieloides progenitoras inmortalizadas de ratón usando SmartSeq2. 2.9.1 Paquetes e Importar los datos en R Los paquetes que vamos a emplear para esta sección son: library(scRNAseq) ## para descargar datos de ejemplo library(DropletUtils) ## para detectar droplets library(Matrix) ## para leer datos en formatos comprimidos library(AnnotationHub) ## para obtener información de genes library(scater) ## para gráficas y control de calidad library(BiocFileCache) ## para descargar datos library(EnsDb.Hsapiens.v86) ## Archivo de anotacion en humanos en Ensembl library(dplyr) ## Modificacion de archivos dataframe Cargar los datos empleando el paquete scRNAseq sce.416b <- LunSpikeInData(which = "416b") ## snapshotDate(): 2023-04-24 ## see ?scRNAseq and browseVignettes('scRNAseq') for documentation ## loading from cache ## see ?scRNAseq and browseVignettes('scRNAseq') for documentation ## loading from cache ## see ?scRNAseq and browseVignettes('scRNAseq') for documentation ## loading from cache ## snapshotDate(): 2023-04-24 ## see ?scRNAseq and browseVignettes('scRNAseq') for documentation ## loading from cache ## snapshotDate(): 2023-04-24 ## loading from cache # Conversion a factor, evitemos mensajes de error sce.416b$block <- factor(sce.416b$block) El paquete scRNAseq contiene múltiples data sets compilados en funciones, para saber más da click aquí. 2.9.2 Anotación de genes ah <- AnnotationHub() ## snapshotDate(): 2023-04-24 query(ah, c("Mus musculus", "Ensembl", "v97")) ## AnnotationHub with 1 record ## # snapshotDate(): 2023-04-24 ## # names(): AH73905 ## # $dataprovider: Ensembl ## # $species: Mus musculus ## # $rdataclass: EnsDb ## # $rdatadateadded: 2019-05-02 ## # $title: Ensembl 97 EnsDb for Mus musculus ## # $description: Gene and protein annotations for Mus musculus based on Ensembl version 97. ## # $taxonomyid: 10090 ## # $genome: GRCm38 ## # $sourcetype: ensembl ## # $sourceurl: http://www.ensembl.org ## # $sourcesize: NA ## # $tags: c("97", "AHEnsDbs", "Annotation", "EnsDb", "Ensembl", "Gene", "Protein", "Transcript") ## # retrieve record with 'object[["AH73905"]]' # Anotacion de genes con la localizacion de cada cromosoma ens.mm.v97 <- ah[["AH73905"]] # solo un cromosoma ## loading from cache location <- mapIds(ens.mm.v97, keys=rownames(sce.416b), keytype="GENEID", column="SEQNAME") ## Warning: Unable to map 563 of 46604 requested IDs. # deteccion de genes mitocondriales is.mito <- which(location=="MT") 2.9.3 Análisis de calidad con addPerCellQC Al imprimir la variable sce.416b podemos observar que es de tipo SingleCellExperiment. # Agregar la informacion de la calidad por cada gen y celula en un mismo archivo # Identificar genes mitocondriales sce.416b <- addPerCellQC(sce.416b, subsets = list(Mito = is.mito) ) sce.416b ## class: SingleCellExperiment ## dim: 46604 192 ## metadata(0): ## assays(1): counts ## rownames(46604): ENSMUSG00000102693 ENSMUSG00000064842 ... ENSMUSG00000095742 CBFB-MYH11-mcherry ## rowData names(1): Length ## colnames(192): SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 ... ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 ## colData names(21): Source Name cell line ... altexps_SIRV_percent total ## reducedDimNames(0): ## mainExpName: endogenous ## altExpNames(2): ERCC SIRV Podemos observar la informacion de este data frame usando colData: # observar la informacion contenida en el dataframe colData(sce.416b) ## DataFrame with 192 rows and 21 columns ## Source Name cell line cell type single cell well quality ## <character> <character> <character> <character> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 SLX-9555.N701_S502.C.. 416B embryonic stem cell OK ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 SLX-9555.N701_S503.C.. 416B embryonic stem cell OK ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 SLX-9555.N701_S504.C.. 416B embryonic stem cell OK ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 SLX-9555.N701_S505.C.. 416B embryonic stem cell OK ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 SLX-9555.N701_S506.C.. 416B embryonic stem cell OK ## ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S505... 416B embryonic stem cell OK ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S506... 416B embryonic stem cell OK ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S507... 416B embryonic stem cell OK ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S508... 416B embryonic stem cell OK ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S517... 416B embryonic stem cell OK ## genotype phenotype strain spike-in addition ## <character> <character> <character> <character> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. wild type phenotype B6D2F1-J ERCC+SIRV ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. wild type phenotype B6D2F1-J ERCC+SIRV ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. wild type phenotype B6D2F1-J ERCC+SIRV ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J ERCC+SIRV ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J ERCC+SIRV ## ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J Premixed ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J Premixed ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J Premixed ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J Premixed ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. wild type phenotype B6D2F1-J Premixed ## block sum detected subsets_Mito_sum subsets_Mito_detected ## <factor> <numeric> <numeric> <numeric> <numeric> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 20160113 865936 7618 78790 20 ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 20160113 1076277 7521 98613 20 ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 20160113 1180138 8306 100341 19 ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 20160113 1342593 8143 104882 20 ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 20160113 1668311 7154 129559 22 ## ... ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 20160325 776622 8174 48126 20 ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 20160325 1299950 8956 112225 25 ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 20160325 1800696 9530 135693 23 ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 20160325 46731 6649 3505 16 ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 20160325 1866692 10964 150375 29 ## subsets_Mito_percent altexps_ERCC_sum altexps_ERCC_detected altexps_ERCC_percent ## <numeric> <numeric> <numeric> <numeric> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 9.09882 65278 39 6.80658 ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 9.16242 74748 40 6.28030 ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 8.50248 60878 42 4.78949 ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 7.81190 60073 42 4.18567 ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 7.76588 136810 44 7.28887 ## ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 6.19684 61575 39 7.17620 ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 8.63302 94982 41 6.65764 ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 7.53559 113707 40 5.81467 ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 7.50037 7580 44 13.48898 ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 8.05569 48664 39 2.51930 ## altexps_SIRV_sum altexps_SIRV_detected altexps_SIRV_percent total ## <numeric> <numeric> <numeric> <numeric> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 27828 7 2.90165 959042 ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 39173 7 3.29130 1190198 ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 30058 7 2.36477 1271074 ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 32542 7 2.26741 1435208 ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 71850 7 3.82798 1876971 ## ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 19848 7 2.313165 858045 ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 31729 7 2.224004 1426661 ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 41116 7 2.102562 1955519 ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 1883 7 3.350892 56194 ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 16289 7 0.843271 1931645 # Ver el nombre de las columnas colnames(colData(sce.416b)) ## [1] "Source Name" "cell line" "cell type" "single cell well quality" ## [5] "genotype" "phenotype" "strain" "spike-in addition" ## [9] "block" "sum" "detected" "subsets_Mito_sum" ## [13] "subsets_Mito_detected" "subsets_Mito_percent" "altexps_ERCC_sum" "altexps_ERCC_detected" ## [17] "altexps_ERCC_percent" "altexps_SIRV_sum" "altexps_SIRV_detected" "altexps_SIRV_percent" ## [21] "total" 2.9.4 Preguntas sobre los datos ¿Cuántas células detectadas se encuentran en el dataframe sce.416b? 1 ¿Cuántos genes fueron analizados con al menos una cuenta? 2 Podemos conocer estas respuestas observando la informacion contenida en sce.416b, en dimensiones. 2.9.5 Visualización de los datos crudos Genes detectados en cada uno de los bloques de secuenciación. plotColData(sce.416b, x = "block", y = "detected") Genes detectados por cada tratamiento en cada bloque de secuenciación. plotColData(sce.416b, x = "block", y = "detected", other_fields = "phenotype" ) + scale_y_log10() + # Cambiar la escala en Y a logaritmo facet_wrap(~phenotype) + # Dividir tratamiento labs(x = "Bloques de secuenciación", y="Genes detectados \\n(log)", title = "Genes detectados") # Etiquetas en X, Y y titulo 2.9.6 Filtro A: Fixed thresholds Para el filtrado y eliminación de las células de baja calidad emplearemos las variables sum, detected, altexps_ERCC_percent y subsets_Mito_percent. # --- Fixed thresholds --- # Valores de corte fijos y estrictos qc.lib <- sce.416b$sum < 100000 # menos de 100 mil cuentas (lecturas) qc.nexprs <- sce.416b$detected < 5000 # menos de 5 mil genes qc.spike <- sce.416b$altexps_ERCC_percent > 10 # 10 % de las cuentas alineando a ERCC qc.mito <- sce.416b$subsets_Mito_percent > 10 # 10 % alineando al genoma mitocondrial discard <- qc.lib | qc.nexprs | qc.spike | qc.mito # si falla alguno de estos eliminarlo # secuencias control = (ERCC spike-in control transcripts) # Resumen del número de células # Número de células eliminadas por cada filtro DataFrame( LibSize = sum(qc.lib), NExprs = sum(qc.nexprs), SpikeProp = sum(qc.spike), MitoProp = sum(qc.mito), Total = sum(discard) ) ## DataFrame with 1 row and 5 columns ## LibSize NExprs SpikeProp MitoProp Total ## <integer> <integer> <integer> <integer> <integer> ## 1 3 0 19 14 33 2.9.7 Filtro B: Adaptative thresholds Valores de cortes adaptados al comportamiento de nuestros datos. # --- Adaptative thresholds --- ## Usando isOutlier() para determinar los valores de corte qc.lib2 <- isOutlier(sce.416b$sum, log = TRUE, type = "lower") qc.nexprs2 <- isOutlier(sce.416b$detected, log = TRUE, type = "lower" ) qc.spike2 <- isOutlier(sce.416b$altexps_ERCC_percent, type = "higher" ) qc.mito2 <- isOutlier(sce.416b$subsets_Mito_percent, type = "higher" ) discard2 <- qc.lib2 | qc.nexprs2 | qc.spike2 | qc.mito2 # Extraemos los límites de valores (thresholds) attr(qc.lib2, "thresholds") ## lower higher ## 434082.9 Inf attr(qc.nexprs2, "thresholds") ## lower higher ## 5231.468 Inf # Obtenemos un resumen del número de células # eliminadas por cada filtro DataFrame( LibSize = sum(qc.lib2), NExprs = sum(qc.nexprs2), SpikeProp = sum(qc.spike2), MitoProp = sum(qc.mito2), Total = sum(discard2) ) ## DataFrame with 1 row and 5 columns ## LibSize NExprs SpikeProp MitoProp Total ## <integer> <integer> <integer> <integer> <integer> ## 1 4 0 1 2 6 2.9.8 Preguntas por resolver ¿Cuántos células se descartan con cada filtro? ¿Cuántas células se comparten entre ambos filtros? ¿Cúal filtro fue más estricto? ¿Existen células que el filtro adaptativo excluyera y que no lo hiciera el filtro estricto? Para contestar estas preguntas podemos emplear: addmargins(table(discard, discard2)) ## discard2 ## discard FALSE TRUE Sum ## FALSE 159 0 159 ## TRUE 27 6 33 ## Sum 186 6 192 2.10 ¿Cómo funciona isOutlier()? Supongamos que la mayor parte del conjunto de datos está formado por células de alta calidad 1 (Opcional: log-transformar la métrica QC) 1. Calcular la mediana de la métrica QC Calcular la desviación absoluta de la mediana (MAD2) de la QC Identifique los valores atípicos como aquellas celdas con una métrica QC a más de 3 MAD3 de la mediana en la dirección “problemática”. Puede controlar cuántas MAD son aceptables Puede decidir qué dirección es problemática QC = Quality Control 1 But we’ll relax that assumption in a few moments 2 MAD is similar to standard deviation 3 Loosely, 3 MADs will retain 99% of non-outliers values that follow a Normal distribution. Figura explicativa, Diapositiva 24. 2.11 Consideran el Batch ## Determino el bloque (batch) de muestras batch <- paste0(sce.416b$phenotype, "-", sce.416b$block) ## Versión de isOutlier() que toma en cuenta los bloques de muestras qc.lib3 <- isOutlier(sce.416b$sum, log = TRUE, type = "lower", batch = batch ) qc.nexprs3 <- isOutlier(sce.416b$detected, log = TRUE, type = "lower", batch = batch ) qc.spike3 <- isOutlier(sce.416b$altexps_ERCC_percent, type = "higher", batch = batch ) qc.mito3 <- isOutlier(sce.416b$subsets_Mito_percent, type = "higher", batch = batch ) discard3 <- qc.lib3 | qc.nexprs3 | qc.spike3 | qc.mito3 # Extraemos los límites de valores (thresholds) attr(qc.lib3, "thresholds") ## induced CBFB-MYH11 oncogene expression-20160113 induced CBFB-MYH11 oncogene expression-20160325 ## lower 461073.1 399133.7 ## higher Inf Inf ## wild type phenotype-20160113 wild type phenotype-20160325 ## lower 599794.9 370316.5 ## higher Inf Inf # Obtenemos un resumen del número de células # eliminadas por cada filtro DataFrame( LibSize = sum(qc.lib3), NExprs = sum(qc.nexprs3), SpikeProp = sum(qc.spike3), MitoProp = sum(qc.mito3), Total = sum(discard3) ) ## DataFrame with 1 row and 5 columns ## LibSize NExprs SpikeProp MitoProp Total ## <integer> <integer> <integer> <integer> <integer> ## 1 5 4 6 2 9 2.12 Visualización gráfica de las células de buena calidad Usaremos el filtro estricto y visualizaremos la distribución de los datos. # Reducir el nombre en los fenotipos / tratamientos sce.416b_edited <- sce.416b sce.416b_edited$phenotype <- ifelse(grepl("induced", sce.416b_edited$phenotype), "induced", "wild type") # Verificar unique(sce.416b_edited$phenotype) ## [1] "wild type" "induced" # Agregar columna de genes descartados sce.416b_edited$discard <- discard # Visualizacion grafica plotColData(sce.416b_edited, x="block", y="sum", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + labs(x = "Bloques de secuenciacion", y="Cuentas totales", title = "Numero de cuentas") # Etiquetas en X, Y y titulo Visualizacion de todas las variables en una sola gráfica. # Visualizacion grafica gridExtra::grid.arrange( plotColData(sce.416b_edited, x="block", y="sum", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + scale_y_log10() + labs(x = "Bloques de secuenciacion", y="Cuentas totales", title = "Numero de cuentas"), # Etiquetas en X, Y y titulo plotColData(sce.416b_edited, x="block", y="detected", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + scale_y_log10() + labs(x = "Bloques de secuenciacion", y="Genes expresados", title = "Numero de genes /n(log)"), # Etiquetas en X, Y y titulo plotColData(sce.416b_edited, x="block", y="subsets_Mito_percent", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + labs(x = "Bloques de secuenciacion", y="Porcentaje de genes mitocondriales /n(%)", title = "Contenido mitocondrial"), # Etiquetas en X, Y y titulo plotColData(sce.416b_edited, x="block", y="altexps_ERCC_percent", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + labs(x = "Bloques de secuenciacion", y="Porcentaje de ERCC /n(%)", title = "Contenido de ERCC"), # Etiquetas en X, Y y titulo, ncol=1 ) Otra visualización gráfica es: plotColData( sce.416b_edited, x = "sum", y = "subsets_Mito_percent", colour_by = "discard", other_fields = c("block", "phenotype") ) + facet_grid(block ~ phenotype) 2.13 Identificando droplets vacíos con datos de PBMC 2.13.1 Conceptos básicos Descripción gráfica de la tecnología Next GEM de 10x Genomics. Fuente: 10x Genomics. Opciones algorítmicas para detectar los droplets vacíos. Fuente: Lun et al, Genome Biology, 2019. 2.13.2 Información de los datos El dataset proviene de células humanas, con un total de 4,340 células con buena calidad. Para más información consulta la página web en 10Xgenomics. A continuación te presento el reporte de este dataset. Captura del reporte de secuenciación del dataset. 10Xgenomics realiza un alineamiento genómico con STAR y emplea CellRanger para realizar la limpieza y cuantificación de los datos. Encontrado la información dividia en dos carpetas importantes: Gene/cell matrix (raw): Contiene toda la información posterior al alineamiento, sin limpiar. Contiene toda la información, contemplando la presencia de doplets vacíos. Gene/cell matrix (filtered): Contiene los datos filtrados por CellRanger. Dejo a tu consideración la posibilidad de emplear alguno de estos archivos. Ambas carpetas contienen 3 archivos importantes para el análisis de los datos: barcode.tsv = Secuencia que define a cada célula por identificadores de cada célula. feature.tsv = Genes identificadores, se les midió expresión. matrix.mtx = Unión entre las secuencias y genes. 2.13.3 Importar datos en R Almacenaremos la información de 10Xgenomics en la memoria Cache de la computadora y posteriormente lo almacenaremos en una variable. # Datos crudos, sin procesar bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) # Archivos contenidos en Temporales test_dir <- tempdir() test_dir <- paste0(test_dir, "/pbmc4k/raw_gene_bc_matrices/GRCh38") list.files(test_dir) # Encontraremos 3 tipos de archivos: barcodes.tsv, genes.tsv y matrix.mtx ## [1] "barcodes.tsv" "genes.tsv" "matrix.mtx" # Cargar datos fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) # Cargar datos de 10Xgenomics de CellRanger sce.pbmc ## class: SingleCellExperiment ## dim: 33694 737280 ## metadata(1): Samples ## assays(1): counts ## rownames(33694): ENSG00000243485 ENSG00000237613 ... ENSG00000277475 ENSG00000268674 ## rowData names(2): ID Symbol ## colnames(737280): AAACCTGAGAAACCAT-1 AAACCTGAGAAACCGC-1 ... TTTGTCATCTTTAGTC-1 TTTGTCATCTTTCCTC-1 ## colData names(2): Sample Barcode ## reducedDimNames(0): ## mainExpName: NULL ## altExpNames(0): Contiene 737280 droplets, aún sin filtrar y evaluando un total de 33,694 genes en este dataset. Si quisieras descargar estos mismos datos pero filtrados, te dejo la ruta: # Datos filtrados, sin celulas muertas, sin un alto contenido mitocondrial, sin droplets vacios o con multiples celulas bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_filtered_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) 2.13.4 Visualización de droplets vacíos bcrank <- barcodeRanks(counts(sce.pbmc)) bcrank ## DataFrame with 737280 rows and 3 columns ## rank total fitted ## <numeric> <integer> <numeric> ## AAACCTGAGAAACCAT-1 219086 1 NA ## AAACCTGAGAAACCGC-1 504862 0 NA ## AAACCTGAGAAACCTA-1 219086 1 NA ## AAACCTGAGAAACGAG-1 504862 0 NA ## AAACCTGAGAAACGCC-1 219086 1 NA ## ... ... ... ... ## TTTGTCATCTTTACAC-1 150232 2 NA ## TTTGTCATCTTTACGT-1 26415 33 NA ## TTTGTCATCTTTAGGG-1 504862 0 NA ## TTTGTCATCTTTAGTC-1 504862 0 NA ## TTTGTCATCTTTCCTC-1 219086 1 NA # Mostremos solo los puntos únicos para acelerar # el proceso de hacer esta gráfica uniq <- !duplicated(bcrank$rank) plot( bcrank$rank[uniq], bcrank$total[uniq], log = "xy", xlab = "Rank", ylab = "Total UMI count", cex.lab = 1.2) ## Warning in xy.coords(x, y, xlabel, ylabel, log): 1 y value <= 0 omitted from logarithmic plot # Agregarle los puntos de corte abline( h = metadata(bcrank)$inflection, col = "darkgreen", lty = 2) abline( h = metadata(bcrank)$knee, col = "dodgerblue", lty = 2) legend( "bottomleft", legend = c("Inflection", "Knee"), col = c("darkgreen", "dodgerblue"), lty = 2, cex = 1.2) UMI = Secuencia única de cada unión en la bead (unique molecular identifiers). Encontremos los droplets vacíos usando emptyDrops(). Los siguientes pasos demoran un tiempo. ## Usemos DropletUtils para encontrar los droplets set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) # Revisa ?emptyDrops para una explicación de por qué hay valores NA summary(e.out$FDR <= 0.001) ## Mode FALSE TRUE NA's ## logical 1006 4283 731991 set.seed(100) limit <- 100 all.out <- emptyDrops(counts(sce.pbmc), lower = limit, test.ambient = TRUE) # Idealmente, este histograma debería verse uniforme. # Picos grandes cerca de cero indican que los _barcodes_ # con un número total de cuentas menor a "lower" no son # de origen ambiental. hist(all.out$PValue[all.out$Total <= limit & all.out$Total > 0], xlab = "P-value", main = "", col = "grey80") 2.13.5 Anotación de genes y eliminación de doples vacíos # Anotación de los genes rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) ## Warning: Unable to map 144 of 33694 requested IDs. # Detección de _droplets_ con células set.seed(100) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] 2.13.6 Control de calidad # Obtener las estadisticas en un archivo aparte stats <- perCellQCMetrics(sce.pbmc, subsets = list(Mito = which(location == "MT")) ) high.mito <- isOutlier(stats$subsets_Mito_percent, type = "higher" ) # Eliminar secuencias con alto contenido de genes mitocondriales sce.pbmc <- sce.pbmc[, !high.mito] 2.14 Visualización de los datos con ISEE Github de iSEE. Workshop de iSEE 2.15 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:25:22 EDT" proc.time() ## user system elapsed ## 996.461 97.738 94971.378 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── El dataset cuenta con 192 células, sce.416b↩︎ El dataset cuenta con 46,604 genes detectados, sce.416b↩︎ "],["normalización-de-datos.html", "3 Normalización de datos 3.1 Material 3.2 Motivación 3.3 Datos 3.4 Normalización por escalamiento (scaling normalization) 3.5 Normalización por deconvolución (deconvolution) 3.6 Transformación logarítmica 3.7 Otras normalizaciones 3.8 Dónde estamos 3.9 Adicionales 3.10 Agradecimientos 3.11 Detalles de la sesión de R", " 3 Normalización de datos Instructora: Dra Laura Lucila Gómez Romero 3.1 Material Diapositivas de Peter Hickey: Ve las diapositivas aquí Capítulo de OSCA: Ve el capítulo del libro OSCA aquí 3.2 Motivación Al igual que con otras tecnologías, single-cell RNA-seq (scRNA-seq) puede presentar diferencias sistemáticas en la cobertura de las librerías de scRAN-seq. Típicamente se debe a diferencias técnicas en procesos como la captura de cDNA, la eficiencia de la amplificación por PCR. La normalización tiene como objetivo remover estas diferencias sistemáticas para que no interfieran cuando comparamos los perfiles de expresión entre células. Al normalizar los datos, las diferencias observadas entre poblaciones celulares o condiciones son debido a la biología y no por factores técnicos. La normalización es diferente a la corrección por lote . El proceso de normalización se lleva a cabo sin importar la estructura de los lotes y sólo considera sesgos técnicos, los cuales tienden a afectar los genes en una manera medianamente similar, por ejemplo: la eficiencia de la amplificación por PCR debido al contenido de GC o la longitud del gene. ¿Qué es correción por lote (batch effect correction)? Da un ejemplo. “Large single-cell RNA sequencing (scRNA-seq) projects usually need to generate data across multiple batches due to logistical constraints. However, the processing of different batches is often subject to uncontrollable differences, e.g., changes in operator, differences in reagent quality. This results in systematic differences in the observed expression in cells from different batches, which we refer to as “batch effects”. Batch effects are problematic as they can be major drivers of heterogeneity in the data, masking the relevant biological differences and complicating interpretation of the results” -OSCA ¿Cuáles son las diferencias entre correción por lote y normalización? “Normalization occurs regardless of the batch structure and only considers technical biases, while batch correction - as the name suggests - only occurs across batches and must consider both technical biases and biological differences. Technical biases tend to affect genes in a similar manner, or at least in a manner related to their biophysical properties (e.g., length, GC content), while biological differences between batches can be highly unpredictable” -OSCA 3.3 Datos Usaremos el dataset de Zeisel. Tipos celulares en cerebro de ratón (oligodendrocitos, microglias, neuronas, etc.) Procesado con STRT-seq (similar a CEL-seq), un sistema de microfluido. 3005 células y 18441 genes. Contiene UMIs. library("scRNAseq") sce.zeisel <- ZeiselBrainData(ensembl = TRUE) sce.zeisel ## class: SingleCellExperiment ## dim: 18441 3005 ## metadata(0): ## assays(1): counts ## rownames(18441): ENSMUSG00000029669 ENSMUSG00000046982 ... ENSMUSG00000064337 ENSMUSG00000065947 ## rowData names(2): featureType originalName ## colnames(3005): 1772071015_C02 1772071017_G12 ... 1772066098_A12 1772058148_F03 ## colData names(10): tissue group # ... level1class level2class ## reducedDimNames(0): ## mainExpName: endogenous ## altExpNames(2): ERCC repeat 3.3.1 Primero se debe hacer el control de calidad Eliminando células de baja calidad: Outliers bajos para log(cuenta total) Outliers bajos para log(número de features detectados) Outliers altos para el porcentaje de cuentas de conjuntos de genes especificados (mitocondriales, transcritos spike-in) # Control de calidad library("scater") unfiltered <- sce.zeisel is.mito <- which(rowData(sce.zeisel)$featureType == "mito") stats <- perCellQCMetrics(sce.zeisel, subsets = list(Mt = is.mito)) qc <- quickPerCellQC(stats, percent_subsets = c("altexps_ERCC_percent", "subsets_Mt_percent") ) colSums(as.data.frame(qc)) ## low_lib_size low_n_features high_altexps_ERCC_percent high_subsets_Mt_percent ## 0 3 66 128 ## discard ## 190 sce.zeisel <- sce.zeisel[, !qc$discard] 3.4 Normalización por escalamiento (scaling normalization) La normalización por escalamiento es la estrategia más simple y usada. Suposición: Cualquier sesgo específico en cada célula afecta a todos los genes de igual manera a través de escalar por el promedio esperado de cuentas para dicha célula. Se realiza de la siguiente manera: Estima un “size factor” para cada célula. Este factor representa el sesgo relativo en esa célula. Divide las cuentas de los genes de cada célula entre su correspondiente “size factor”. \\[ CuentasNormalizadas = Cuentas / Size factor\\] Los valores de expresión normalizados pueden ser usados por análisis posteriores como clustering o reducción de dimensiones. 3.4.1 Normalizacion por tamaño de biblioteca (Library Size normalization) Tamaño de biblioteca (Library Size): La suma total de las cuentas a tráves de todos los genes en una célula. Asumimos que este valor escala con cualquier sesgo específico en cada célula. \\[Library Size_{cell} = \\sum_{n=1}^{j} gene\\] Donde \\(j\\) es el número total de genes y \\(gene\\) es el número de cuentas por gen en la célula \\(cell\\). Para escalar los datos ocuparemos un factor de escalamiento llamado Library Size factor. Este valor se calcula a partir de escalar el tamaño de la biblioteca, tal que el promedio de los Library Size factor en todas las células sea igual a 1. \\[ mean(Library Size factor) = 1 \\] Lo que nos permite que los valores normalizados están en la misma escala y pueden ser útiles para la interpretación. # Estimar factores de normalización lib.sf.zeisel <- librarySizeFactors(sce.zeisel) # Examina la distribución de los tamaños de librerías # que acabamos de estimar summary(lib.sf.zeisel) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0.1754 0.5682 0.8669 1.0000 1.2758 4.0651 hist(log10(lib.sf.zeisel), xlab = "Log10[Library Size factor]", col = "grey80") ¿A qué crees que se deba la variación en los factores de escalamiento? ## Calculando el tamaño de las librerias ls.zeisel <- colSums(counts(sce.zeisel)) plot(ls.zeisel, lib.sf.zeisel, log="xy", xlab="Library size", ylab="Size factor") 3.4.2 Puntos finales La normalización por tamaño de biblioteca asume que no hay un sesgo de composición, es decir, si existe un grupo de genes cuya expresión aumenta entonces debe existir otro grupo de genes para los que la expresión disminuye en la misma magnitud, esto generalmente no es verdad para los experimentos de scRNA-seq. Para algunos análisis exploratorios, la precisión de la normalización no es un punto mayor a considerar. La normalizacion por tamaño de biblioteca suele ser suficiente en algunas ocasiones donde se busca identificar clusters y los marcadores de los clusters, dado que el sesgo por composición normalmente no afecta la separación de los clusters, sólo la magnitud. Sin embargo, esta falta de precisión podría afectar cuando se busca obtener estimaciones y estadísticas a nivel de genes individuales. 3.5 Normalización por deconvolución (deconvolution) El problema causado por el sesgo de composición y cómo eliminarlo ha sido estudiado en bulk RNA-seq por métodos como DESeq2::estimateSizeFactorsFromMatrix() y edgeR::calcNormFactors(). En ambos casos, se asume que la mayoría de genes no estarán diferencialmente expresados entre las muestras (en nuestro caso células) y cualquier diferencia entre los genes no diferencialmente expresados representa un sesgo el cual se remueve utilzando el factor de normalización calculado. Sin embargo, en single-cell RNA-seq se tienen muchas cuentas bajas y ceros debido a limitaciones en la tecnología, las cuales no necesariamente indican ausencia de expresión. Para este fenómento no están preparados los métodos utilizados en bulk RNA-seq. La normalización por deconvolución (o normalización scran): Junta las cuentas de varias células (pool) para incrementar el tamaño de las cuentas, reduciendo ceros y cuentas bajas. Aplica los métodos de normalización que corrigen el sesgo de composición. Repiten esto para conjuntos sobrelapantes de células para obtener size factors en pool. Deconvoluciona estos size factors en pool para obtener size factors para cada célula. # Normalización por deconvolución (deconvolution) library("scran") # Pre-clustering (establece una semilla para obtener resultados reproducibles) set.seed(100) clust.zeisel <- quickCluster(sce.zeisel) # Calcula factores de tamaño para la deconvolución (deconvolution) deconv.sf.zeisel <- calculateSumFactors(sce.zeisel, clusters = clust.zeisel, min.mean = 0.1) El pre-clustering mejora la estimación de los size factors al normalizar células similares juntas. # Examina la distribución de los factores de tamaño summary(deconv.sf.zeisel) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0.1282 0.4859 0.8248 1.0000 1.3194 4.6521 hist(log10(deconv.sf.zeisel), xlab = "Log10[Deconvolution size factor]", col = "grey80" ) plot(lib.sf.zeisel, deconv.sf.zeisel, xlab = "Library size factor", ylab = "Deconvolution size factor", log = "xy", pch = 16, col=as.integer(factor(sce.zeisel$level1class)) ) abline(a = 0, b = 1, col = "red") 3.5.1 Puntos finales La normalización por deconvolución (deconvolution) mejora los resultados para análisis posteriores de una manera más precisa que los métodos para bulk RNA-seq. El método scran::calculateSumFactors algunas veces calcula factores negativos o ceros lo cual altera la matriz de expresión normalizada. ¡Checa los factores que calculas! Si obtienes factores negativos intenta variar el número de clusters. summary(deconv.sf.zeisel) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0.1282 0.4859 0.8248 1.0000 1.3194 4.6521 3.6 Transformación logarítmica Una vez calculados los factores de normalización con computeSumFactors(), podemos calcular las cuentas en escala logarítmica usando logNormCounts(). ¿Qué es lo que hace esta función? Divide las cuentas de cada gene por el size factor correspondiente para esa célula (estos serían los valores normalizados) y entonces le aplica una transformción logarítmica a estos valores normalizados. Típicamente agrega una pseudo-cuenta de 1 para evitar calcular log(0). Estas cuentas en escala log se conocen como: valores de expresión normalizados en escala logarítmica (log-transformed normalized expression values). sce.zeisel ## class: SingleCellExperiment ## dim: 18441 2815 ## metadata(0): ## assays(1): counts ## rownames(18441): ENSMUSG00000029669 ENSMUSG00000046982 ... ENSMUSG00000064337 ENSMUSG00000065947 ## rowData names(2): featureType originalName ## colnames(2815): 1772071015_C02 1772071017_G12 ... 1772063068_D01 1772066098_A12 ## colData names(10): tissue group # ... level1class level2class ## reducedDimNames(0): ## mainExpName: endogenous ## altExpNames(2): ERCC repeat # Normalization # Esto agrega el "sizeFactor" como parte del objeto # set.seed(100) # clust.zeisel <- quickCluster(sce.zeisel) sce.zeisel <- computeSumFactors(sce.zeisel, cluster=clust.zeisel, min.mean=0.1) sce.zeisel ## class: SingleCellExperiment ## dim: 18441 2815 ## metadata(0): ## assays(1): counts ## rownames(18441): ENSMUSG00000029669 ENSMUSG00000046982 ... ENSMUSG00000064337 ENSMUSG00000065947 ## rowData names(2): featureType originalName ## colnames(2815): 1772071015_C02 1772071017_G12 ... 1772063068_D01 1772066098_A12 ## colData names(11): tissue group # ... level2class sizeFactor ## reducedDimNames(0): ## mainExpName: endogenous ## altExpNames(2): ERCC repeat # Log transformation sce.zeisel <- scater::logNormCounts(sce.zeisel) assayNames(sce.zeisel) ## [1] "counts" "logcounts" 3.6.1 Motivación, ¿Por qué hacemos esta transformación? ¿Qué gen es más interesante? Gen X: el promedio de expresión en el tipo celular A: 50 y B: 10 Gen Y: el promedio de expresión en el tipo celular A: 1100 y B: 1000 50 - 10 ## [1] 40 1100 - 1000 ## [1] 100 log(50) - log(10) ## [1] 1.609438 log(1100) - log(1000) ## [1] 0.09531018 Exacto, Gen X 3.6.2 Lluvia de ideas ¿Qué pasa cuando hacemos la transformación logarítmica? ¿Qué es una pseudo-cuenta? ¿Por qué se usa? ¿Qué valor de pseudo-cuenta usa logNormCounts()? 3.7 Otras normalizaciones Te invitamos a leer más sobre otras formas de normalizar, para empezar puedes consultar el siguiente curso del Sanger Institute. Si estas interesad@ en diferencias en el contenido total de RNA en cada célula, checa la normalización por spike-ins. La cual asume que los spike-ins fueron añadidos en un nivel constante en cada célula. Si tienes resultados donde el library size está asociado a tus datos a pesar de haber normalizado, checa la opción de downsample=TRUE dentro de la función de logNormCounts(). Si te gustaría tener factores de normalización específicos para cada gen que tomen en cuenta la varianza, checa las funciones varianceStabilizingTransformation() de DESeq2 o sctransform de Seurat. 3.8 Dónde estamos 3.9 Adicionales [1] 2018 BioInfoSummer Workshop [2] HBC training 3.10 Agradecimientos Este curso está basado en el libro Orchestrating Single Cell Analysis with Bioconductor de Aaron Lun, Robert Amezquita, Stephanie Hicks y Raphael Gottardo, además del curso de scRNA-seq para WEHI creado por Peter Hickey. Y en el material de la comunidadbioinfo/cdsb2020 con el permiso de Leonardo Collado-Torres. 3.11 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:25:52 EDT" proc.time() ## user system elapsed ## 1022.206 100.158 95001.934 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── "],["selección-de-genes-altamente-variables.html", "4 Selección de genes altamente variables 4.1 Diapositivas de Peter Hickey 4.2 Motivación 4.3 Selección de features (genes) 4.4 Dataset ilustrativo: PBMC4k 10X sin filtrar 4.5 Dataset ilustrativo: 416B 4.6 Cuantificando la varianza por gen 4.7 Coeficiente de variación de las cuentas 4.8 Varianza de los log-counts vs coeficiente de variación 4.9 Cuantificando el ruido técnico 4.10 En la ausencia de spike-ins 4.11 Recordemos propiedades de los datos de sce.416b 4.12 Considerando factores experimentales 4.13 Seleccionando genes altamante variables (high-variable genes, HVGs) 4.14 Poniendo todo junto 4.15 Resumen y recomendaciones 4.16 Recomendaciones para empezar 4.17 Detalles de la sesión de R", " 4 Selección de genes altamente variables José Antonio Ovando 08 de agosto de 2023 4.1 Diapositivas de Peter Hickey Ver las diapositivas originales aquí 4.2 Motivación Usualmente usamos datos scRNA-seq para caracterizar la heterogeneidad entre células Para hacer esto, usamos métodos como el clustering y la reducción de dimensionalidad Esto involucra resumir las diferencias por gen en una sola medida de (dis)similitud entre un par de células ¿Cuáles genes deberíamos usar para calcular esta medida de (dis)similitud? 4.3 Selección de features (genes) La elección de los features tiene un mayor impacto en qué tan similares decidimos que son las células ➕ Features que contienen información útil biológica ➖ Features que contienen ruido aleatorio 👉 Efectos laterales al reducir la dimensionalidad de los datos Deseamos seleccionar los genes altamente variables (High Variable Genes HVGs). Genes con una variación incrementada en comparación con otros genes que están siendo afectados por ruido técnico u otra variación biológica que no es de nuestro interés. 4.4 Dataset ilustrativo: PBMC4k 10X sin filtrar 4.4.1 Descargar datos # Usemos datos de pbmc4k library(BiocFileCache) bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) library(DropletUtils) library(Matrix) fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) sce.pbmc ## class: SingleCellExperiment ## dim: 33694 737280 ## metadata(1): Samples ## assays(1): counts ## rownames(33694): ENSG00000243485 ENSG00000237613 ... ENSG00000277475 ENSG00000268674 ## rowData names(2): ID Symbol ## colnames(737280): AAACCTGAGAAACCAT-1 AAACCTGAGAAACCGC-1 ... TTTGTCATCTTTAGTC-1 TTTGTCATCTTTCCTC-1 ## colData names(2): Sample Barcode ## reducedDimNames(0): ## mainExpName: NULL ## altExpNames(0): Dataset “Células mononucleares humanas de sangre periférica” de 10X Genomics Descripción aquí 3 4.4.2 Anotación # Anotación de los genes library(scater) rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) library(EnsDb.Hsapiens.v86) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) # Detección de _droplets_ con células set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] 4.4.3 Control de calidad # Control de calidad stats <- perCellQCMetrics(sce.pbmc, subsets = list(Mito = which(location == "MT")) ) high.mito <- isOutlier(stats$subsets_Mito_percent, type = "higher" ) sce.pbmc <- sce.pbmc[, !high.mito] # Normalización de los datos library(scran) set.seed(1000) clusters <- quickCluster(sce.pbmc) sce.pbmc <- computeSumFactors(sce.pbmc, cluster = clusters) sce.pbmc <- logNormCounts(sce.pbmc) 4.5 Dataset ilustrativo: 416B library(scRNAseq) sce.416b <- LunSpikeInData(which = "416b") sce.416b$block <- factor(sce.416b$block) Línea celular de células mieloides progenitoras inmortalizadas de ratón usando SmartSeq2 https://osca.bioconductor.org/lun-416b-cell-line-smart-seq2.html 4 # gene-annotation library(AnnotationHub) ens.mm.v97 <- AnnotationHub()[["AH73905"]] rowData(sce.416b)$ENSEMBL <- rownames(sce.416b) rowData(sce.416b)$SYMBOL <- mapIds(ens.mm.v97, keys = rownames(sce.416b), keytype = "GENEID", column = "SYMBOL" ) rowData(sce.416b)$SEQNAME <- mapIds(ens.mm.v97, keys = rownames(sce.416b), keytype = "GENEID", column = "SEQNAME" ) library(scater) rownames(sce.416b) <- uniquifyFeatureNames( rowData(sce.416b)$ENSEMBL, rowData(sce.416b)$SYMBOL ) # quality-control mito <- which(rowData(sce.416b)$SEQNAME == "MT") stats <- perCellQCMetrics(sce.416b, subsets = list(Mt = mito)) qc <- quickPerCellQC(stats, percent_subsets = c("subsets_Mt_percent", "altexps_ERCC_percent"), batch = sce.416b$block ) sce.416b <- sce.416b[, !qc$discard] # normalization library(scran) sce.416b <- computeSumFactors(sce.416b) sce.416b <- logNormCounts(sce.416b) 4.6 Cuantificando la varianza por gen 4.6.1 Varianza de los log-counts El enfoque más simple para cuantificar la variación per-feature es simplemente calcular la varianza de los log-counts ➕ Selección del feature basado en los log-counts (que serán usadas en los análisis más adelante) ⚠️ La transformación log no logra la estabilización de la varianza perfecta, así que se requiere modelar la relación de la varianza-media de los features. 4.6.2 Enfoque simple Calcular la varianza de los log-counts para cada gen (ignorando grupos experimentales) Ordenar los genes del más-al-menos variable 4.6.3 Un enfoque más sofisticado Calcular la varianza de los log-counts para cada gen (ignorando grupos experimentales) Modelar la relación entre la media y la varianza de los log-counts para estimar la variación técnica Estimar la varianza biológica sustrayendo la varianza técnica de la varianza total Ordenar los genes de la variable de mayor-a-menor biológicamente 4.6.4 Supuestos # Varianza de las log-counts library(scran) dec.pbmc <- modelGeneVar(sce.pbmc) 🤓 El supuesto es que a cualquier abundancia dada, la abundancia de los perfiles de expresión de la mayoría de los genes están dominados por el ruido aleatorio técnico 🤓 Por lo consiguiente, una tendencia representa un estimado del ruido técnico como una función de la abundancia 🤓 Podemos entonces descomponer la varianza total de cada gen en un componente técnico y uno biológico 🤓 Genes con una gran varianza biológica son considerados interesantes 4.6.5 Visualizando la media y varianza # Visualicemos la relación entre la media y la varianza fit.pbmc <- metadata(dec.pbmc) plot(fit.pbmc$mean, fit.pbmc$var, xlab = "Mean of log-expression", ylab = "Variance of log-expression" ) curve(fit.pbmc$trend(x), col = "dodgerblue", add = TRUE, lwd = 2) 4.6.6 Ordenando genes interesantes # Ordenemos por los genes más interesantes para checar # los datos dec.pbmc[order(dec.pbmc$bio, decreasing = TRUE), ] ## DataFrame with 33694 rows and 6 columns ## mean total tech bio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## LYZ 1.94129 4.99949 0.824172 4.17532 1.44008e-250 2.83205e-246 ## S100A9 1.92243 4.48842 0.824008 3.66441 1.25315e-193 6.16112e-190 ## S100A8 1.68566 4.35303 0.814526 3.53850 6.89502e-185 2.71195e-181 ## HLA-DRA 2.09063 3.73576 0.819396 2.91636 7.27124e-125 1.19164e-121 ## CD74 2.90080 3.34898 0.786799 2.56218 6.72905e-105 6.96492e-102 ## ... ... ... ... ... ... ... ## PTMA 3.83144 0.474774 0.733464 -0.258690 0.990672 1 ## HLA-B 4.49970 0.479899 0.748285 -0.268386 0.991626 1 ## EIF1 3.23434 0.471616 0.766366 -0.294750 0.994844 1 ## TMSB4X 6.07476 0.408677 0.719095 -0.310419 0.998006 1 ## B2M 5.94601 0.311508 0.690710 -0.379202 0.999875 1 4.7 Coeficiente de variación de las cuentas El coeficiente de variación de las cuentas al cuadrado (CV2) es una alternativa a la varianza de los log-counts 👉 Se calcula usando las cuentas en lugar de los log-counts 🤓 CV es el ratio de la desviación estándar a la media y está muy relacionada con el parámetro de dispersión de la distribución binomial negativa usada en edgeR y DESeq2 4.7.1 Coeficiente de variación # Coeficiente de variación dec.cv2.pbmc <- modelGeneCV2(sce.pbmc) 🤓 Modela la relación de la media de la varianza cuando se considera la relevancia de cada gen 🤓 Asume que la mayoría de los genes contienen ruido aleatorio y que la tendencia captura la mayoría de la variación técnica 🤓 Genes con un gran CV2 que se desvían fuertemente de la tendencia es probable que representen genes afectados por la estructura biológica 🤓 Usa la tasa (en lugar de la diferencia) del CV2 a la tendencia 4.7.2 Visualizando el coeficiente de variación # Visualicemos la relación con la media fit.cv2.pbmc <- metadata(dec.cv2.pbmc) plot(fit.cv2.pbmc$mean, fit.cv2.pbmc$cv2, log = "xy" ) curve(fit.cv2.pbmc$trend(x), col = "dodgerblue", add = TRUE, lwd = 2 ) 4.7.3 Genes por coeficiente de variación # Ordenemos por los genes más interesantes para checar # los datos dec.cv2.pbmc[order(dec.cv2.pbmc$ratio, decreasing = TRUE ), ] ## DataFrame with 33694 rows and 6 columns ## mean total trend ratio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## GNG11 1.0300722 694.193 1.39084 499.117 0 0 ## PTK7 0.0710992 3664.385 17.32128 211.554 0 0 ## RNF208 0.0721694 3558.419 17.06755 208.490 0 0 ## TUBA8 0.0723199 3544.014 17.03246 208.074 0 0 ## ARHGAP6 0.0777368 3074.612 15.86022 193.857 0 0 ## ... ... ... ... ... ... ... ## AC023491.2 0 NaN Inf NaN NaN NaN ## AC233755.2 0 NaN Inf NaN NaN NaN ## AC233755.1 0 NaN Inf NaN NaN NaN ## AC213203.1 0 NaN Inf NaN NaN NaN ## FAM231B 0 NaN Inf NaN NaN NaN 4.8 Varianza de los log-counts vs coeficiente de variación Generalmente se usa la varianza de los log-counts Ambas son medidas efectivas para cuantificar la variación en la expresión génica CV2 tiende a tener otorgar rangos altos a genes altamente variables (HGVs) con bajos niveles de expresión Éstos son dirigidos por una sobreregulación en subpoblaciones raras Puede asignar un alto rango a genes que no son de nuestro interés con varianza baja absoluta La variación descrita por el CV2 de las cuentas es menos relevante para los procedimientos que operan en los log-counts 4.9 Cuantificando el ruido técnico Previamente, ajustamos una línea de tendencia a todos los genes endógenos y asumimos que la mayoría de los genes no están dominados por ruido técnico En la práctica, todos los genes expresados tienen algún nivel de variabilidad biológica diferente de cero (e.g., transcriptional bursting) Esto sugiere que nuestros estimados de los componentes técnicos estarán inflados probablemente 👉 Es mejor que pensemos estos estimados como una variación técnica más la variación biológica que no es interesante 🤔 Pero que tal si un grupo de genes a una abundancia particular es afectado por un proceso biológico? E.g., fuerte sobre regulación de genes específicos de un tipo celular podrían conllevar a un enriquecimiento de HVGs en abundancias altas. Esto inflaría la tendencia y compromete la detección de los genes relevantes ¿Cómo podemos evitar este problema? Podemos revisar dos enfoques: Cuando tenemos spike-ins Cuando no tenemos spike-ins 4.9.1 En la presencia de spike-ins dec.spike.416b <- modelGeneVarWithSpikes( sce.416b, "ERCC" ) # Ordering by most interesting genes for # inspection. dec.spike.416b[order(dec.spike.416b$bio, decreasing = TRUE ), ] ## DataFrame with 46604 rows and 6 columns ## mean total tech bio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## Lyz2 6.61097 13.8497 1.57131 12.2784 1.48993e-186 1.54156e-183 ## Ccl9 6.67846 13.1869 1.50035 11.6866 2.21855e-185 2.19979e-182 ## Top2a 5.81024 14.1787 2.54776 11.6310 3.80015e-65 1.13040e-62 ## Cd200r3 4.83180 15.5613 4.22984 11.3314 9.46221e-24 6.08573e-22 ## Ccnb2 5.97776 13.1393 2.30177 10.8375 3.68706e-69 1.20193e-66 ## ... ... ... ... ... ... ... ## Rpl5-ps2 3.60625 0.612623 6.32853 -5.71590 0.999616 0.999726 ## Gm11942 3.38768 0.798570 6.51473 -5.71616 0.999459 0.999726 ## Gm12816 2.91276 0.838670 6.57364 -5.73497 0.999422 0.999726 ## Gm13623 2.72844 0.708071 6.45448 -5.74641 0.999544 0.999726 ## Rps12l1 3.15420 0.746615 6.59332 -5.84670 0.999522 0.999726 👉 Ajusta la tendencia solo con los spike-ins (que deberían estar afectados solamente por variación técnica) plot(dec.spike.416b$mean, dec.spike.416b$total, xlab = "Mean of log-expression", ylab = "Variance of log-expression" ) fit.spike.416b <- metadata(dec.spike.416b) points(fit.spike.416b$mean, fit.spike.416b$var, col = "red", pch = 16 ) curve(fit.spike.416b$trend(x), col = "dodgerblue", add = TRUE, lwd = 2 ) 4.10 En la ausencia de spike-ins set.seed(0010101) dec.pois.pbmc <- modelGeneVarByPoisson(sce.pbmc) # Ordering by most interesting genes for inspection. dec.pois.pbmc[order(dec.pois.pbmc$bio, decreasing = TRUE), ] ## DataFrame with 33694 rows and 6 columns ## mean total tech bio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## LYZ 1.94129 4.99949 0.625290 4.37420 0 0 ## S100A9 1.92243 4.48842 0.628977 3.85944 0 0 ## S100A8 1.68566 4.35303 0.669965 3.68307 0 0 ## HLA-DRA 2.09063 3.73576 0.594291 3.14146 0 0 ## CD74 2.90080 3.34898 0.418950 2.93003 0 0 ## ... ... ... ... ... ... ... ## COX6A1 0.905824 0.579594 0.633121 -0.0535269 0.883561 0.968946 ## NEDD8 0.842764 0.558542 0.612707 -0.0541655 0.893881 0.978680 ## NDUFA1 0.863339 0.557910 0.619832 -0.0619222 0.920683 1.000000 ## SAP18 0.766806 0.515749 0.582464 -0.0667157 0.946979 1.000000 ## SUMO2 1.362264 0.612538 0.694805 -0.0822664 0.952613 1.000000 👉 Realiza algunas asunciones estadísticas acerca del ruido 🤓 Las cuentas UMI típicamente muestran una variación cercana a Poisson si solo consideramos ruido técnico de la preparación de las librerías y la secuenciación ⚠️ modelGeneVarByPoisson() realiza simulaciones, por lo que necesitamos “ajustar la “semilla” para obtener resultados reproducibles 🤓 modelGeneVarByPoisson() pueden también simular una variación binomial negativa (variación de Poisson sobredispersada) plot(dec.pois.pbmc$mean, dec.pois.pbmc$total, pch = 16, xlab = "Mean of log-expression", ylab = "Variance of log-expression" ) curve(metadata(dec.pois.pbmc)$trend(x), col = "dodgerblue", add = TRUE ) 🤓 La línea de tendencia basada puramente en ruido técnico tiende a producir componentes “biológicos” más grandes por los genes altamente expresados, que frecuentemente incluyen los genes “house-keeping” 🤔 Necesitas considerar si tales genes son “interesantes” o no en tu dataset de interés 4.11 Recordemos propiedades de los datos de sce.416b Este dataset consiste de células de una línea celular de células inmortalizadas mieloides progenitoras de ratón utilizando SmartSeq2 Una cantidad constante de spike-in ERCC RNA se agregó a cada lisado celular antes de la prepatación de la librería Descripción aquí Lun, A. T. L., Calero-Nieto, F. J., Haim-Vilmovsky, L., Göttgens, B. & Marioni, J. C. Assessing the reliability of spike-in normalization for analyses of single-cell RNA sequencing data. Genome Res. 27, 1795–1806 (2017) 4.12 Considerando factores experimentales Los datos que contienen múltiples batches muy seguido presentan efecto de bloque que pueden crear HGVs artificiales Se debe identificar los HGVs en cada batch y combinarlos en una única lista de HGVs # calculando la variacion por bloque dec.block.416b <- modelGeneVarWithSpikes(sce.416b, "ERCC", block = sce.416b$block ) dec.block.416b[order( dec.block.416b$bio, decreasing = TRUE ), ] ## DataFrame with 46604 rows and 7 columns ## mean total tech bio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## Lyz2 6.61235 13.8619 1.58416 12.2777 0.00000e+00 0.00000e+00 ## Ccl9 6.67841 13.2599 1.44553 11.8143 0.00000e+00 0.00000e+00 ## Top2a 5.81275 14.0192 2.74571 11.2734 3.89855e-137 8.43398e-135 ## Cd200r3 4.83305 15.5909 4.31892 11.2719 1.17783e-54 7.00721e-53 ## Ccnb2 5.97999 13.0256 2.46647 10.5591 1.20380e-151 2.98405e-149 ## ... ... ... ... ... ... ... ## Gm12816 2.91299 0.842574 6.67730 -5.83472 0.999989 0.999999 ## Gm5786 2.90717 0.879485 6.71686 -5.83738 0.999994 0.999999 ## Rpl9-ps4 3.26421 0.807057 6.64932 -5.84226 0.999988 0.999999 ## Gm13623 2.72788 0.700296 6.63875 -5.93845 0.999998 0.999999 ## Rps12l1 3.15425 0.750775 6.70033 -5.94955 0.999995 0.999999 ## per.block ## <DataFrame> ## Lyz2 6.35652:13.3748:2.08227:...:6.86819:14.3490:1.08605:... ## Ccl9 6.68726:13.0778:1.65923:...:6.66956:13.4420:1.23184:... ## Top2a 5.34891:17.5972:3.91642:...:6.27659:10.4411:1.57501:... ## Cd200r3 4.60115:15.7870:5.55587:...:5.06496:15.3948:3.08197:... ## Ccnb2 5.56701:15.4150:3.46931:...:6.39298:10.6362:1.46362:... ## ... ... ## Gm12816 2.86995:0.624143:7.43036:...:2.95604:1.061004:5.92424:... ## Gm5786 2.96006:0.902872:7.49911:...:2.85427:0.856098:5.93462:... ## Rpl9-ps4 3.60690:0.543276:7.36805:...:2.92151:1.070839:5.93058:... ## Gm13623 2.83129:0.852901:7.39442:...:2.62447:0.547692:5.88308:... ## Rps12l1 3.14399:0.716670:7.57246:...:3.16452:0.784881:5.82819:... Al calcular tendencias específicas por batch se tomarán en cuenta las diferencias en la relación media-varianza entre batches Se deben obtener estimados de los componentes biológico y técnico para cada gene específicos de cada batch, los cuales se promedian entre los batches para crear una única lista de HVGs 4.13 Seleccionando genes altamante variables (high-variable genes, HVGs) Hasta ahora hemos ordenado los genes del más al menos interesantemente variable ¿Qué tanto debemos de bajar en la lista para seleccionar nuestros HVGs? Para responder esta pregunta debemos tomar en cuenta lo siguiente: elegir un subset más grande: Reduce el riesgo de desechar señal biológica Incrementa el ruido por la inclusión de genes irrelevantes Es difícil determinar el balance óptimo porque el rudio en un contexto podría ser una señal útil en otro contexto Discutiremos algunas estrategias para seleccionar HVGs 4.13.1 Seleccionando HVGs sobre la métrica de varianza La estrategia más simple es seleccionar los top-X genes con los valores más grandes para la métrica relevante de varianza, por ejemplo, la varianza biológica más grande calculada con scran::modelGeneVar() Pro: El usuario puede controlar directamente el número de HVGs Contra: ¿Qué valor de X se debe usar? # Works with modelGeneVar() output hvg.pbmc.var <- getTopHVGs(dec.pbmc, n = 1000) str(hvg.pbmc.var) ## chr [1:1000] "LYZ" "S100A9" "S100A8" "HLA-DRA" "CD74" "CST3" "TYROBP" "IGKC" "CCL5" "S100A4" "HLA-DRB1" "NKG7" ... # Works with modelGeneVarWithSpikes() output hvg.416b.var <- getTopHVGs(dec.spike.416b, n = 1000) str(hvg.416b.var) ## chr [1:1000] "Lyz2" "Ccl9" "Top2a" "Cd200r3" "Ccnb2" "Gm10736" "Hbb-bt" "Mcm5" "Cenpa" "Birc5" "Cd200r4" "Mcm6" ... # Also works with modelGeneCV2() but note `var.field` hvg.pbmc.cv2 <- getTopHVGs(dec.cv2.pbmc, var.field = "ratio", n = 1000 ) str(hvg.pbmc.cv2) ## chr [1:1000] "GNG11" "PTK7" "RNF208" "TUBA8" "ARHGAP6" "PDZK1IP1" "CTB-55O6.8" "NDST2" "GUCY1B3" "MAP1LC3A" "HYI" ... 4.13.1.1 Estrategias para seleccionar X Asume que, por ejemplo, no más del 5% de los genes están diferencialmente expresados entre las células de nuestra población: Establece X como el 5% de los genes Normalmente no conocemos el número de genes diferencialmente expresados desde antes, por lo tanto, solo hemos cambiado un número arbitrario por otro número arbitrario RECOMENDACIÓN: Si decides utilizar los top-X HGVs, elige un valor de X y procede con el resto del análisis con la intención de regresar más adelante y probar otros valores, en vez de dedicarle mucho esfuerzo a encontrar el valor óptimo 4.13.2 Seleccionando HVGs de acuerdo a su significancia estadística Establece un límite fijo en alguna métrica de significancia estadística. Por ejemplo: algunos de los métodos reportan un p-valor para cada gene, entonces selecciona todos los genes con un p-valor ajustado menor que 0.05 Recuerda que las pruebas estadísticas siempre dependen del tamaño de la muestra Ventajas: * Fácil de implementar * Menos predecible que la estrategia de los top-X Desventajas: * Podría priorizar genes con significancia estadística fuerte en vez de significancia biológica fuerte # Works with modelGeneVar() output hvg.pbmc.var.2 <- getTopHVGs(dec.pbmc, fdr.threshold = 0.05) str(hvg.pbmc.var.2) ## chr [1:629] "LYZ" "S100A9" "S100A8" "HLA-DRA" "CD74" "CST3" "TYROBP" "IGKC" "CCL5" "S100A4" "HLA-DRB1" "NKG7" ... # Works with modelGeneVarWithSpikes() output hvg.416b.var.2 <- getTopHVGs(dec.spike.416b, fdr.threshold = 0.05 ) str(hvg.416b.var.2) ## chr [1:2568] "Lyz2" "Ccl9" "Top2a" "Cd200r3" "Ccnb2" "Gm10736" "Hbb-bt" "Mcm5" "Cenpa" "Birc5" "Cd200r4" "Mcm6" ... # Also works with modelGeneCV2() but note `var.field` hvg.pbmc.cv2.2 <- getTopHVGs(dec.cv2.pbmc, var.field = "ratio", fdr.threshold = 0.05 ) str(hvg.pbmc.cv2.2) ## chr [1:1706] "GNG11" "PTK7" "RNF208" "TUBA8" "ARHGAP6" "PDZK1IP1" "CTB-55O6.8" "NDST2" "GUCY1B3" "MAP1LC3A" "HYI" ... 4.13.3 Seleccionando genes por arriba de la tendencia media-varianza Selecciona todos los genes con una varianza biológica positiva Este es un extremo del equilibrio sesgo-varianza que minimiza el sesgo con el costo de maximizar el ruido Si seguimos esta aproximación, estamos: Dándole a la estructura secundaria de la población una oportunidad de manifestarse Capturando más ruido, lo cual puede reducir la resolución de poblaciones bien separadas enmascarando la señal secundaria que intentamos preservar Funciona mejor si tenemos datasets altamente heterogeneos que contienen muchos tipos celulares diferentes # Works with modelGeneVar() output hvg.pbmc.var.3 <- getTopHVGs(dec.pbmc, var.threshold = 0) str(hvg.pbmc.var.3) ## chr [1:12852] "LYZ" "S100A9" "S100A8" "HLA-DRA" "CD74" "CST3" "TYROBP" "IGKC" "CCL5" "S100A4" "HLA-DRB1" "NKG7" ... # Works with modelGeneVarWithSpikes() output hvg.416b.var.3 <- getTopHVGs(dec.spike.416b, var.threshold = 0 ) str(hvg.416b.var.3) ## chr [1:11087] "Lyz2" "Ccl9" "Top2a" "Cd200r3" "Ccnb2" "Gm10736" "Hbb-bt" "Mcm5" "Cenpa" "Birc5" "Cd200r4" "Mcm6" ... # Also works with modelGeneCV2() but note `var.field` and # value of `var.threshold` hvg.pbmc.cv2.3 <- getTopHVGs(dec.cv2.pbmc, var.field = "ratio", var.threshold = 1 ) str(hvg.pbmc.cv2.2) ## chr [1:1706] "GNG11" "PTK7" "RNF208" "TUBA8" "ARHGAP6" "PDZK1IP1" "CTB-55O6.8" "NDST2" "GUCY1B3" "MAP1LC3A" "HYI" ... 4.13.4 EJERCICIO: Dibujando los HVGs Para este ejercicio tendrás que repetir la gráfica que muestra la tendencia de la relación media-varianza (ejeX: media de la expresión, ejeY: varianza de la expresión) incluyendo la línea de tendencia obtenida con alguna de las funciones vistas en la primer parte de la clase (modelGeneVar, modelGeneVarWithSpikes, modelGeneCV2). En esta gráfica, deberás colorear los puntos que corresponden a los HGVs obtenidos con algunos de los enfoques revisados RESPUESTA plot(fit.pbmc$mean, fit.pbmc$var, xlab = "Mean of log-expression", ylab = "Variance of log-expression" ) points(fit.pbmc$mean[hvg.pbmc.var], fit.pbmc$var[hvg.pbmc.var], col = "orange") curve(fit.pbmc$trend(x), col = "dodgerblue", add = TRUE, lwd = 2) 4.13.5 Seleccionando genes de interés a priori Una estrategia contundente es usar sets predefinidos de genes de interés. No hay vergüenza en aprovechar el conocimiento biológivo previo Sin embargo, limita nuestra capacidad de descubrir aspectos nuevos o inesperados de la variación. Por lo tanto, considera esta como una estrategia complementaria a otros tipo de estrategias de selección de HGVs También podrías eliminar listas pre-definidas de genes: Genes de proteínas ribosomales o genes mitocondriales son conocidos por encontrarse dentro de los genes más variables y por interferir con análisis posteriores Sin embargo, tampoco hay que pecar de prevacido, espera a que estos genes demuestren ser problemáticos para removerlos 4.14 Poniendo todo junto # Elegimos el 10% de los genes con con componente biologico de variacion mayor dec.pbmc <- modelGeneVar(sce.pbmc) chosen <- getTopHVGs(dec.pbmc, prop = 0.1) str(chosen) ## chr [1:1285] "LYZ" "S100A9" "S100A8" "HLA-DRA" "CD74" "CST3" "TYROBP" "IGKC" "CCL5" "S100A4" "HLA-DRB1" "NKG7" ... Después de esto tenemos varias opciones para imponer nuestra selección de HGVs durante el resto del análisis: Hacer un subset de SCE para quedarnos únicamente con los HGVs Especificar los HGVs en funciones posteriores Magia (altExps) 4.14.1 Quedándonos sólo con los HGVs sce.pbmc.hvg <- sce.pbmc[chosen, ] sce.pbmc.hvg ## class: SingleCellExperiment ## dim: 1285 3968 ## metadata(1): Samples ## assays(2): counts logcounts ## rownames(1285): LYZ S100A9 ... ZNF770 TMEM106C ## rowData names(2): ID Symbol ## colnames(3968): AAACCTGAGACAGACC-1 AAACCTGAGGCATGGT-1 ... TTTGTCAGTTAAGACA-1 TTTGTCATCCCAAGAT-1 ## colData names(3): Sample Barcode sizeFactor ## reducedDimNames(0): ## mainExpName: NULL ## altExpNames(0): PRO: Te aseguras de que los métodos posteriores sólo usen estos genes para sus cálculos CONTRA: Los genes no-HGVs son eliminados del nuevo objeto SingleCellExperiment, lo cual hace menos conveniente la interrogación del dataset completo sobre genes que no son HGVs 4.14.2 Especificando los HGVs # Example of specifying HVGs in a downstream function # Performing PCA only on the chosen HVGs. library(scater) sce.pbmc <- runPCA(sce.pbmc, subset_row = chosen) sce.pbmc ## class: SingleCellExperiment ## dim: 33694 3968 ## metadata(1): Samples ## assays(2): counts logcounts ## rownames(33694): RP11-34P13.3 FAM138A ... AC213203.1 FAM231B ## rowData names(2): ID Symbol ## colnames(3968): AAACCTGAGACAGACC-1 AAACCTGAGGCATGGT-1 ... TTTGTCAGTTAAGACA-1 TTTGTCATCCCAAGAT-1 ## colData names(3): Sample Barcode sizeFactor ## reducedDimNames(1): PCA ## mainExpName: NULL ## altExpNames(0): Mantiene el objeto SingleCellExperiment original y especifica los genes para usar en funciones posteriores mediante un argumento adicional como subset_row PRO: Es útil si el análisis usa varios conjuntos de HGVs en diferentes pasos CONTRA: Podría ser inconveniente especificar repetidamente el mismo conjunto de HGVs en diferentes pasos 4.14.3 Witchcraft (Brujería) # Add the full SCE to the subsetted data SCE altExp(sce.pbmc.hvg, "original") <- sce.pbmc sce.pbmc.hvg ## class: SingleCellExperiment ## dim: 1285 3968 ## metadata(1): Samples ## assays(2): counts logcounts ## rownames(1285): LYZ S100A9 ... ZNF770 TMEM106C ## rowData names(2): ID Symbol ## colnames(3968): AAACCTGAGACAGACC-1 AAACCTGAGGCATGGT-1 ... TTTGTCAGTTAAGACA-1 TTTGTCATCCCAAGAT-1 ## colData names(3): Sample Barcode sizeFactor ## reducedDimNames(0): ## mainExpName: NULL ## altExpNames(1): original altExp(sce.pbmc.hvg, "original") ## class: SingleCellExperiment ## dim: 33694 3968 ## metadata(1): Samples ## assays(2): counts logcounts ## rownames(33694): RP11-34P13.3 FAM138A ... AC213203.1 FAM231B ## rowData names(2): ID Symbol ## colnames(3968): AAACCTGAGACAGACC-1 AAACCTGAGGCATGGT-1 ... TTTGTCAGTTAAGACA-1 TTTGTCATCCCAAGAT-1 ## colData names(3): Sample Barcode sizeFactor ## reducedDimNames(1): PCA ## mainExpName: NULL ## altExpNames(0): Utilizando el sistema de “experimento alternartivo” en la clase SingleCellExperiment PRO: Evita algunos problemas a largo plazo cuando el dataset original no está sincronizado con el conjunto filtrado por HVGs CONTRA: Ralentiza todos los análisis subsecuentes 4.15 Resumen y recomendaciones Es fácil atorarse en este paso debido a la variedad de opciones disponibles Elige un conjunto de HVGs y continúa con el análisis, recuerda regresar para probar la robustez de tus resultados usando una forma diferente para seleccionar los HVGs Si tienes spike-ins, trata de usarlos. No obstante, recuerda que los spike-ins no pueden capturar todas las fuentes de variación técnica 4.16 Recomendaciones para empezar Para CEL-Seq2: scran::modelGeneVarWithSpikes() Para 10X: scran::modelGeneVarByPoisson() Si quieres irte por el lado de conservar demasiados genes: scran::getTopHVGs(dec, var.threshold=0) Y realiza una comparación rápida con, por lo menos, el top-1000 HVGs Regresa al paso de selección de HVG para eliminar genes problemáticos tantas veces como sea necesario 4.17 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:26:43 EDT" proc.time() ## user system elapsed ## 1068.631 101.742 95052.699 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Zheng, G. X. Y. et al. Massively parallel digital transcriptional profiling of single cells. Nat. Commun. 8, 14049 (2017).↩︎ Lun, A. T. L., Calero-Nieto, F. J., Haim-Vilmovsky, L., Göttgens, B. & Marioni, J. C. Assessing the reliability of spike-in normalization for analyses of single-cell RNA sequencing data. Genome Res. 27, 1795–1806 (2017)).↩︎ "],["reducción-de-dimensiones.html", "5 Reducción de dimensiones 5.1 Diapositivas de Peter Hickey 5.2 Motivación 5.3 Reducción de dimensionalidad 5.4 Dataset ilustrativo: Zeisel 5.5 Dataset ilustrativo: 10x PBMC4k no filtradas 5.6 Análisis de Componentes Principales 5.7 Reducción de dimensionalidad para visualización 5.8 Dónde estamos 5.9 Detalles de la sesión de R", " 5 Reducción de dimensiones Instructora: Laura Gómez-Romero 5.1 Diapositivas de Peter Hickey Contenido adaptado de: aquí 5.2 Motivación El siguiente paso en el análisis de scRNA-seq usualmente consiste en identificar grupos de células “similares”. Por ejemplo: un análisis de clustering busca identificar células con un perfil transcriptómico similar al calcular distancias entre ellas. Si tuviéramos un dataset con dos genes podríamos hacer una gráfica de dos dimensiones para identificar clusters de células. Pero… tenemos decenas de miles de genes : Reducción de dimensionalidad 5.3 Reducción de dimensionalidad Es posible porque la expresión de diferentes genes estaría correlacionada si estos genes son afectados por el mismo proceso biológico. Por lo tanto, no necesitamos almacenar información independiente para genes individuales. Podemos comprimir múltiples “features” (genes) en una única dimensión. Ventajas: Reduce trabajo computacional en análisis posteriores. Reduce el ruido al “promediar” mútiples genes obteniendo una representación más precisa de los patrones en los datos. Permite una graficación efectiva en dos dimensiones. 5.4 Dataset ilustrativo: Zeisel library(scRNAseq) sce.zeisel <- ZeiselBrainData(ensembl = TRUE) # Estos datos contienen tipos celulares previamente anotados table(sce.zeisel$level1class) ## ## astrocytes_ependymal endothelial-mural interneurons microglia oligodendrocytes ## 224 235 290 98 820 ## pyramidal CA1 pyramidal SS ## 939 399 Estudio de tipos celulares en el cerebro de ratón (oligodendrocitos, microglia, neuronas, etc) procesados con el sistema STRT-seq (similar a CEL-Seq) Descripción aquí Zeisel, A. et al. Brain structure. Cell types in the mouse cortex and hippocampus revealed by single-cell RNA-seq. Science 347, 1138-1142 (2015) # Quality control # Descartar celulas con alto contenido mitocondrial o con alto porcentaje de spike-ins library(scater) is.mito <- which(rowData(sce.zeisel)$featureType == "mito") stats <- perCellQCMetrics(sce.zeisel, subsets = list(Mt = is.mito) ) qc <- quickPerCellQC(stats, percent_subsets = c("altexps_ERCC_percent", "subsets_Mt_percent") ) sce.zeisel <- sce.zeisel[, !qc$discard] # normalization # encontramos unos clusters rápidos para las células y usamos esa información para calcular los factores de tamaño library(scran) set.seed(1000) clusters <- quickCluster(sce.zeisel) sce.zeisel <- computeSumFactors(sce.zeisel, cluster = clusters ) sce.zeisel <- logNormCounts(sce.zeisel) # variance-modelling dec.zeisel <- modelGeneVarWithSpikes( sce.zeisel, "ERCC" ) top.zeisel <- getTopHVGs(dec.zeisel, n = 2000) ¿Cómo se está modelando la relación media varianza? ¿Cómo se están obteniendo los HGVs? 5.5 Dataset ilustrativo: 10x PBMC4k no filtradas library(BiocFileCache) bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) library(DropletUtils) library(Matrix) fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) Dataset “Células mononucleares humanas de sangre periférica” de 10X Genomics Descripción aquí Zheng, G. X. Y. et al. Massively parallel digital transcriptional profiling of single cells. Nat. Commun. 8, 14049 (2017) # gene-annotation library(scater) rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) library(EnsDb.Hsapiens.v86) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) # cell-detection set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] # quality-control stats <- perCellQCMetrics(sce.pbmc, subsets = list(Mito = which(location == "MT")) ) high.mito <- isOutlier(stats$subsets_Mito_percent, type = "higher" ) sce.pbmc <- sce.pbmc[, !high.mito] # normalization library(scran) set.seed(1000) clusters <- quickCluster(sce.pbmc) sce.pbmc <- computeSumFactors(sce.pbmc, cluster = clusters) sce.pbmc <- logNormCounts(sce.pbmc) # variance modelling set.seed(1001) dec.pbmc <- modelGeneVarByPoisson(sce.pbmc) top.pbmc <- getTopHVGs(dec.pbmc, prop = 0.1) ¿Cómo se está modelando la relación media varianza? ¿Cómo se están obteniendo los HGVs? 5.6 Análisis de Componentes Principales PCA es el arma principal de la reducción de dimensionalidad. PCA descubre las combinaciones (lineales) de “features” que capturan la cantidad más grande de variación En un PCA, la primer combinación lineal (componente principal) se elige tal que permite capturar la mayor varianza a través de las células. El siguiente PC se elige tal que es “ortogonal” al primero y captura la cantidad más grande de la variación restante, y así sucesivamente… 5.6.1 PCA aplicado a datos de scRNA-seq Podemos realizar reducción de dimensionalidad al aplicar PCA en la matriz de cuentas transformadas (log-counts matrix) y restringiendo los análisis posteriores a los primeros PCs (top PCs). Esto puede reducir nuestro dataset de 20,000 dimensiones a, digamos, 10, sin perder demasiada información. La técnica de PCA tiene muchas propiedades teóricas bien estudiadas. Hay varias formas rápidas de realizar PCA en datasets grandes. 5.6.2 Suposiciones de PCA aplicadas a los datos de scRNA-seq Los procesos biológicos afectan múltiples genes en una manera coordinada. Los primeros PCs probablemente representan la estructura biológica dado que más variación puede ser capturada considerando el comportamiento correlacionado de muchos genes. Se espera que el ruido técnico azaroso afecte cada gen independientemente. Consideración: Los primeros PCs capturarón “batch effects” (efectos de lote) que afectan muchos genes en una manera coordinada ## Aplicar PCA en la matriz de cuentas transformadas (log-counts matrix) library(scran) library(scater) set.seed(100) sce.zeisel <- runPCA(sce.zeisel, subset_row = top.zeisel ) ¿Estamos corriendo el análisis sobre todos los genes de nuestro dataset? Por default, runPCA() usa un método rápido aproximado que realiza simulaciones, por lo tanto, es necesario ‘configurar la semilla’ para obtener resultados reproducibles. 5.6.3 Eligiendo el número de PCs Esta elección en análoga a la elección del número de highly variable genes (HGV). Elegir más PCs evitará descartar señal biológica a expensas de retener más ruido Es común seleccionar un número de PCs “razonable” pero arbitrario (10-50), continuar con el análisis y regresar para checar la robustez de los resultados en cierto rango de valores. Ahora exploraremos algunas estrategias guiadas por los datos (data-driven) para hacer esta selección. 5.6.3.1 Usando el punto del codo library(PCAtools) percent.var <- attr(reducedDim(sce.zeisel), "percentVar") chosen.elbow <- PCAtools::findElbowPoint(percent.var) plot(percent.var, xlab = "PC", ylab = "Variance explained (%)") abline(v = chosen.elbow, col = "red") Una heurística simple es elegir el número de PCs basado en el porcentaje de varianza explicado por PCs sucesivos. 5.6.3.2 Basados en la estructura de la población Esta es una aproximación heurística más sofisticada que usa el número de clusters como un proxy del número de subpoblaciones. choices <- getClusteredPCs(reducedDim(sce.zeisel)) chosen.clusters <- metadata(choices)$chosen plot(choices$n.pcs, choices$n.clusters, xlab = "Number of PCs", ylab = "Number of clusters" ) abline(a = 1, b = 1, col = "red") abline(v = chosen.clusters, col = "grey80", lty = 2) Supongamos que esperamos d subpoblaciones de células, en ese caso, necesitamos d-1 dimensiones para garantizar la separación de todas las subpoblaciones. Pero… en un escenario real realmente no sabes cuántas poblaciones hay… Intenta con un rango para d y únicamente considera valores que produzcan a lo más d+1 clusters Cuando se seleccionan más clusters con menos dimensiones se produce ‘overclustering’. Elige una d que maximice el número de clusters sin caer en ‘overclustering’. Ventaja: Es una solución pragmática que soluciona el equilibrio sesgo-varianza en los análisis posteriores (especialmente en el análisis de clustering). Desventaja: Hace suposiciones fuertes sobre la naturaleza de las diferencias biológicas entre los clusters, y de hecho supone la existencia de clusters, los cuales podrían no existir en algunos procesos biológicos como la diferenciación. 5.6.4 Juntando todo set.seed(100) # Calcula y almacena todos los posibles PCs sce.zeisel <- runPCA(sce.zeisel, subset_row = top.zeisel) # Selecciona y almacena el conjunto reducido de PCs: # ... por el método del codo reducedDim(sce.zeisel, "PCA_elbow") <- reducedDim( sce.zeisel, "PCA" )[, 1:chosen.elbow] # ... basado en la estructura poblacional reducedDim(sce.zeisel, "PCA_clusters") <- reducedDim( sce.zeisel, "PCA" )[, 1:chosen.clusters] 5.6.5 EJERCICIO Realiza un PCA para los datos sce.pbmc. Elige el número de PCs a conservar utilizando el método del codo. Elige el número de PCs a conservar utilizando la estructura de la población. Agrega esta información al objeto sce.pbmc. 5.6.6 Usando el ruido técnico Otra técnica de reducción de dimensiones consiste en conservar todos los PCs hasta que el % de variación explicado alcance algun límite (por ejemplo, basado en la estimación de la variación técnica). denoisePCA() automáticamente selecciona el número de PCs. Por default, denoisePCA() realiza algunas simulaciones, por lo tanto necesitamos ‘configurar la semilla’ para obtener resultados reproducibles. library(scran) set.seed(111001001) denoised.pbmc <- denoisePCA(sce.pbmc, technical = dec.pbmc, subset.row = top.pbmc ) dim(reducedDim(denoised.pbmc, "PCA")) ## [1] 3968 8 La dimensionalidad del output es el límite inferior para el número de PCs requeridos para explicar toda la variación biológica. Lo que significa que cualquier número menor de PCs definitivamente descartará algún aspecto de la señal biológica. Esto no grantiza que los PCs retenidos capturen toda la señal biológica Esta técnica usualmente retiene más PCs que el método del punto del codo scran::denoisePCA() internamente limita el numero de PCs, por default 5-50, para evitar la selección de excesivamente pocos PCs (cuando el ruido técnico es alto relativo al ruido biológico) o excesivamente muchos PCs (cuando el ruido técnico es demasiado bajo). 5.6.6.1 ¿Qué pasa si calculamos la relación media-varianza con la función modelGeneVar para el dataset sce.pbmc (anteriormente usamos la función modelGeneVarByPoisson para este propósito)? dec.pbmc2 <- modelGeneVar(sce.pbmc) denoised.pbmc2 <- denoisePCA(sce.pbmc, technical = dec.pbmc2, subset.row = top.pbmc ) dim(reducedDim(denoised.pbmc2)) ## [1] 3968 5 scran::denoisePCA() tiende a funcionar mejor cuando la relación media-varianza refleja el ruido técnico verdadero, i.e estimado por scran::modelGeneVarByPoisson() o scran::modelGeneVarWithSpikes() en vez de scran::modelGeneVar(). El dataset PBMC está cerca de este límite inferior: el ruido técnico es alto relativo al ruido biológico. 5.6.6.2 ¿Qué pasa si calculamos el número de PCs usando el ruido técnico para el dataset sce.zeisel? set.seed(001001001) denoised.zeisel <- denoisePCA(sce.zeisel, technical = dec.zeisel, subset.row = top.zeisel ) dim(reducedDim(denoised.zeisel)) ## [1] 2815 50 Los datos de cerebro de Zeisel están cerca de este límite superior: el ruido técnico es demasiado bajo dim(reducedDim(denoised.zeisel, "PCA")) ## [1] 2815 50 dim(reducedDim(denoised.zeisel, "PCA_elbow")) ## [1] 2815 7 dim(reducedDim(denoised.zeisel, "PCA_clusters")) ## [1] 2815 15 5.7 Reducción de dimensionalidad para visualización 5.7.1 Motivación Los algoritmos de clustering, así como la mayoría de los algoritmos, operan fácilmente sobre 10-50 (a lo más) PCs, pero ese número es aún demasiado para la visualización. Por lo tanto, necesitamos estrategias adicionales para la reducción de dimensionalidad si queremos visualizar los datos. 5.7.2 Visualizando con PCA plotReducedDim(sce.zeisel, dimred = "PCA") plotReducedDim(sce.zeisel, dimred = "PCA", colour_by = "level1class" ) PCA es una técnica lineal, por lo tanto, no es eficiente para comprimir diferencias en más de 2 dimensiones en los primeros 2 PCs. 5.7.3 Retos y resumen de la visualización con PCA plotReducedDim(sce.zeisel, dimred = "PCA", ncomponents = 4, colour_by = "level1class" ) Ventajas: PCA es predecible y no introducirá estructura artificial en los datos. Es determínistico y robusto a cambios pequeños en los valores de entrada. Desventajas: Usualmente la visualización no es suficiente para visualizar la naturaleza compleja de los datos de scRNA-seq. 5.7.4 Visualización con t-SNE set.seed(00101001101) sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA") plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class") t-stochastic neighbour embedding (t-SNE) es la visualización por excelencia de datos de scRNA-seq. Intenta encontrar una representación (no-lineal) de los datos usando pocas dimensiones que preserve las distancias entre cada punto y sus vecinos en el espacio multi-dimensional 5.7.4.1 Retos de la visualización con t-SNE set.seed(100) sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA", perplexity = 30 ) plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class" ) 5.7.4.2 Preguntas ¿Qué pasa si vuelves a correr runTSNE() sin especificar la semilla? ¿Qué pasa si especificas la semilla pero cambias el valor del parámetro perplexity? 5.7.4.3 Continuando Baja perplejidad favorece la resolución de la estructura fina, posiblemente al grado de que la visualización parece ruido random. set.seed(100) sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA", perplexity = 5) p1 <- plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class") sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA", perplexity = 20) p2 <- plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class") sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA", perplexity = 80) p3 <- plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class") library("patchwork") p1 + p2 + p3 El siguiente foro discute la selección de parámetros para t-SNE con cierta profundidad. No sobreinterpretes los resultados de t-SNE como un ‘mapa’ de las identidades de las células individuales. Algunos componentes aleatorios y la selección de parámetros cambiarán la visualización. La interpretación puede ser engañada por el tamaño y posición de los clusters. t-SNE infla clusters densos y comprime clusters escasos. t-SNE no está obligado a preservar las localizaciones relativas de clusters no-vecinos (no puedes interpretar distancias no locales). Aún así: t-SNE es una herramienta probada para visualización general de datos de scRNA-seq y sigue siendo muy popular 5.7.5 Visualización con UMAP Uniform manifold approximation and project (UMAP) es una alternativa a t-SNE. Así como t-SNE, UMAP intenta encontrar una representación (no lineal) de pocas dimensiones de los datos que preserve las distancias entre cada punto y sus vecinos en el espacio multi-dimensional. t-SNE y UMAP están basados en diferentes teorías matemáticas. set.seed(1100101001) sce.zeisel <- runUMAP(sce.zeisel, dimred = "PCA") plotReducedDim(sce.zeisel, dimred = "UMAP", colour_by = "level1class" ) Comparado con t-SNE: UMAP tiende a encontrar clusters visualmente más compactos. Intenta preservar más de la estructura global que t-SNE. Tiende a ser más rápido que t-SNE, lo cual puede ser importante para datasets grandes. La diferencia desaparece cuando se aplican sobre los primeros PCs. 5.7.5.1 Preguntas ¿Qué pasa si vuelves a correr runUMAP() sin especificar la semilla? ¿Qué pasa si especificas la semilla pero cambias el valor del parámetro n_neighbors? 5.7.5.2 Continuando Igual que para t-SNE, es necesario configurar una semilla y diferentes valores para los parámetros cambiaron la visualización. Si el valor para los parámetros n_neighbors o min_dist es demasiado bajo entonces el ruido aleatorio se interpretará como estructura de alta-resolución, si son demasiado altos entonces se perderá la estructura fina. TIP: Trata un rango de valores para cada parámetro para asegurarte de que no comprometen ninguna de las conclusiones derivadas de la gráfica UMAP o t-SNE 5.7.6 Interpretando las gráficas Recuerda: Reducción de dimensionalidad para la visualización de los datos necesariamente involucra descartar información y distorsionar las distancias entre las células. No sobre interpretes las gráficas bonitas. 5.7.7 Resumen y recomendaciones Las gráficas de t-SNE y UMAP son herramientas diagnóstico importantes, por ejemplo: para checar si dos clusters son realmente subclusters vecinos o si un cluster puede ser dividido en más de un cluster. Es debatible cuál visualización, t-SNE o UMAP, es más útil o estéticamente agradable. Está bien elegir aquella que funcione mejor para tu análisis (tomando en cuenta que tratarás la gráfica únicamente como una herramienta de visualización/diagnóstico y que no llegarás a ninguna conclusión fuerte basado únicamente en la gráfica). 5.8 Dónde estamos 5.9 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:28:51 EDT" proc.time() ## user system elapsed ## 1191.645 104.838 95181.086 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── "],["clustering.html", "6 Clustering 6.1 Dataset ilustrativo: 10X PBMC4k no filtrado 6.2 Motivación 6.3 ¿Por qué no realizamos el clustering sobre las coordenadas de t-SNE/UMAP? 6.4 ¿Cuál es el verdadero clustering? 6.5 Clustering basado en grafos 6.6 Evaluando la separación de los clusters 6.7 Otros métodos de clustering 6.8 Evaluando la estabilidad de los clusters 6.9 Subclustering 6.10 Resumen y recomendaciones 6.11 Dónde estamos 6.12 Detalles de la sesión de R", " 6 Clustering Instructora: Laura Gómez-Romero Este contenido está basado en las diapositivas de Peter Hickey. Ve las diapositivas aquí. Y en el curso de OSCA, lee el material aquí 6.1 Dataset ilustrativo: 10X PBMC4k no filtrado library(BiocFileCache) bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) library(DropletUtils) library(Matrix) fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) Dataset de células mononucleares de sangre periférica humana (PBMC) de 10X Genomics Descripción aquí Zheng, G. X. Y. et al. Massively parallel digital transcriptional profiling of single cells. Nat. Commun. 8, 14049 (2017) # gene-annotation library(scater) rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) library(EnsDb.Hsapiens.v86) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) # cell-detection set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] # quality-control stats <- perCellQCMetrics(sce.pbmc, subsets = list(Mito = which(location == "MT")) ) high.mito <- isOutlier(stats$subsets_Mito_percent, type = "higher" ) sce.pbmc <- sce.pbmc[, !high.mito] # normalization library(scran) set.seed(1000) clusters <- quickCluster(sce.pbmc) sce.pbmc <- computeSumFactors(sce.pbmc, cluster = clusters) sce.pbmc <- logNormCounts(sce.pbmc) # variance modelling set.seed(1001) dec.pbmc <- modelGeneVarByPoisson(sce.pbmc) top.pbmc <- getTopHVGs(dec.pbmc, prop = 0.1) # dimensionality-reduction set.seed(10000) sce.pbmc <- denoisePCA(sce.pbmc, subset.row = top.pbmc, technical = dec.pbmc ) set.seed(100000) sce.pbmc <- runTSNE(sce.pbmc, dimred = "PCA") set.seed(1000000) sce.pbmc <- runUMAP(sce.pbmc, dimred = "PCA") ¿Para qué sirve el método que estamos usando para reducir la dimensionalidad de los datos? ¿Los HGVs están almacenados en nuestro objeto sce.pbmc? 6.2 Motivación Clustering es un procedimiento no supervisado par definir grupos de células con perfiles de expresión similares Su propósito principal es resumir los datos en un formato digerido susceptible a interpretación humana Nos permite asignar etiquetas (por ejemplo, tipos celulares) a las células 6.3 ¿Por qué no realizamos el clustering sobre las coordenadas de t-SNE/UMAP? Las técnicas de t-SNE/UMAP han comprimido datos altamente multi-dimensionales en dos dimensiones Esta compresión inevitablemente ha provocado la perdida de información Por lo tanto, agrupamos sobre los PCs y después visualizamos las identidades de los clusters en la gráfica t-SNE/UMAP 6.4 ¿Cuál es el verdadero clustering? Un cluster no implica un tipo celular Nosotros podemos definir tantos clusters como queramos y podemos utilizar el algoritmo que más nos acomode El clustering, como un microscopio, simplemente es una herramienta para explorar los datos Preguntar por el mejor clustering es similar a preguntar cuál es la mejor magnificación en un microscopio sin contenido 6.5 Clustering basado en grafos 6.5.1 Antecedentes El clustering basado en grafos fue popularizado (más no inventado) por su uso en Seurat Objetivo: Construir un grafo en el que cada nodo es una célula que está conectada a sus vecinos más cercanos (otras células con perfiles de expresión similares) en el espacio multidimensional 6.5.2 Gráfica de los k vecinos más cercanos (k-nearest neighbour -KNN- graph) Ilustremos como funciona para 20 células 6.5.3 Gráfica de los vecinos más próximos compartidos (SNN) De una gráfica KNN se puede construir una gráfica SNN. En este tipo de grafo, dos células estarán conectadas por una arista si comparten alguno de sus vecinos más próximos. 6.5.4 Gráfica SNN con pesos en las aristas Podemos asignar pesos a cada arista del grafo, basándonos en la similaridad de las células involucradas, dándole pesos más altos a células que están más cercanamente relacionadas Para ver los distintos esquemas de pesado puedes consultar la documentación de la función makeSNNGraph del paquete bluster. Algunos ejemplos son: Rango: El peso entre dos nodos está dado por k-r/2 donde r es la suma más pequeña de los rangos (de proximidad, el vecino más cercano tiene el rango 1) para cualquiera de los vecinos compartidos Número: el peso entre dos nodos es igual al número de vecinos más próximos compartidos Jaccard: el peso entre dos nodos es igual a la similaridad de Jaccard entre los conjuntos de vecinos de estos nodos 6.5.5 Obteniendo comunidades a partir de una gráfica SNN pesada mediante un algoritmo de clustering A partir de una gráfica SNN pesada podemos aplicar algoritmos para identificar comunidades de células Una comunidad es un grupo de células que están más conectadas a células en el mismo grupo que lo que están a células de un grupo diferente Cada comunidad representa un cluster 6.5.6 Resumen de clustering basado en grafos La construcción y búsqueda de una red KNN es rápida, por lo tanto, es escalable para datasets grandes Debes evitar obtener conclusiones fuertes acerca de la forma de los clusters o la distribución de células dentro de cada cluster El algoritmo conecta cada célula con un número mínimo de células vecinas lo cual reduce, más no elimina, el riesgo de clusters no informativos Después de la construcción del grafo, no se almacena información adicional más alla de las células vecinas. Esto puede producir subclusters artificiales en regiones con muchas células 6.5.7 Detalles a considerar en la implementación ¿Cuántas céulas vecinas debo considerar durante la construcción del grafo? ¿Cómo debo pesar las aristas? ¿Cuál algoritmo de detección de comunidades se debe usar para definir los clusters? 6.5.8 Implementación library(scran) # Construir grafo usando k= 10 vecinos más cercanos en el espacio definido por el PCA g <- buildSNNGraph(sce.pbmc, k = 10, use.dimred = "PCA") # Identificar comunidades utilizando el método Walktrap clust <- igraph::cluster_walktrap(g)$membership # Visualizar clusters en una gráfica t-SNE library(scater) sce.pbmc$cluster <- factor(clust) plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster") ¿Qué pasa si utilizas una k más grande o más pequeña? library(scran) #Construir grafo usando k= 50 vecinos más cercanos en el espacio definido por el PCA g50 <- buildSNNGraph(sce.pbmc, k = 50, use.dimred = "PCA") # Identificar comunidades utilizando el método Walktrap clust50 <- igraph::cluster_walktrap(g50)$membership # Visualizar clusters en una gráfica t-SNE library(scater) sce.pbmc$cluster50 <- factor(clust50) plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster50") En esta implementación: La construcción de la red KNN se baso en la distancia Euclideana entre células La construcción de la red KNN implica que las aristas se crean entre todos los pares de células que comparten por lo menos un vecino Se utilizó el esquema de peso de: Xu and Su (2015) 6.5.9 Eligiendo un valor de k El valor de k puede ser toscamente interpretado como el tamaño anticipado de la subpoblación más pequeña Si una subpoblación tiene menos que (k+1) células entonces el método será forzado a construir aristas entre células de esa subpoblación y células de otras subpoblaciones, incrementando el riesgo de que la subpoblación en cuestión no forme su propio cluster 6.5.10 Una implementación diferente: estilo Seurat # Pesos definidos estilo Jaccard seguidos por clustering de Louvain # aka 'clustering estilo Seurat' g2 <- buildSNNGraph(sce.pbmc, k = 10, use.dimred = "PCA", type = "jaccard") clust2 <- igraph::cluster_louvain(g2)$membership sce.pbmc$cluster2 <- factor(clust2) plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster2") 6.5.11 Detalles de las implementaciones más comunes Pipelines basados en Seurat: Pesos basados en Jacard Clustering Louvain Pipelines basados en Scran: Pesos basados en Rangos Clustering Walktrap Para detalles sobre la seleccion de parámetros y comparaciones: visitar esta página. library("patchwork") ## Estilo scran vs estilo Seurat plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster") + plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster2") Figure 6.1: Estilo scran vs estilo Seurat. 6.5.12 Otras implementaciones Distintas métricas de distancia g.num <- buildSNNGraph(sce.pbmc, use.dimred = "PCA", type = "number") g.jaccard <- buildSNNGraph(sce.pbmc, use.dimred = "PCA", type = "jaccard") g.none <- buildKNNGraph(sce.pbmc, use.dimred = "PCA") Distintos métodos de clustering clust.louvain <- igraph::cluster_louvain(g)$membership clust.infomap <- igraph::cluster_infomap(g)$membership clust.fast <- igraph::cluster_fast_greedy(g)$membership clust.labprop <- igraph::cluster_label_prop(g)$membership clust.eigen <- igraph::cluster_leading_eigen(g)$membership 6.6 Evaluando la separación de los clusters Modularidad es una métrica natural para evaluar la separación entre comunidades/clusters La modularidad se define como la diferencia (escalada) entre el peso total observado de las aristas entre los nodos en el mismo cluster y el peso total esperado si los pesos fueran distribuidos aleatoriamente entre todos los pares de nodos Nosotros calcularemos un score de modularidad para cada cluster usando las tasas en vez de las diferencias, debido a que las tasas no se ven tan fuertemente influenciadas por el tamaño de los clusters library(bluster) # obteniendo la métrica de modularidad ratio <- pairwiseModularity(g, clust, as.ratio = TRUE) dim(ratio) ## [1] 19 19 library(pheatmap) pheatmap(log2(ratio + 1), cluster_rows = FALSE, cluster_cols = FALSE, color = colorRampPalette(c("white", "blue"))(100) ) Un dataset que contiene clusters bien separados debería contener la mayoría del peso total observado en las entradas diagonales, i.e la mayoría de las aristas ocurren entre células del mismo cluster Para más detalles sobre evaluación de la separación entre clusters visite esta página 6.7 Otros métodos de clustering Clustering por k-means PRO: Rápido Se debe especificar el número de clusters de antemano Favorece clusters esféricos Clustering jerárquico Produce un dendograma (árbol) representando las células y la similaridad entre subpoblaciones a varias resoluciones Demasiado lento para correrse en algo más grande que los datasets más pequeños de scRNA-seq 6.8 Evaluando la estabilidad de los clusters Una propiedad deseable de cualquier cluster es que éste sea estable a las perturbaciones en los datos de entrada, de esta manera: Pequeños cambios en el procesamiento de los datos no cambiarán el resultado Se incrementa la probabilidad de que las conclusiones puedan ser replicadas en un estudio independiente Uno puede hacer un proceso de bootstrap para evaluar la estabilidad de un algoritmo de clustering en un dataset dado y calcular la coasignación. La coasignación es la probabilidad de que células elegidas al azar del cluster X y Y sean asignadas al mismo cluster en la réplica del proceso de bootstrap myClusterFUN <- function(x) { g <- buildSNNGraph(x, use.dimred = "PCA", type = "jaccard") igraph::cluster_louvain(g)$membership } originals <- myClusterFUN(sce.pbmc) set.seed(0010010100) coassign <- bootstrapStability(sce.pbmc, FUN = myClusterFUN, clusters = originals ) pheatmap(coassign, cluster_row = FALSE, cluster_col = FALSE, color = rev(viridis::magma(100)) ) Probabilidad alta de coasignación indica que X es estable con respecto a su separación de Y. Queremos altas probabilidades de coasignación en la diagonal Debes considerar que el bootstraping solo considera el efecto del ruido de muestreo e ignora otros factores que pueden afectar la reproducibilidad (como efectos de batch) Además, una pobre separación puede ser altamente estable 6.9 Subclustering Mejora la resolución al repetir el proceso de feature selection y clustering dentro de un único cluster Se enfoca en los HGVs y PCs que son los más relevantes para un cluster específico Veamos como se comporta la expresión de ciertos genes en nuestros clusters CD3E, CCR7, CD69, y CD44 son marcadores de células T de memoria. g.full <- buildSNNGraph(sce.pbmc, use.dimred = "PCA") clust.full <- igraph::cluster_walktrap(g.full)$membership sce.pbmc$clust.full <- factor(clust.full) plotExpression(sce.pbmc, features = c("CD3E", "CCR7", "CD69", "CD44"), x = "clust.full", colour_by = "clust.full" ) De esta gráfica deducimos que las células T de memoria se encuentran en el cluster 10 Dentro de las células T de memoria, ¿dónde están las subpoblaciones CD4+ y CD8+? # Repetimos TODO el proceso de clustering en el subconjunto de células que hemos identificado como células T de memoria (cluster 10). memory <- 10 sce.memory <- sce.pbmc[, clust.full == memory] dec.memory <- modelGeneVar(sce.memory) sce.memory <- denoisePCA(sce.memory, technical = dec.memory, subset.row = getTopHVGs(dec.memory, prop = 0.1) ) g.memory <- buildSNNGraph(sce.memory, use.dimred = "PCA") clust.memory <- igraph::cluster_walktrap(g.memory)$membership sce.memory$clust.memory <- factor(clust.memory) plotExpression(sce.memory, features = c("CD8A", "CD4"), x = "clust.memory" ) Expresión de CD4 es bajo, por lo tanto, su cambio es modesto, pero la interpretación es clara Si tipos celulares o estados celulares se extienden sobre las fronteras de los clusters, entonces un subcluster podría representar contaminación de un tipo celular en un cluster separado 6.10 Resumen y recomendaciones Un cluster no implica un tipo celular Nosotros podemos definir tantos clusters como queramos y podemos utilizar el algoritmo que más nos acomode El clustering, como un microscopio, simplemente es una herramienta para explorar los datos Preguntar por el mejor clustering es similar a preguntar cuál es la mejor magnificación en un microscopio sin contenido Clustering basado en grafos es rápido y evita tener que hacer suposiciones fuertes sobre la forma de los clusters o la distribución de las células dentro de cada cluster: scran::buildSNNGraph() igraph::cluster_walktrap() o igraph::cluster_louvain() Modularidad y estabilidad de los clusters son diagnósticos útiles El proceso de subclustering podría mejorar la resolución dentro de clusters grandes 6.11 Dónde estamos 6.12 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:30:11 EDT" proc.time() ## user system elapsed ## 1267.839 107.667 95260.648 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── "],["identificación-de-genes-marcadores.html", "7 Identificación de genes marcadores 7.1 Diapositivas de Peter Hickey 7.2 Motivación 7.3 Dataset ilustrativo: PBMC4k 10X sin filtrar 7.4 Motivación - continuación 7.5 Prueba t modificada de Welch pareada 7.6 Ejemplo ilustrativo: CD3E como gen marcador en el dataset PBMC4k 10X 7.7 Aplicación estándar 7.8 Usando el log-fold change 7.9 Encontrando marcadores específicos de clústeres 7.10 Pruebas alternas 7.11 Prueba de rangos de Wilcoxon 7.12 Prueba binomial 7.13 Métodos de expresión diferencial personalizados 7.14 Problemas estadísticos 7.15 Detalles de la sesión de R Patrocinadores", " 7 Identificación de genes marcadores Instructora: Yalbi I. Balderas-Martínez. 7.1 Diapositivas de Peter Hickey Ver las diapositivas originales aquí 7.2 Motivación Ahora que hemos obtenido los clústeres, nos preguntamos, pero qué son? (e.g. ¿qué tipo celular es el clúster 1?) ¿Cuáles genes están dirigiendo el agrupamiento (e.g., ¿cuáles son los genes diferencialmente expresados entre los clústeres 1 y 2?) Idea: Mirar las diferencias en los perfiles de expresión de las células de los diferentes clústeres 7.3 Dataset ilustrativo: PBMC4k 10X sin filtrar # Usemos datos de pbmc4k library(BiocFileCache) bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) library(DropletUtils) library(Matrix) fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) Dataset “Células mononucleares humanas de sangre periférica” de 10X Genomics (Zheng, G.X.Y. et al, 2017) 5 7.3.1 Anotación # Anotación de los genes library(scater) rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) library(EnsDb.Hsapiens.v86) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) # Detección de células set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] 7.3.2 Control de calidad # Control de calidad stats <- perCellQCMetrics(sce.pbmc, subsets=list(Mito=which(location=="MT"))) high.mito <- isOutlier(stats$subsets_Mito_percent, type="higher") sce.pbmc <- sce.pbmc[,!high.mito] 7.3.3 Normalización de los datos library(scran) set.seed(1000) clusters <- quickCluster(sce.pbmc) sce.pbmc <- computeSumFactors(sce.pbmc, cluster=clusters) sce.pbmc <- logNormCounts(sce.pbmc) 7.3.4 Genes variables # Identificación de genes altamente variables set.seed(1001) dec.pbmc <- modelGeneVarByPoisson(sce.pbmc) top.pbmc <- getTopHVGs(dec.pbmc, prop = 0.1) 7.3.5 Reducción de dimensiones # Reducción de dimensiones set.seed(10000) sce.pbmc <- denoisePCA(sce.pbmc, subset.row=top.pbmc, technical=dec.pbmc) set.seed(100000) sce.pbmc <- runTSNE(sce.pbmc, dimred="PCA") set.seed(1000000) sce.pbmc <- runUMAP(sce.pbmc, dimred="PCA") 7.3.6 Clustering # Clustering g <- buildSNNGraph(sce.pbmc, k=10, use.dimred="PCA") clust <- igraph::cluster_walktrap(g)$membership sce.pbmc$cluster <- factor(clust) 7.4 Motivación - continuación ¿Algunos de estos genes están asociados con los resultados de clustering? # El gen 1 está asociado con el clustering? plotExpression(sce.pbmc, features = rownames(sce.pbmc)[1], x = "cluster", colour_by = "cluster" ) # El gen 2 está asociado con el clustering? plotExpression(sce.pbmc, features = rownames(sce.pbmc)[2], x = "cluster", colour_by = "cluster" ) # El gen 252 está asociado con el clustering? plotExpression(sce.pbmc, features = rownames(sce.pbmc)[2512], x = "cluster", colour_by = "cluster" ) # El gen CD3E está asociado con el clustering? plotExpression(sce.pbmc, features = "CD3E", x = "cluster", colour_by = "cluster" ) Ver una gráfica como una forma de encontrar los genes marcadores obviamente no nos sirve a gran escala Necesitamos un método estadístico para identificar estos genes marcadores 👉 La prueba t de Welch es una opción obvia para probar las diferencias en la expresión entre clústeres 7.5 Prueba t modificada de Welch pareada ➕ Rápidas y buenas propiedades estadísticas para un gran número de células (Soneson and Robinson, 2018) 6 ➕ Las comparaciones pareadas proveen un log-fold change para indicar cuáles clústeres son distinguidos por cada gen 🤔 ¿Por qué no comparar cada clúster con el promedio de todas las otras células? Sensible a la composición poblacional, una subpoblación dominante sola que dirige la selección de los marcadores top para cualquier otro clúster 7.6 Ejemplo ilustrativo: CD3E como gen marcador en el dataset PBMC4k 10X 7.6.1 Pruebas pareadas comparison logFC Pval 1 vs 2 1.50 1.7e-198 1 vs 3 -0.08 0.11 … … … 2 vs 1 1.39 1.7e-198 … … … 18 vs 17 0.11 0.46 K = 18 clústeres K!/K-2)! = 306 comparaciones * La mitad de ellas son redundantes 7.6.2 Combinando comparaciones del gen CD3E para el clúster 1 “Me interesa saber si el gen CD3 está diferencialmente expresado entre el clúster 1 y ..” cualquier (any) otro clúster = P = 1.3 x 10-205 (Simes adjusted P-value) todos (all) los otros clústeres = P = 0.11 (Berger’s intersection-union test) algunos (some) de los otros clústeres = P = 2.0 x 10-44 (mediana u otro cuantil, Holm-adjusted P-values) 7.6.3 Extendiendo a todos los genes # scran::pairwiseTTests() # scran::combineMarkers() M = 33,694 genes 🤓 K x M = 10,310,364 pruebas Comparaciones involucrando clúster 1… Comparaciones involucrando clúster … Comparaciones involucrando clúster 18 7.7 Aplicación estándar Para cada clúster, usar pruebas t de Welch para identificar los genes que están diferencialmente expresados entre éste y cualquier (any) otro clúster # scran::findMarkers() library(scran) markers.pbmc <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="t", pval.type="any") 7.7.1 Explorando los resultados chosen <- "9" interesting <- markers.pbmc[[chosen]] plotExpression(sce.pbmc, rownames(interesting)[1:4], x="cluster", colour_by="cluster") 7.7.2 Con un heatmap best.set <- interesting[interesting$Top <= 6,] logFCs <- as.matrix(best.set[,-(1:3)]) colnames(logFCs) <- sub("logFC.", "", colnames(logFCs)) library(pheatmap) pheatmap(logFCs, breaks=seq(-5, 5, length.out=101)) 👉 Usamos el campo Top para identificar un conjunto de genes que distinguen al clúster 9 de cualquier otro clúster. El conjunto de genes con Top <= X es la unión del top X genes (ordenados por p-value) de cada comparación de pares que involucran al cluster 9. Por ejemplo, el conjunto de todos los genes con valores Top 1 contienen el gen con el p-value mas pequeño de cada comparación. El conjunto de genes Top valor menor o igual a 10 contiene los 10 genes top de cada comparación. Se consolida en un ranking para cada clúster. 7.8 Usando el log-fold change 7.8.1 Sin especificar el lfc Para cada clúster, usa pruebas t de Welch para identificar los genes que están sobreexpresados entre éste y cualquier otro clúster # set direction = "up" to only consider upregulated genes as potential markers markers.pbmc.up <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="t", direction="up", pval.type="any") interesting.up <- markers.pbmc.up[[chosen]] 7.8.2 Usando el lfc Para cada clúster, usa pruebas t de Welch para identificar los genes que están sobreexpresados con un log-fold change (lfc) o al menos 1 entre éste y cualquier otro clúster markers.pbmc.up2 <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="t", direction="up", lfc=1, pval.type="any") interesting.up2 <- markers.pbmc.up2[[chosen]] 👉 La prueba t también nos permite especificar un log-fold change diferente de cero como la hipótesis nula 🤓 Es más riguroso que simplemente filtrar por log-fold change (TREAT) 7 7.8.3 Heatmap best.set <- interesting.up2[interesting.up2$Top <= 5,] logFCs <- as.matrix(best.set[,-(1:3)]) colnames(logFCs) <- sub("logFC.", "", colnames(logFCs)) pheatmap(logFCs, breaks=seq(-5, 5, length.out=101)) 👉 Los promedios están más centrados en un conjunto de genes marcadores candidatos que están sobreexpresados en el clúster 9 ⚠️ El incremento del rigor no se da sin costo ⚠️ Si el lfc es muy grande podría descartar genes útiles E.g., un gen sobreexpresado en una proporción pequeña de células en un clúster sigue siendo un marcador efectivo si el foco está en la especificidad más que en la sensibilidad 7.9 Encontrando marcadores específicos de clústeres 👉 Por defecto, scran::findMarkers() dará un alto rango a genes que están DE en cualquier comparación pareada 🤔 Quiero genes que son específicos de cada clúster 👉 Tú quieres genes que son DE en todas las comparaciones pareadas Para cada clúster, usa pruebas t de Welch para identificar genes que están sobreexpresados entre éste y todos los otros clústeres Considera todos los genes que están diferencialmente expresados en todas las comparaciones pareadas incluyendo al clúster de interés markers.pbmc.up3 <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, direction="up", pval.type="all") interesting.up3 <- markers.pbmc.up3[[chosen]] 🤓 Usa una prueba de unión-intersección para combinar los P-values que es el máximo P-value de todas las comparaciones pareadas. Un gen solo logrará un bajo nivel de P-value combinado si está fuertemente DE en todas las comparaciones - cuando funciona es muy efectivo - te da un pequeño conjunto de marcadores candidatos. Un gen que esté al mismo nivel que los demás clústeres no será detectado. No nos serviría para diferenciar en las poblaciones CD4 CD8. 7.9.1 Pros/cons de los genes marcadores específicos de los clústeres Poblacion Expresion_CD4 Expresion_CD8 DN(CD4-/CD8-) No No CD4+> Si No CD8+> No Si DP(CD4+/CD8+) Si Si 7.9.2 findMarkers con pval.type some Para cada clúster, usa pruebas t de Welch para identificar los genes que están sobreexpresados entre éste y algunos de los otros clústers. markers.pbmc.up4 <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, direction="up", pval.type="some") interesting.up4 <- markers.pbmc.up4[[chosen]] 👉 Si pval.type=\"all\" es muy estricto, entonces pval.type=\"any\" es muy generoso 🤓 Podemos entonces usar some. Aplica la corrección Holm-Bonferroni a los P-values y toma el mejor valor de en medio como el P-value combinado Prueba la hipótesis nula de que al menos 50% de las comparaciones pareadas no tienen DE Se aplica un rango para obtener el conjunto de los mejores marcadores ⚠️ Perderás algunas garantías ofrecidas por los otros métodos 7.10 Pruebas alternas 7.10.1 Motivación La prueba t no es la única forma de comparar dos grupos de mediciones 🤔 Quiero una prueba que pueda ser usada perfectamente para distinguir dos clústeres uno del otro 👉 Prueba de rangos Wilcoxon 🤔 Quiero identificar genes que son expresados más frecuentemente en un clúster que en otro 👉 Prueba Binomial 7.11 Prueba de rangos de Wilcoxon Evalúa directamente la separación entre la distribución de la expresión de los diferentes clústeres 🤓 Es proporcional al área bajo la curva (AUC), que es la probabilidad de que una célula al azar de un clúster tenga mayor que expresión que una célula al azar de otro clúster 👉 AUCs de 1 o 0 indican que los dos clústeres tienen distribuciones de expresión separadas 🤓 También se conoce como prueba Wilcoxon-Mann-Whitney (WMW) 7.11.1 findMarkers para Wilcoxon Para cada clúster, usa la prueba de rangos de Wilcoxon para identificar genes que están sobreexpresados entre éste y cualquier otro clúster markers.pbmc.wmw <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="wilcox", direction="up", pval.type="any") interesting.wmw <- markers.pbmc.wmw[[chosen]] 7.11.2 Heatmap de genes marcadores con Wilcoxon best.set <- interesting.wmw[interesting.wmw$Top <= 5,] AUCs <- as.matrix(best.set[,-(1:3)]) colnames(AUCs) <- sub("AUC.", "", colnames(AUCs)) pheatmap(AUCs, breaks=seq(0, 1, length.out=21), color=viridis::viridis(21)) 7.11.3 Resumen de la prueba de rangos de Wilcoxon ➕ Ofrece directamente la propiedad deseable de un gen marcador (i.e. que el gen distinga perfectamente entre dos clústeres) ➕ Es simétrico con respecto a las diferencias en el tamaño de los grupos comparados ➖ Es mucho más lento comparado con la prueba t (aunque esto en general no es un problema en la práctica) 7.12 Prueba binomial Es una prueba que identifica los genes que difieren en la proporción de células que se expresan entre clústeres Una definición mucho más estricta de genes marcadores 🤓 Convierte la expresión en una medida binaria de presencia/ausencia, por lo que toda la información cuantitativa es ignorada Desde una perspectiva práctica, puede ser más fácil para validar 7.12.1 findMarkers para binomial Para cada clúster, usa la prueba Binomial para identificar genes que están más frecuentemente expresados (sobreexpresados) en comparación con cualquier otro clúster markers.pbmc.binom <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="binom", direction="up", pval.type="any") interesting.binom <- markers.pbmc.binom[[chosen]] 🤓 El efecto en el tamaño se reporta como el log-fold change en la proporción de las células que se expresan entre clústeres 👉 Log-fold changes grandes positivos, indican que el gen está más frecuentemente expresado en un clúster comparado con otro 7.12.2 Visualizando genes marcadores de la prueba binomial top.genes <- head(rownames(interesting.binom)) plotExpression(sce.pbmc, x="cluster", features=top.genes) 7.12.3 Resumen de la prueba binomial La prueba Binomial no toma en cuenta la normalización ➕ Produce genes marcadores que pueden ser más fáciles de validar ➖ Ser más estricto puede llevar a la pérdida de buenos marcadores candidatos 7.13 Métodos de expresión diferencial personalizados 🤔 ¿Por qué no usar edgeR/DESeq2/limma-voom u otros métodos personalizados (e.g., MAST)? 👉 Claro que puedes! Checa OSCA 👉 Pero éstos son tal vez algo exagerados para identificar genes marcadores 🤓 Las células son nuestras “réplicas” para el propósito de identificar genes marcadores 🤓 edgeR/DESeq2/limma-voom hacen asunciones más fuertes acerca de los datos que es más probable que no se cumplan para células individuales en scRNA-seq 7.14 Problemas estadísticos 7.14.1 Invalidez de P-values Todas las estrategias de DE para detectar genes marcadores entre clústeres son estadísticamente defectuosas de alguna manera 🤓 “Dragado de datos”: El análisis DE se realiza usando los mismos datos usados para obtener los clústeres 👉 Las pruebas para genes DE entre clústeres producirá inevitablemente algunos resultados significativos y así es como los clústeres serán definidos! 👉 Aún cuando los P-values son defectuosos, el efecto no es muy dañino para la detección de genes ya que los P-values solo son usados para los rangos 🤓 No se pueden usar P-values para definir “diferencias significativas” entre los clústeres con respecto a un umbral de la tasa de error 7.14.2 Naturaleza de la replicación 👉 Idealmente, validar algunos de los marcadores con una población de células independientes (y idealmente usando una técnica diferente, e.g., hibridación fluorescente in situ o qPCR) 7.14.3 Comentarios adicionales 👉 La estrategia de análisis DE es que los marcadores son definidos relativo a subpoblaciones en el mismo dataset 👉 Si un gen se expresa uniformemente a través de la población no servirá como un marcador e.g., los marcadores de las células T no serán detectados si solamente hay células T en los datos usualmente no es un problema, ya que tenemos idea de las células que se capturaron 👉 Existen métodos de machine learning para hacer la identificación de los genes marcadores, pero la humilde prueba t sigue siendo muy buena 7.14.4 Resumen y recomendaciones 👉 Crea múltiples listas de genes marcadores con diferentes niveles de rigor 👉 La forma más simple de interpretar los genes marcadores es que son los sobreexpresados de “forma única”, o son “genes específicos de clústeres”, especialmente si queremos imponer un log-fold change mínimo 👉 Puedes requerir hacer una identificación de genes marcadores más enfocada, e.g., subset de los datos de solo 2 clústeres de interés y entonces correr scran::findMarkers() 7.15 Detalles de la sesión de R options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-06 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Patrocinadores La presentación fue hecha con el paquete de R xaringan y configurada con xaringanthemer. Este curso está basado en el libro Orchestrating Single Cell Analysis with Bioconductor de Aaron Lun, Robert Amezquita, Stephanie Hicks y Raphael Gottardo, además del curso de scRNA-seq para WEHI creado por Peter Hickey. Puedes encontrar los archivos para este taller en comunidadbioinfo/cdsb2023. Descarga los materiales con usethis::use_course('comunidadbioinfo/cdsb2023') o revísalos en línea vía comunidadbioinfo.github.io/cdsb2023. Zheng, G. X. Y. et al. Massively parallel digital transcriptional profiling of single cells. Nat. Commun. 8, 14049 (2017).↩︎ Soneson C, Robinson MD. Bias, robustness and scalability in single-cell differential expression analysis. Nat Methods. 2018 Apr;15(4):255-261. doi: 10.1038/nmeth.4612. Epub 2018 Feb 26. PMID: 29481549.↩︎ McCarthy DJ, Smyth GK. Testing significance relative to a fold-change threshold is a TREAT. Bioinformatics. 2009 Mar 15;25(6):765-71. doi: 10.1093/bioinformatics/btp053. Epub 2009 Jan 28. PMID: 19176553; PMCID: PMC2654802.↩︎ "],["anotación-de-tipos-celulares.html", "8 Anotación de tipos celulares 8.1 Diapositivas 8.2 Introducción 8.3 Motivación 8.4 Aproximaciones para anotar 8.5 Paqueterías de R más “famosas” para anotar 8.6 Paqueterías de R con conjuntos de datos de referencia 8.7 Preparación del dataset", " 8 Anotación de tipos celulares Erick Cuevas 08 de agosto de 2023 8.1 Diapositivas div.color { border-radius: 5px; padding: 20px; margin: 30px 0px 30px;} div.red { background-color:#f67155; } div.orange{ background-color:#f0BB51;} div.pair { display: flex; flex-direction: row; justify-content: center; text-align:center; padding:0px} div.inside { width: 49%; padding: 0px} div.scroll { max-height: 400px; overflow-y: auto; background: #111111; border-radius:5px; padding: 10px; margin: 30px 0px 30px; color: #999999;} div.alert{color:#bd475d; background-color:transparent} 8.2 Introducción El análisis de secuenciación de ARN a nivel de célula única (scRNAseq) ha revolucionado nuestra capacidad para estudiar la heterogeneidad celular en diversos tejidos y condiciones. A diferencia de la secuenciación de ARN tradicional, que proporciona información promedio de todas las células en una muestra, el scRNAseq permite el estudio detallado de la expresión génica en células individuales. Esto ha abierto puertas a descubrimientos sin precedentes en biología celular, permitiendo identificar nuevos tipos celulares, estados transicionales y vías de señalización específicas de células. Dentro de este contexto, la anotación de clusters en scRNAseq es esencial. Una vez que se han identificado grupos o “clusters” de células con perfiles de expresión similares, es crucial determinar qué representan estas agrupaciones en términos biológicos. Es aquí donde entra en juego la anotación. 8.3 Motivación Identificación de Tipos y Subtipos Celulares: La principal motivación para anotar clusters es identificar y etiquetar tipos y subtipos celulares específicos dentro de una muestra. Esto es fundamental para entender la composición celular de un tejido y cómo esta composición puede cambiar en diferentes condiciones, como en enfermedades. Entender la Función Celular: Al anotar clusters, no solo identificamos qué tipo de célula es, sino que también podemos inferir su función actual basándonos en su perfil de expresión génica. Descubrimiento de Nuevos Tipos Celulares: En algunos casos, la anotación puede revelar grupos de células que no se ajustan a tipos celulares conocidos, lo que indica la posible existencia de un tipo celular previamente no descrito. Base para Análisis Posteriores: Una vez que se han anotado los clusters, se pueden realizar análisis más detallados, como estudios de vías de señalización, análisis de reguladores maestros o estudios de interacción celular. Comparación Entre Muestras y Condiciones: La anotación permite comparar la composición celular entre diferentes muestras, tejidos o condiciones, lo que es esencial para estudios comparativos y de enfermedades. 8.4 Aproximaciones para anotar Modo artístico. Usando conocimiento previo de genes marcadores ya publicados. Usando referencias de conjuntos de datos ya anotados. Combinando el modo artístico con referencias. Anclas con Seurat. 8.5 Paqueterías de R más “famosas” para anotar SingleR Seurat scCATCH cellassign SCINA Garnett 8.6 Paqueterías de R con conjuntos de datos de referencia SeuratData celldex scRNAseq Otros sitios interesantes para obtener conjuntos de datos de referencia: Azimuth Single Cell Expression Atlas GLIASEQ 8.7 Preparación del dataset El dataset tiene el ID en GEO GSE159677 OJO PARA FINES DEL TIEMPO DEL CURSO POR AHORA NO GENERAREMOS este dataset desde cero, este proceso realízalo cuando tengas memoria ram libre y no utilices tu equipo para otra cosa library(cowplot) library(ggplot2) library(scater) library(scds) library(SingleCellExperiment) #Carga de datos y re formato #Carga de las cuentas crudas #Recuerda cambiar el PATH o directorio a la ubicación de los datos fastq_dirs <- list.dirs("../datos_atherosclerosis/tom_alsaigh_2022/", recursive = FALSE, full.names = TRUE) names(fastq_dirs) <- basename(fastq_dirs) sce <- DropletUtils::read10xCounts(fastq_dirs) #Renombrar row/colData nombre de columnas y SCE dimnames names(rowData(sce)) <- c("ENSEMBL", "SYMBOL") names(colData(sce)) <- c("sample_id", "barcode") sce$sample_id <- factor(basename(sce$sample_id)) dimnames(sce) <- list( with(rowData(sce), paste(SYMBOL, sep = ".")), with(colData(sce), paste(barcode, sample_id, sep = "."))) # Agregamos la metadata md <- data.frame( Sample_ID = c("Patient1_AC", "Patient1_PA", "Patient2_AC", "Patient2_PA", "Patient3_AC", "Patient3_PA"), Age = c(82, 82, 87, 87, 65, 65), AHA_Classification = c("Type_VII_Calcified", "Type_VII_Calcified", "Type_VII_Calcified", "Type_VII_Calcified", "Type_VII_Calcified", "Type_VII_Calcified"), Region = c("Atherosclerotic_Core", "Proximal_Adjacent", "Atherosclerotic_Core", "Proximal_Adjacent", "Atherosclerotic_Core", "Proximal_Adjacent") ) m <- match(sce$sample_id, md$Sample_ID) sce$region <- md$Region[m] sce$AHA_Classification <- md$AHA_Classification[m] sce$sample_id <- md$Sample_ID[m] sce$Age <- md$Age[m] Hacemos ahora un pequeño proceso de limpieza y normalización #Remover genes no detectados sce <- sce[Matrix::rowSums(counts(sce) > 0) > 0, ] dim(sce) #Remover doublets #dividir SCE por muestra OJO esto podria ser por lotes cs_by_s <- split(colnames(sce), sce$sample_id) sce_by_s_2 <- lapply(cs_by_s, function(cs) sce[, cs]) #correr 'scds' sce_by_s_2 <- lapply(sce_by_s_2, function(u) scds::cxds_bcds_hybrid(scds::bcds(scds::cxds(u)))) #Eliminando doublets sce_by_s <- lapply(sce_by_s_2, function(u) { #Calcula numero de doublets (10x) n_dbl <- ceiling(0.01 * ncol(u)^2 / 1e3) #Elimina 'n_dbl' celulas con mayor scpre de doublet o <- order(u$hybrid_score, decreasing = TRUE) u[, -o[seq_len(n_dbl)]] }) #Integrar nuevamente al objeto SCE sce <- do.call(cbind, sce_by_s) #Calcular metricas QC (mito <- grep("MT-", rownames(sce), value = TRUE)) # sce <- perCellQCMetrics(sce, subsets = list(Mito=mito)) sce <- addPerCellQCMetrics(sce, subsets = list(Mito=mito)) sce <- addPerFeatureQCMetrics(sce) Filtración de células #Obtener outliers cols <- c("total", "detected", "subsets_Mito_percent") log <- c(TRUE, TRUE, FALSE) type <- c("both", "both", "higher") # Con esto decidimos que barcode desechar drop_cols <- paste0(cols, "_drop") for (i in seq_along(cols)){ colData(sce)[[drop_cols[i]]] <- isOutlier(sce[[cols[i]]], nmads = 2.5, type = type[i], log = log[i], batch = sce$sample_id) } # Muestra un resumen de los barcodes que se eliminaran sapply(drop_cols, function(i) sapply(drop_cols, function(j) sum(sce[[i]] & sce[[j]]))) cd <- data.frame(colData(sce)) ps <- lapply(seq_along(cols), function (i) { p <- ggplot(cd, aes_string(x = cols[i], alpha = drop_cols[i])) + geom_histogram(bins = 100, show.legend = FALSE) + scale_alpha_manual(values = c("FALSE" = 1, "TRUE" = 0.4)) + facet_wrap(~sample_id, ncol = 1, scales = "free") + theme_classic() + theme(strip.background = element_blank()) if (log[i]) p <- p + scale_x_log10() return(p) }) plot_grid(plotlist = ps, ncol = 3) layout(matrix(1:2, nrow = 1)) ol <- Matrix::rowSums(as.matrix(colData(sce)[drop_cols])) != 0 x <- sce$total y <- sce$detected LSD::heatscatter(x, y, log="xy", main = "unfiltered", xlab = "Total counts", ylab = "Non-zero features") LSD::heatscatter(x[!ol], y[!ol], log="xy", main = "filtered", xlab = "Total counts", ylab = "Non-zero features") #Generar resumen de celulas a mantener ns <- table(sce$sample_id) ns_fil <- table(sce$sample_id[!ol]) print(rbind( unfiltered = ns, filtered = ns_fil, "%" = ns_fil / ns * 100)) #Eliminar celulas outlier sce <- sce[, !ol] dim(sce) #count > 1 sce <- sce[Matrix::rowSums(counts(sce) > 1) >= 20, ] dim(sce) Agrupamiento, toma en cuenta que esta parte podría demorar bastante. #Load packages library(cowplot) library(Seurat) library(SingleCellExperiment) library(ggplot2) #INTEGRATE #Crear SeuratObject so <- CreateSeuratObject( counts = counts(sce), meta.data = data.frame(colData(sce)), project = "Alsaigh_10x_data") #Dividir por muestra cells_by_sample <- split(colnames(sce), sce$sample_id) so <- lapply(cells_by_sample, function(i) subset(so, cells = i)) #Normalizar, encontrar genes variables, escalar so <- lapply(so, NormalizeData, verbose = FALSE) so <- lapply(so, FindVariableFeatures, nfeatures = 2e3, selection.method = "vst", do.plot = FALSE, verbose = FALSE) so <- lapply(so, ScaleData, verbose = FALSE) #Encontrar anclas # Estas anclas nos ayudaran despues para integrar todo con la funcion IntegrateData. as <- FindIntegrationAnchors(so, verbose = TRUE) so <- IntegrateData(anchorset = as, dims = seq_len(30), verbose = TRUE) #Escalar datos integrados DefaultAssay(so) <- "integrated" so <- ScaleData(so, display.progress = FALSE) #Reducción de dimension so <- RunPCA(so, npcs = 100, verbose = FALSE) #Cambiar numbero de PCs usedos so <- RunTSNE(so, reduction = "pca", dims = seq_len(20), seed.use = 1, do.fast = TRUE, verbose = FALSE) so <- RunUMAP(so, reduction = "pca", dims = seq_len(20), seed.use = 1, verbose = FALSE) #CLUSTERING so <- FindNeighbors(so, reduction = "pca", dims = seq_len(20), verbose = FALSE) for (res in c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1)){ so <- FindClusters(so, resolution = res, random.seed = 1, verbose = FALSE) } Para los ejercicios de la presentación descarga los siguientes archivos https://drive.google.com/file/d/1HbJ0syxTcxkI1aG6dIQ6hkJ7SrLHCLfl/view?usp=drive_link https://drive.google.com/file/d/1gJ2raTr8BhLsjeW3n1sdKko0qLYE2g5n/view?usp=drive_link "],["nuevas-funcionalidades-de-rstudio-quarto..html", "9 Nuevas funcionalidades de RStudio, Quarto. 9.1 Diapositivas", " 9 Nuevas funcionalidades de RStudio, Quarto. Erick Cuevas 09 de agosto de 2023 9.1 Diapositivas "],["control-de-versiones-con-github-y-rstudio.html", "10 Control de versiones con GitHub y RStudio 10.1 Diapositivas 10.2 ¿Por qué hacer control de versiones de nuestros proyectos? 10.3 Git 10.4 Recomendaciones para sus proyectos 10.5 Proyectos colaborativos 10.6 GitHub 10.7 Manual de sobreviviencia con Git Y GitHub en RStudio (en caso de ser necesario) 10.8 Cómo clonar un repositorio y tener conección/permisos para modificarlo? 10.9 Credenciales HTTPS en Cache 10.10 Conectando RStudio con Git y Github. 10.11 GitHub primero, RStudio después… 10.12 Rmarkdown en GitHub 10.13 RStudio primero y GitHub también 10.14 Proyecto existente, GitHub al final 10.15 Git basics: commands 10.16 Merge conflics 10.17 Merge conflics 10.18 En resumen", " 10 Control de versiones con GitHub y RStudio Dra. Alejandra Medina Rivera 09 de agosto de 2023 div.color { border-radius: 5px; padding: 20px; margin: 30px 0px 30px;} div.red { background-color:#f67155; } div.orange{ background-color:#f0BB51;} div.pair { display: flex; flex-direction: row; justify-content: center; text-align:center; padding:0px} div.inside { width: 49%; padding: 0px} div.scroll { max-height: 400px; overflow-y: auto; background: #111111; border-radius:5px; padding: 10px; margin: 30px 0px 30px; color: #999999;} div.alert{color:#bd475d; background-color:transparent} Este documento se basa en “Happy Git with R” de Jenny Bryan, los STAT 545 TAs, Jim Hester https://happygitwithr.com 10.1 Diapositivas 10.2 ¿Por qué hacer control de versiones de nuestros proyectos? ✅ Los proyectos suelen cambiar y crecer. 💾 Es díficil saber cuáles fueron todos los cambios a lo largo del tiempo (en especial tiempos largos, hazlo por tu yo del futuro!). 🤔 Las colaboraciones se pueden complicar sin un buen control de versiones. 🔐 Seguridad. 10.3 Git Git es un sistema de control de versiones Git funciona con GitHub, Bitbucket o GitLab ¿Por qué usar Git en vez de solo renombrar los archivos? ✅✅Por qué es mejor tener una filogenia del archivo. Git es un sistema de control de versiones distribuido, gratuito y de código abierto, diseñado para manejar todo tipo de proyectos, desde los más pequeños hasta los más grandes, con rapidez y eficiencia. Git es fácil de aprender y ocupa poco espacio con un rendimiento rapidísimo. Supera a las herramientas SCM como Subversion, CVS, Perforce y ClearCase con características como la ramificación local barata, las cómodas áreas de preparación y los múltiples flujos de trabajo. 10.3.1 Git vs controles de versión a mano Con Git cada contribuidor tiene una copia del repositorio central, con todos los archivos y la historia de los cambios por los que han pasado. Excuse me, do you have a moment to talk about version control?, Jennifer Bryan, 2017 ⚠️ NO OLVIDES TENER INSTALADO Git, en caso de que aún no lo hayas instalado, lo puedes descargar en el siguiente enlace https://git-scm.com/downloads. Para conocer la localización y la versión de Git que tienes en tu computadora, corre el siguiente comando en la terminal: which git y git --version 10.4 Recomendaciones para sus proyectos Dedicar un directorio Es mejor organizarlo en un RStudio Project Hacer un repositorio de Git Trabajen como siempre, solo además de guardar, recuerden hacer commit De vez en vez hagan push de sus cambios cuando los hayan verificado. 10.5 Proyectos colaborativos GitHub se parece más a un GoogleDoc que a un Word Document. Es fácil que los colaboradores hagan cambios y también es fácil saber quién hizo que. El owner del proyecto puede dar permisos a los diferentes colaboradores. También existen organizaciones, esto puede ser útil para manejar los permisos de grupos grandes de colaboración. 10.6 GitHub GitHub es una plataforma para guardar proyectos, hace uso de Git. Su principal utilidad es para generar código fuente de programas. ⚠️ NO OLVIDES TENER UNA CUENTA EN GITHUB, en caso de que aún no lo hayas hecho, puedes ir la página de GitHub y seleccionar join. Es indispensable tu usuario para los ejercicios que siguen. También existen otras plataformas como Bitbucked y GitLab, las cuales funcionan de manera similar a GitHub. 10.7 Manual de sobreviviencia con Git Y GitHub en RStudio (en caso de ser necesario) Por cualquier problema con la conexión entre RStudio y Git, siempre ten en cuenta la ubicación de dónde se instaló Git. Puedes usar en la terminal which git (Mac y Linux) O bien usar en la terminal where git (Windows) Recuerda que la terminal (o línea de comandos ó consola ó shell ó bash) es un programa en tu computadora que funciona para correr otros programas. Desde RStudio puedes abrir la terminal, lo cual es muy conveniente si estás trabajando en un proyecto. Puedes abrir una terminal con: Tools > Terminal (abre la terminal dentro del IDE de RStudio) Tools > Shell (abre una terminal externa a RStudio) 10.8 Cómo clonar un repositorio y tener conección/permisos para modificarlo? Git puede comunicarse con un servidor remoto usando uno de dos protocolos, HTTPS o SSH, y cada protocolo usa credenciales diferentes. La recomendación actual de GitHub es usar HTTPS porque es la manera más fácil de configurar y tiene operabilidad en multiples redes y plataformas. Es menos probable que HTTPS sea bloqueado por un firewall. Una conexión HTTPS permite que credential.helper almacene en caché su contraseña. (por tanto puedes configurar tu usuario y contraseña en tu equipo de uso) Es más sencillo acceder a un repositorio desde cualquier lugar, ya que solo necesitas los detalles de tu cuenta (no se requieren claves SSH) para escribir en el repositorio. Usualmente cuando inicies un proyecto colaborativo con GitHub inicializa el ropositorio con un README. Copia el HTTPS URL para clonar el repositorio en la terminal git clone https://github.com/TU-USUARIO/TU-REPOSITORIO.git. 10.9 Credenciales HTTPS en Cache Para usar HTTPS debes crear un token de acceso personal, PAT (PERSONAL ACCESS TOKEN), esa será tu credencial para HTTPS. Es una alternativa al uso de contraseñas para la autenticación en GitHub. Como precaución de seguridad, GitHub elimina automáticamente los tokens de acceso personales que no se han usado durante un año. ¿Cómo crear un token? Ve a tu perfil de GitHub, dale click a la imagen de perfil (usualmente en la esquina superior derecha), y busca la opción de settings ó configuración según sea la configuración de idioma que tengas. Da click a continuación en Developer settings ó Parámetros del desarrollador. En la barra lateral izquierda da click en Tokens de acceso personal. Haz click en Generar un nuevo token. Asígna un nombre descriptivo a tu token. Selecciona los alcances o permisos que deseas otorgarle a este token. Para usar tu token para acceder a repositorios desde la línea de comando, selecciona repo. (Recomendados: repo, user, workflow ) Finalmente haz click en generar token. Listo, copia y pega tu token en el lugar dónde siempre lo puedas volver a copiar, ya que por razones de seguridad, una vez salgas de la página no podrás volver a ver el token. Nota: Preserva tus tokens de la misma manera que tus contraseñas y no se las reveles a nadie. Una vez que tengas un token, puedes ingresarlo en lugar de tu contraseña cuando realices operaciones de Git a través de HTTPS. El punto final es que una vez configurada una PAT, varios paquetes de R, incluidos usethis y gh, podrán trabajar con la API de GitHub en su nombre, de forma automática. Por lo tanto, una PAT configurada correctamente significa que todo esto funcionará a la perfección: - Operaciones HTTPS remotas a través de la línea de comando Git y, por lo tanto, a través de RStudio - Operaciones HTTPS remotas a través del paquete gert R y, por lo tanto, usethis - Operaciones de la API de GitHub a través del paquete gh R y, por lo tanto, usethis Probar el repositorio Clonado Después de hacer clone Usa estos comandos para verificar tu repositorio y revisar desde dónde se está sincorinzando. cd myrepo ls -la head README.md git remote show origin Probemos haciendo un cambio en el README echo "Something I want to add to the README in my local computer" >> README.md git status Qué pasó? Ahora tenemos que decirle a git que queremos seguir los cambios de ese archivo Vamos a commit los cambios y luego a subir (push) los mismos a GitHub git add README.md git commit -m "A commit from my local computer" git push Recuerda tu TOKEN!! ¿Cómo crear un token desde R? Puedes ir directamente a la página de GitHub a la parte para generar tu token de acceso personal mediante la siguiente función: usethis::create_github_token() Y con las opciones que se mencionaban anteriormente puedes configurar y crear tu PAT. Si lo que quieres es especificar tu PAT en RStudio, las siguientes funciones te serán útiles: library(gitcreds) gitcreds_set() library(credentials) set_github_pat() Para eliminar credenciales utiliza la función credentials::git_credential_forget() 10.9.1 Actividad Ejecuta los códigos y genera tu PAT, recuerda no perderlo! 10.10 Conectando RStudio con Git y Github. Para lo que sigue a continuación, deberías tener esto: Tener una cuenta en GitHub R y RStudio actualizados Git instalado Saber que desde la terminal puedes hacer push y pull 10.11 GitHub primero, RStudio después… Crea un repositorio en GitHub: mi_repositorio > Public > YES initialize this repository with a README > clicken el gran botón verde “Create repository” En RStudio crea un nuevo proyecto: File > New Project > Version Control > Git. Ahi pega el URL del repositorio https://github.com/mi_usuario/mi_repositorio.git. Da click en Create Project. Esto nos generará los siguientes elementos: Un directorio nuevo Un repositorio Git enlazado a al repositorio de GitHub Un proyecto en RStudio Con este procedimiento ya no es necesario preocuparse por configurar controles remotos Git y rastrear ramas en la línea de comandos. 10.11.1 Actividad Genera un repositorio con el nombre que desees. Y conéctalo a RStudio. Cerciorate de que el archivo README se encuentre en tu nueva carpeta. Usa la función usethis::use_r(\"titulo_de_un_script\") y observa lo que sucede. PAUSA ¿Cómo comento y doy push/pull desde RStudio? 10.11.2 Comentar, pull y push Con la flecha azul podemos hacer pull (RECUERDA HACERLO ANTES DE HACER UN PUSH), y con la flecha verde un push. Para poder comentar y hacer push debemos marcar con una flechita mediante un click en las pequeñas cajas blancas de la columna Staged, damoc click en commit lo cual no abre la siguiente ventana. Volvemos a dar click en commit, y finalizamos con push (flecha verde). 10.12 Rmarkdown en GitHub Creemos un Rmakrdown y subámoslo a GitHub Ahora hay que agregarlo al repositorio (add), stage and commit. Subieron el hmlt? Qué tal se ve? No se ve como queremos, verdad? Para eso necesitamos recuperar el .md. El .md es un resultado intermedio de crear el html desde Rmd. Tenemos que cambiar el header para esto --- title: "RmarkwondTest" output: html_document: keep_md: true --- 10.12.1 Actividad Usa el código dir.create(\"mis_imagenes\") en la consola de tu sesión de RStudio (la que está vinculada a tu repositorio). Ejecuta el siguiente código quitando los #: install.packages("MASS") library (MASS) data(MASS::cats) # pdf("mis_imagenes/cats_plot.pdf") ggplot(cats, aes(x = Sex)) + geom_bar(fill = "orange", color = "black") + theme_classic() + xlab("Sexo") + ylab("Número de Gatos") + ggtitle("Gatos") # dev.off() Comenta y da push a los cambios que realizaste en el repositorio. 10.13 RStudio primero y GitHub también Usa uno de los proyectos que hayas generado en las sesiones anteriores, PERO, que no esté enlazado a GitHub. Ahora veremos como conectar un proyecto de R existente con GitHub. Realiza los pasos que hicimos en GitHub primero, RStudio después pero asegurate de crear un repositorio con un nuevo nombre. Y LISTO!! usa un simple ctrl + c, ó mv ó click derecho + copiar ó el método que prefieras para mover o copiar archivos. Copia los archivos de tu antigüo proyecto al proyecto nuevo. Solo haz commit y push y listo, lo que tenía en tu antigüo proyecto ya está enlazado a GitHub. 10.14 Proyecto existente, GitHub al final Supongamos que tenemos un proyecto de R existente en algún lugar de nuestra computadora. NOTA: Para generar proyecto de RStudio desde la consola puedes utilizar el siguiente código: usethis::create_project() O en RStudio con File > New Project > Existing Directory Si su proyecto ya es un proyecto de RStudio, ejecútelo. ¿Ya es un repositorio de Git? La presencia del panel de Git debería alertarlo. Si es así, ha terminado. Sino este es el primer camino a seguir: Con el páquete usethis usa la función usethis::use_git En RStudio ve a Tools > Project Options > Git/SVN. Dentro de Version control system, selecciona Git. Y da click a “Yes” cuando aparezca “Confirm New Git Repository?”. Si usaste RStudio o usethis, el proyecto debería reiniciarse en RStudio. Hazlo tu mismo si hizo git init. RStudio ahora debería tener un panel Git. 10.14.1 Breviario cultural con los PATs Si usas el paquete usethis Y has configurado un token de acceso personal (PAT) de GitHub has esto en R: usethis::use_github() Esto creará un nuevo repositorio en GitHub, lo agregará como un control remoto, configurará una rama de seguimiento y lo abrirá en su navegador. Lea la ayuda de use_github() para conocer sus argumentos y consejos sobre cómo configurar una PAT. Esto es extremadamente útil para una variedad de flujos de trabajo que llaman a la API de GitHub. Considere configurar esto si usa usethis, devtools o gh con regularidad. Volviendo al tema de Proyecto existente, GitHub al final. Otra opción que se puede hacer para conectar un proyecto existen a GitHub es ir a hacer un repositorio a GitHub PERO ten en cuenta los siguientes cambios: Elije un nombre de repositorio; probablemente debería coincidir con el nombre de su proyecto y directorio local. NO inicialice este repositorio con un archivo README. Todo lo demás es igual a los pasos que hacíamos en GitHub primero, RStudio después… Ahora ve a tu proyecto de RStudio, has clic en los “dos cuadros de color púrpura y un cuadrado blanco” en el panel de Git. Has clic en “Agregar control remoto”. Pegue la URL aquí y elija un nombre remoto, casi con certeza el origin. Ahora “ADD”. Pasado esto deberiamos volver en el cuadro de diálogo “New Branch”. Ingresa “master” como el nombre de la rama y asegúrate de que la opción “Sync branch with remote” esté marcada. Haz clic en “Create”. En el siguiente cuadro de diálogo elije “overwrite”. Ahora solo haz commit/pull/push y cérciorate que FUNCIONE!! 10.15 Git basics: commands Fetch Commits git fetch Create and Switch to a branch git branch [branch-name] git checkout [branch-name] 10.16 Merge conflics A veces, no tan a veces también, las cosas no salen bien a la primera Merging (Fusionar) es una de esas cosas Cuando bajamos un cambio o fusionamos branches esto puede pasar. Primera regla: NO ENTRAR EN PANICO!!! Revisen el status del repositorio. Qué archivo tiene conflicto? 10.17 Merge conflics Abran ese archivo y busquen los problemas de merge. Es fácil, se ven así: <<<<<<< HEAD:index.html <div id="footer">contact : email.support@github.com</div> ======= <div id="footer"> please contact us at support@github.com </div> >>>>>>> issue-5:index.html Editen esa sección, dejen una versión final. Hagan commit y push Si entran en pánico? Aborten la misión! git merge --abort t 10.18 En resumen ¡QUE LA FUERZA TE ACOMPAÑE! "],["solución-de-problemas-con-las-versiones-de-paquetes-de-rstudio..html", "11 Solución de problemas con las versiones de paquetes de Rstudio. 11.1 Diapositivas", " 11 Solución de problemas con las versiones de paquetes de Rstudio. Yalbi Balderas 09 de agosto de 2023 11.1 Diapositivas "],["keynote-convirtiendo-tu-flujo-de-análisis-en-un-paquete-de-rbioconductor..html", "12 Keynote: Convirtiendo tu flujo de análisis en un paquete de R/Bioconductor. 12.1 Diapositivas", " 12 Keynote: Convirtiendo tu flujo de análisis en un paquete de R/Bioconductor. Dr. Leonardo Collado Torres 02 de agosto de 2022 12.1 Diapositivas Puedes encontrar las diapositivas aquí. "],["documentación-de-funciones.html", "13 Documentación de funciones 13.1 Diapositivas 13.2 Links importantes: 13.3 ¿Qué es la documentación de una función y por qué es importante? 13.4 Generacion de la documentacion con ayuda del paquete roxygen 13.5 Antes de empezar…✏️ 13.6 Generacion de un bloque de documentacion con ayuda del paquete roxygen. 13.7 Otros campos de la documentacion.", " 13 Documentación de funciones Andrés Arredondo Cruz 09 de agosto de 2023 13.1 Diapositivas 13.2 Links importantes: Esta lección está basada en algunos manuales sobre documentación: Una viñeta del cranproject El manual de paqutes de r En esta viñeta de cranproject 13.3 ¿Qué es la documentación de una función y por qué es importante? 🙇️ Es la información complementaria que el desarrollador escribe sobre una función y que se accede con ? seguido el nombre de una función actual de un paquete p.ej. ?unafuncion. 📁 La documentación se almacena como un archivo .Rd (“R documentation) en la carpeta man/. 🔎 La documentación usa una síntesis especial, que es distinta a la de r y que está ligeramente basada en LaTeX. 📄 Se puede renderizar como html, pdf o texto sin formato según se necesite. 13.4 Generacion de la documentacion con ayuda del paquete roxygen En un paquete de r y en cualquier ecosistema de devtools no editamos un documento .Rd manualmente. La documentación usa una síntesis parecida a LaTex que puede ser fácil de estropear. Por ventaja existen paquetes como roxigen2. Usar roxigen nos permite usar comentarios especiales sobre el inicio de la función, esto nos da un par de ventajas: ✅ La documentación y la función estarán en un mismo lugar, por lo que si editas la función será mas fácil recordar actualizar la documentcion también. 🎉 Puedes usar markdown en lugar de la síntesis especial para los archivos .Rd 13.5 Antes de empezar…✏️ Vamos a crear un función para nuestro paquete. Supongamos que para nuestro paquete necesitamos una función que calcule la moda. Esta es una forma sencilla de calcular la moda: getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } unique(serievector): Crea un vector que contiene únicamente los valores únicos de la serie de números serievector. match(serievector, uniqv): Encuentra la posición de cada valor de serievector en el vector único uniqv. tabulate(match(serievector, uniqv)): Cuenta cuántas veces aparece cada valor en la serie serievector. which.max(tabulate(match(serievector, uniqv))): Encuentra el índice del valor máximo en el vector de frecuencias. uniqv[which.max(tabulate(match(serievector, uniqv)))]: Devuelve el valor correspondiente al índice calculado, que es la moda. Creamos un ejemplo para ver que funcione: serie_numeros <- c(1, 2, 2, 2, 2, 3, 3, 4, 4, 4) resultado <- getmode(serie_numeros) print(resultado) ## [1] 2 Bien ahora si podemos podemos empezar a usar el paquete de roxygen para documentar nuestra función.. comencemos. 13.6 Generacion de un bloque de documentacion con ayuda del paquete roxygen. Podemos insertar un esqueleto de comentarios de roxygen para ver su síntesis. Colocamos el cursor en algún lugar de la definición de nuestra función y buscamos en la pestaña Código > Insertar Roxygen Skeleton. #' Title #' #' @param serievector #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ahora ya tenemos un esqueleto de la documentación que nos da una ventaja para su creación. Las líneas de comentarios de Roxygen siempre comienzan con #', el habitual para un comentario # mas un ' Veamos los comentarios de uno por uno: Empezamos con el titulo. Se sugiere poner en el titulo las acciones principales que realiza la función en este caso por ejemplo podremos usar: #' @title Encontrar la Moda de una Serie de Números #' #' @param serievector #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Muy bien!. El siguiente comentario que podemos ver es @param. Pero antes, vamos a añadir una pequeña descripción de la función y como usarla. Primero añadimos la pequeña descripción con @description: #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' @param serievector #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ahora vamos a añadir el comentario @usage que nos indica como puedes mandar a llamar la función. #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' @usage getmode(serievector) #' @param serievector #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ahora si vamos a añadir una pequeña descripción de nuestros argumentos. Si tuviéramos mas de un parámetro en nuestra función podríamos llamar las veces que sea necesario el comentario de parámetro con @param, veamoslo. Ahora añadimos una pequeña descripción a nuestro único parámetro que es serievector: #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Después, podemos añadir un comentario de detalles de la función con @details. Por ejemplo, si en nuestro ejemplo tuviéramos ciertos valores no numéricos en nuestro vector de entrada, por ejemplo letras, ¿nuestra función podría leerlas?, o si le diéramos un vector sin caracteres ¿que pasaría?, veamos: serie_numeros <- c(0,2,2,"d", "d","d") resultado <- getmode(serie_numeros) print(resultado) ## [1] "d" serie_numeros <- c() resultado <- getmode(serie_numeros) print(resultado) ## NULL Entonces, esto es un ejemplo de lo que podríamos poner en el comentario @details. Hagamoslo describiendo esto. En details podemos agregar detalles un poco mas específicos que en la descripción de la función #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @details si tu vector de entrada puede ser interpretado alternando números y #' letras escritas entre comillas "". Si un vector esta vacío, dará como #' resultado un NULL. #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ya casi terminamos de llenar nuestra documentación, pero antes vamos a ver algunos otros arrobas que pudieran ser importantes. El @import e @importfrom importan funciones de otros paquetes en caso de que las necesitemos, el primero importa todas las funciones del paquete que que solicites, y el segundo importa solo algunas funciones especificas. En nuestra función no necesitamos llamar funciones de otros paquetes puesto que todas las que usamos están en r base. Pero imaginemos que tu función, por ejemplo necesita leer un archivo .tsv con la función read_tsv del paquete readr y después reconvertir la tabla resultante en un archivo con write.table pero solo necesitas esa función del paquete utils, entonces haríamos: #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @details si tu vector de entrada puede ser interpretado alternando números y #' letras escritas entre comillas "". Si un vector esta vacío, dará como #' resultado un NULL. #' @import readr #' @importFrom utils write.table #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Así podemos importar las funciones que necesitemos de otros paquetes y se incluirán en la documentación y se cargaran automáticamente al cargar tu paquete. :eyes::exclamation: Para un correcto funcionamiento de tu paquete y al estar los paquetes necesarios incluidos en la documentación, no será necesario llamarlos de la forma ``library(“apackage”)```. Entonces llegamos a la sección @return. Esta descripción le servirá al usuario del paquete para conocer cual sera el resultado de la función, que puede ser un archivo, una tabla, un numero,etc. Entonces retomando la función que usamos al inicio, vamos a escribir una descripción corta del resultado de la función getmode(). #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @details si tu vector de entrada puede ser interpretado alternando números y #' letras escritas entre comillas "". Si un vector esta vacío, dará como #' resultado un NULL. #' @return El carácter con mas frecuencia de el vector de entrada. #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Por ultimo tenemos @export que es el encargado de renderizar la documentación para que pueda aparecer en la ventana de Ayuda (abajo a la derecha). esta opción la dejamos para funciones principales que el usuario va a utilizar, aunque puede que existan alguna funciones internas que no queremos que el usuario vea. En ese caso vamos a usar @noRd en lugar de este. Antes de terminar podemos incluir ejemplos de como funciona nuestra función para un mejor entendimiento, pongamos los que ya realizamos: #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @details si tu vector de entrada puede ser interpretado alternando números y #' letras escritas entre comillas "". Si un vector esta vacío, dará como #' resultado un NULL. #' @return El carácter con mas frecuencia de el vector de entrada. #' @export #' #' @examples #' serie_números <- c(1, 2, 2, 2, 2, 3, 3, 4, 4, 4) #' resultado <- getmode(serie_números) #' print(resultado) getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ahora si, una vez teniendo listo el bloque de comentarios para la documentación, vamos a ejecutar devtools::load_all() para cargar nuestras funciones y hecho esto, ejecutamos devtools::document() o presionamos Ctrl/Cmd + Shift + D para convertir los comentarios en archivo .Rd y poder renderizarlo. 💯 Listo, tenemos nuestra documentación para una función. Así se verá cuando el paquete esté terminado. 13.7 Otros campos de la documentacion. @seealso para indicar funciones relacionadas y facilitar la búsqueda de funciones. @references añade algunas referencias. @author para especificar el autor de la función. "],["diseño-de-pruebas.html", "14 Diseño de pruebas 14.1 Diapositivas", " 14 Diseño de pruebas Mirna Vázquez Rosas-Landa 10 de agosto de 2023 14.1 Diapositivas "],["creación-de-viñetas.html", "15 Creación de viñetas 15.1 Diapositivas 15.2 ¿Qué es una viñeta? 15.3 Características de una vignette 15.4 ¿Cómo consultar la viñeta de un paquete? 15.5 ¿Cómo crear una viñeta? 15.6 ¿Cómo guardar y actualizar la viñeta? 15.7 Veamos un ejemplo 15.8 Actividad", " 15 Creación de viñetas Joselyn Cristina Chávez Fuentes 10 de agosto de 2023 15.1 Diapositivas 15.2 ¿Qué es una viñeta? Es una guía extendida sobre cómo funciona el paquete. Es recomendable que muestre cómo utilizar las funciones del paquete, aplicado en un flujo de trabajo; por ejemplo: el análisis estadístico de una encuesta o el análisis de expresión diferencial de genes. Podemos estructurarlo como haríamos con la escritura de un capítulo de libro o de un artículo científico: debe mostrar el problema a resolver y la metodología paso a paso sobre cómo el paquete lo resuelve. Si el paquete contiene funciones que se complementan entre sí para alcanzar un fin específico, entonces debes mostrar su uso de forma compartamentalizada. 15.3 Características de una vignette Debe mostrar un flujo de análisis explotando el potencial de tu paquete. Implementa tantas funciones de tu paquete como sea posible, pero no es necesario que incluya todas. Los datos a usar deben ser pequeños o fáciles de acceder. Puedes crear múltiples viñetas para mostrar diferentes casos de análisis y cubrir una mayor cantidad de funciones. 15.4 ¿Cómo consultar la viñeta de un paquete? browseVignettes(package = "ggplot2") 15.5 ¿Cómo crear una viñeta? biocthis::use_bioc_vignette("mi_vignette") Esta función tendrá tres efectos: Generar el directorio vignettes en caso que no exista. Agregar dependencias en el archivo DESCRIPTION (por ejemplo, knitr necesario para construir viñetas dentro del paquete). Abrir un templado en formato .Rmd para comenzar a escribir la viñeta, que se va a guardar en vignettes/mi_vignette.Rmd 15.6 ¿Cómo guardar y actualizar la viñeta? Una vez que se ha generado el archivo vignettes/mi_vignette.Rmd se hacen las modificaciones necesarias. Puedes usar el comando: edit_file("vignettes/mi_vignette.Rmd") Para guardar los cambios debes hacer click en el botón Knit o utiliza la combinación de teclas Ctrl/Cmd-Shift-K. 15.7 Veamos un ejemplo Busca la viñeta del paquete regutools en la página de Bioconductor https://bioconductor.org/packages/release/bioc/html/regutools.html 15.8 Actividad Escribe una viñeta que muestre cómo utilizar las funciones para cargar y filtrar los datos de pbmc. "],["compilación-e-instalación-de-paquetes.html", "16 Compilación e instalación de paquetes 16.1 Diapositivas 16.2 Metadatos de una paquetería 16.3 Licencias 16.4 Paqueterías de código fuente 16.5 ¿En dónde podemos encontrar el código fuente de un paquete? 16.6 Instalando la última versión en desarrollo 16.7 Instalando paquetes desde GitHub 16.8 Instalando un paquete local 16.9 Contribuyendo código", " 16 Compilación e instalación de paquetes Joselyn Cristina Chávez Fuentes 10 de agosto de 2023 16.1 Diapositivas 16.2 Metadatos de una paquetería Los metadatos de la paquetería se encuentran en el archivo DESCRIPTION. 16.2.1 Description El campo Description describe lo que hace tu paquetería. Suele ser extenso, si requieres escribir múltiples líneas, deben estar indentadas. Por ejemplo: # Description: Este paquete contiene todas las funciones generadas en el curso # de escritura de paqueterías en R. También contiene las funciones que cada # participante propuso para solucionar un problema relacionado con su trabajo. 16.2.2 Dependencias Las dependencias son las paqueterías que tu paquete necesita para funcionar. La lista de paquetes se escribe separada por comas y es recomendado que se escriban en orden alfabético. Existen tres tipos: Imports: Son paquetes que deben instalarse para que tu paquete funcione y por tanto se van a instalar en el momento que instales el paquete. Internamente existe una función que evalúa si los paquetes se encuentran instalados o no y solamente instala los faltantes. Esta dependencia hace solamente la instalación pero no ejecuta library(), por lo que los paquetes requeridos deberán ser cargados dentro de la escritura del paquete. Depends: Son paquetes que obligatoriamente deben estar para que tu paquetería funcione pero no se instalarán de manera automática. Aquí también se indica la versión de R requerida para el funcionamiento del paquete. Los paquetes que se listen aquí se van a cargar al mismo tiempo que se ejecute el library(mipaquete). Suggests: Se refiere a los paquetes que tu paquete puede utilizar y aprovechar para ser más poderoso en el análsis pero no los necesita para funcionar. Por ejemplo, paquetes que contienen sets de datos para hacer pruebas o análisis de práctica. Nota Importante Se recomienda listar los paquetes necesarios para el funcionamiento de nuestro paquete en Imports porque cuando se ponen en Depends se cargan los paquetes completos y probablemente solamente requerimos una o dos funciones. Cargar demasiados paquetes completos, sin ser necesario, sólo hace que nuestro paquete se vuelva pesado y lento. Es mejor llamar particularmente a las funciones usando la sintaxis explícita: Biostrings::translate() 16.2.3 ¿Cómo añadir dependencias? Usando usethis: usethis::use_package("ggplot2", type = "Imports") Editando manualmente el archivo DESCRIPTION. 16.3 Licencias Establece quién puede usar tu paquete. Existen diversas licencias pero hablaremos sobre las 3 más comunes: MIT (Massachusetts Institute of Technology): es simple y permisiva. Permite a cualquier persona usar y distribuir tu paquetería con una sola restricción: la distribución debe incluir la declaración de licencia del autor. Existe un texto base al cual se le pueden añadir cláusulas o excepciones. Este es un ejemplo: GPL-2 (General Public License): Permite usar y distribuir tu código con la condición que si se genera una versión modificada de tu código, su distribución debe ser también bajo esta licencia. Aunque está enfocada a la distribución de código abierto, permite dejar en claro quién es el autor del material y evitar la apropiación del código por terceros. Un ejemplo de la aplicación de esta licencia es el desarrollo de Linux. CCO: Esta licencia implica que cedes todos los derechos y el código puede ser utilizado con cualquier fin, excepto fines comerciales. Es el más utilizado en los paquetes. Concede el derecho a utilizar y distribuir el material sin requerir el permiso del autor. 16.4 Paqueterías de código fuente En algunas ocasiones necesitaremos instalar paquetes que no se encuentran compilados, por ejemplo: Paquetes en desarrollo de CRAN o Bioconductor. Versiones anteriores de paquetes de CRAN o Bioconductor. Paquetes que no se encuentran depositados en CRAN o Bioconductor, sino en repositorios personales como GitHub. Paquetes que estás desarrollando de forma local. El paquete remotes será de gran utilidad. Regularmente, los paquetes que instalamos desde algún repositorio como CRAN o Bioconductor son paquetes binarios que ya se encuentran compilados previamente. Existen algunas funciones que nos permiten instalar paquetes desde código fuente. Anteriormente, se solían utilizar las funciones install_* del paquete devtools; sin embargo, recientemente se creó el paquete remotes que contiene las mismas funciones pero está específicamente diseñado para ayudarnos a trabajar con paquetes desde código fuente. 16.5 ¿En dónde podemos encontrar el código fuente de un paquete? Si el paquete se encuentra disponible en CRAN, puedes encontrar el link al código fuente en la sección URL. Si el paquete se encuentra disponible en Bioconductor, puedes encontrar el link al código fuente en la sección Package Archives Si el paquete se encuentra en GitHub o GitLab, necesitarás conocer el nombre de usuario y el nombre del paquete. 16.6 Instalando la última versión en desarrollo Si el paquete se encuentra depositado en CRAN podemos usar la función remotes::install_dev("pkgname") Por ejemplo, para instalar la versión en desarrollo de dplyr usaremos el comando remotes::install_dev("dplyr") Si el paquete se encuentra en Bioconductor usaremos la siguiente función: remotes::install_bioc("pkgname") Por ejemplo, para instalar la versión en desarrollo de regutools, el paquete desarrollado por miembros de la CDSB, usaremos el comando remotes::install_bioc("regutools") 16.7 Instalando paquetes desde GitHub Para poder instalar un paquete desde GitHub necesitaremos conocer el usuario del creador y el nombre del repositorio. remotes::install_github("usuario/repositorio") Por ejemplo, para instalar el paquete starwarssay desarrollado por Erick Cuevas (Erickcufe) utilizaremos el siguiente comando: remotes::install_github("Erickcufe/starwarssay") Independientemente de si el paquete se encuentra en CRAN, Bioconductor, o ninguno de ellos, podemos instalar un paquete depositado en una cuenta de GitHub. Para poder instalar un paquete desde GitHub necesitaremos conocer el usuario del creador y el nombre del repositorio donde se encuentra depositado el paquete. Con esta información usaremos la siguiente función: 16.8 Instalando un paquete local Paso 1: Abre el proyecto del paquete que estás desarrollando. Paso opcional: Ejecuta la documentación si realizaste algún cambio. devtools::document() Paso 2: Construye el paquete: devtools::build() Paso 3: Instala el paquete desde tu proyecto actual: devtools::install() 16.9 Contribuyendo código Una ventaja de descargar el paquete de forma local es que puedes realizar cambios, probar que funciona de manera local y después contribuir (haciendo un pull-request). Usemos el paquete saludo Clona el repositorio en tu computadora. git clone https://github.com/ComunidadBioInfo/saludo.git Ahora puedes abrir el proyecto del paquete y agregar tu código. "],["proyectos-colaborativos-1.html", "17 Proyectos colaborativos 17.1 Propuesta 1 17.2 Propuesta 2 17.3 Propuesta 3 17.4 Propuesta 4 17.5 Propuesta 5", " 17 Proyectos colaborativos 17.1 Propuesta 1 Crea un paquete que implemente el análisis de expresión diferencial. Evalúa el funcionamiento del paquete en el análisis de placas calcificadas de Aterogénesis. Puedes descargar los datos de: https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE159677 17.2 Propuesta 2 Realiza la anotación de tipos celulares del sistema inmune en una muestra de médula ósea usando los marcadores propuestos por Human Cell Atlas. Puedes descargar los datos de single-cell de: https://www.10xgenomics.com/resources/datasets/20-k-bone-marrow-mononuclear-cells-bmmn-cs-5-ht-v-2-0-2-high-6-1-0 17.3 Propuesta 3 Realiza el análisis y anotación de tipos celulares en un dataset de cáncer de próstata. Puedes descargar los datos de: https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE157703 17.4 Propuesta 4 Crear un paquete que implemente el análisis de enriquecimiento de los genes diferencialmente expresados. Evalúa el funcionamiento del paquete en el análisis de células neoplásticas en glioblastoma humano. Puedes descargar los datos de: https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE84465 Consulta el artículo original en: https://www.sciencedirect.com/science/article/pii/S2211124717314626?via%3Dihub#app3 17.5 Propuesta 5 Desarrolla un paquete para facilitar la visualización de los tipos celulares de alguno de los datasets mencionados previamente. "],["404.html", "Page not found", " Page not found The page you requested cannot be found (perhaps it was moved or renamed). You may want to try searching to find the page's new location, or use the table of contents to find the page you are looking for. "]]
+[["index.html", "Workshop CDSB 2023: Creando paquetes de R/Bioconductor para análisis transcriptómicos de célula única. Bienvenida 0.1 Instructores 0.2 Ponentes invitados 0.3 Ayudantes 0.4 Temario 0.5 Patrocinadores 0.6 Licencia", " Workshop CDSB 2023: Creando paquetes de R/Bioconductor para análisis transcriptómicos de célula única. Dra. Joselyn Cristina Chávez-Fuentes, Dr. Leonardo Collado-Torres, Dra. Yalbi Balderas-Martínez, M.C. Erick Cuevas-Fernández, Dra. Mirna Vázquez Rosas-Landa, Dra. Alejandra Medina-Rivera, Bienvenida Les damos la bienvenida al Workshop Creando paquetes de R/Bioconductor para análisis transcriptómicos de célula única! En los últimos años, la generación de datos transcriptómicos de célula única ha cobrado gran relevancia en la investigación biomédica; sin embargo, las herramientas necesarias para su análisis continúan en desarrollo. En este taller haremos un repaso a las herramientas estadísticas existentes para analizar datos transcriptómicos de célula única usando Bioconductor, cómo documentar tu análisis y revisaremos algunas herramientas para la interpretación de resultados. A la par, aprenderás cuáles son los pasos cruciales para desarrollar un paquete de R y algunas buenas prácticas para la generación de código. Con la integración de estas herramientas, tendrás la oportunidad de crear tu primer paquete y contribuir a la comunidad de desarrolladores. 0.1 Instructores Dra. Joselyn Cristina Chávez Fuentes: Estancia Postdoctoral en Icahn School of Medicine at Mount Sinai. Dr. Leonardo Collado-Torres: Investigador en Lieber Institute for Brain Development. Dra. Yalbi Balderas Martínez: Investigadora en el Instituto Nacional de Enfermedades Respiratorias Ismael Cosío Villegas. M.C. Erick Cuevas Fernández: Estudiante de Doctorado en la Universidad Nacional Autónoma de México. Dra. Mirna Vázquez Rosas Landa: Investigadora en el Instituto de Ciencias de Mar y Limnología de la UNAM. Dra. Alejandra Medina Rivera: Investigadora Asociada en el Laboratorio Internacional de Investigación de Medicina Genómica, UNAM. 0.2 Ponentes invitados Dra. Evelia Coss Dra Laura Lucila Gómez Romero M.C. José Antonio Ovando M.C. Andrés Arredondo Cruz 0.3 Ayudantes Dra. Evelia Coss M.C. José Antonio Ovando M.C. Andrés Arredondo Cruz M.C. Diego Ramírez M.C. Luis Alberto Meza 0.4 Temario Consulta el calendario de este curso en: https://bit.ly/calendarcdsb2023 Día 1: Flujo de análisis de datos transcriptómicos de célula única Parte I Presentación de la CDSB. Estructura e importe de datos. Control de calidad. Normalización. Día 2: Flujo de análisis de datos transcriptómicos de célula única Parte II Selección de genes altamente variables. Reducción de dimensiones. Clustering. Genes marcadores. Anotación de tipos celulares. Día 3: Creación de paquetes de R/Bioconductor Parte I Nuevas funcionalidades de RStudio, Quarto. Control de versiones con GitHub y RStudio. Solución de problemas con las versiones de paquetes de Rstudio. Infraestructura de un paquete de R/Bioconductor. Plática: Convirtiendo tu flujo de análisis en un paquete de R/Bioconductor. Documentación de funciones. Sesión social: Conociendo a la comunidad. Día 4: Creación de paquetes de R/Bioconductor Parte II Diseño de pruebas. Creación de viñetas. Compilación e instalación de paquetes. Proyectos colaborativos Parte I. Día 5: Proyectos colaborativos Proyectos colaborativos Parte II. Presentación de proyectos. Clausura. 0.5 Patrocinadores Agradecemos a nuestros patrocinadores: 0.6 Licencia Este material posee una licencia tipo Creative Commons Attribution-ShareAlike 4.0 International License. Para conocer más sobre esta licencia, visite http://creativecommons.org/licenses/by-sa/4.0/ "],["estructura-e-importe-de-datos.html", "1 Estructura e importe de datos 1.1 Diapositivas 1.2 Bulk RNAseq vs single-cell RNAseq 1.3 Consideraciones experimentales 1.4 Generación de la matriz de cuentas 1.5 Nombres de los genes 1.6 Importando los datos 1.7 Actividad 1.8 Actividad 1.9 El objeto SingleCellExperiment 1.10 Construyendo un objeto SingleCellExperiment 1.11 Accediendo a los elementos del objeto 1.12 Agregando más assays 1.13 Un vistazo al flujo de trabajo", " 1 Estructura e importe de datos Joselyn Cristina Chávez Fuentes 07 de agosto de 2023 1.1 Diapositivas 1.2 Bulk RNAseq vs single-cell RNAseq Tomado de Yu X, et al. Bulk RNAseq Tomado de Hyeongseon Jeon, et al. scRNAseq 1.3 Consideraciones experimentales 1.3.1 Tecnologías de scRNAseq Droplet-based: Son las tecnologías más usadas debido a su buen rendimiento con un relativo bajo costo. 10X Genomics inDrop seq Drop-seq Plate-based Tienen la capacidad de capturar información adicional, como la morfología. Tienen más opciones para personalizar el diseño de experimento. Con UMIs: CEL-seq MARS-seq Con reads: Smart-seq2 Otros sciRNA-seq 1.3.2 ¿UMIs o Reads? Los métodos basados en reads proveen una cobertura de transcriptoma completo, lo que puede ser útil para ciertas aplicaciones, como el análisis de splicing o mutaciones en exones. Los métodos basados en UMIs suelen ser más populares, ya que eliminan el ruido causado por la amplificación durante el PCR. 1.3.3 ¿Cuántas células y profundidad de secuenciación necesito? Depende… Si tu objetivo es el estudio de subgrupos raros o poco abundantes de células, necesitarás un mayor número de células por muestra. Si tu objetivo es estudiar diferencias sutiles en la expresión de genes, necesitarás una mayor profundidad de secuenciación. Hasta el momento, las tecnologías basadas en droplets capturan entre 10,000 y 100,000 células, con un aproximado de 1,000 a 10,000 UMIs por célula. Existen algunas variaciones entre el rendimiento y la tasa de doublets que pueden afectar la eficiencia real de secuenciación. Encontrar un balance entre el número de células por muestra, la profundidad de secuenciación, el número de condiciones y réplicas a secuenciar depende mucho de la aplicación y el presupuesto. 1.4 Generación de la matriz de cuentas El método para generar la matriz depende de la tecnología utilizada. 10X Genomics: Cellranger es el programa más popular. Utiliza STAR para alinear los reads con el genoma de referencia y después cuenta el número de UMIs únicos mapeados con cada gene. Como alternativa, métodos de pseudo-alineamiento como alevin pueden ser usados. No requiere un alineamiento con genoma de referencia, lo que reduce el tiempo de cómputo y los requerimientos de memoria. El paquete scPipe provee un análisis general. Utiliza Rsubread para alinear los reads y después cuenta reads o UMIs por gene. CEL-seq o CEL-seq2 El paquete scruff provee un pipeline para la cuantificación. De manera general, los protocolos basados en reads pueden reusar los métodos desarrollados para bulk RNA-seq. Si el grupo de datos involucra transcritos spike-in, las secuencias spike-in deben proveerse junto al genoma de referencia durante el alineamiento y cuantificación. 1.5 Nombres de los genes En todos los casos, los identificadores de genes deben definirse considerando los nombres de Ensembl o Entrez. Esto mantiene un mapeo sin lugar a errores para la identificación de genes en la matriz. Estos identificadores pueden ser reemplazados por el nombre común del gene durante el análisis, pero considera que estos nombres pueden cambiar con el tiempo. Consideraciones adicionales: Algunas herramientas de conteo, como HTSeq, incluyen un reporte dentro de la matriz de cuentas con el número lecturas sin alinear. Estos valores pueden ser útiles para el control de calidad, pero deben ser removidas de la matriz de cuentas y guardadas en otro lugar antes de continuar con el análisis para que no sean confundidas con los valores de expresión de genes. Generalmente, las secuencias spike-ins son desarrolladas por el External RNA Controls Consortium (ERCC) y suelen tener nombres como ERCC-00002. En las muestra de humano, debemos evitar confundir estos identificadores con los genes de la familia ERCC, que suelen tener nombres similares ERCC1. Podemos evitar estos problemas si usamos los identificadores de Ensembl. 1.6 Importando los datos 1.6.1 Datos tabulares Descarguemos los datos de cáncer de páncreas de Muraro et al (2016) GSE85241. Solamente necesitamos el archivo “GSE85241_cellsystems_dataset_4donors_updated.csv” Una forma sencilla mat <- read.delim( "GSE85241_cellsystems_dataset_4donors_updated.csv") mat <- as.matrix(mat) dim(mat) mat[1:3,1:3] Una opción más eficiente. Solamente se leen los datos diferentes a cero. sparse.mat <- scuttle::readSparseCounts( "GSE85241_cellsystems_dataset_4donors_updated.csv") dim(sparse.mat) sparse.mat[1:3,1:3] 1.7 Actividad Comparemos la clase y la cantidad de memoria que utiliza cada opción. Utiliza las funciones class() y lobstr::obj_size() para comparar mat y sparse.mat 1.7.1 Datos de cellRanger Cuando usamos datos de 10X Genomics, Cellranger genera un directorio que contiene 3 archivos: cuentas, anotaciones de features y barcodes. Podemos usar la ruta a este directorio y la función read10xCounts() del paquete DropletUtils. Utilicemos como ejemplo un dataset de células sanguíneas periféricas. sce <- DropletUtils::read10xCounts( "raw_gene_bc_matrices/GRCh38/") 1.8 Actividad Evalúa la clase de sce. ¿Habías escuchado antes sobre este tipo de objeto? Imprime el objeto sce en la consola. ¿Cómo se ve el resultado? 1.8.1 Datos con formato HDF5 El formato Hierarchical Data Format version 5 (HDF5) permite guardar tanto los valores de expresión asociados a los genes, como la anotación de los tipos celulares dentro de un mismo archivo. Podemos leer este archivo con un objeto SingleCellExperiment utilizando el paquete zellkonverter. library(zellkonverter) demo <- system.file("extdata", "krumsiek11.h5ad", package = "zellkonverter") sce <- readH5AD(demo) 1.8.2 Datos con formato loom Los archivos con formato Loom son una variante de HDF5, pueden ser leídos como un objeto SingleCellLoomExperiment usando el paquete LoomExperiment. Este objeto es una extensión del SingleCellExperiment. library(LoomExperiment) demo <- system.file("extdata", "L1_DRG_20_example.loom", package = "LoomExperiment") scle <- import(demo, type="SingleCellLoomExperiment") 1.9 El objeto SingleCellExperiment 1.10 Construyendo un objeto SingleCellExperiment Para crear un SingleCellExperiment rudimentario, solamente necesitamos el slot assays. Este slot necesita la matriz de cuentas, donde los renglones corresponden a los genes (features) y las columnas corresponden a las células. mat <- read.delim( "GSE85241_cellsystems_dataset_4donors_updated.csv") mat <- as.matrix(mat) sce <- SingleCellExperiment::SingleCellExperiment( assays = list(counts = mat)) 1.11 Accediendo a los elementos del objeto Para poder ver el contenido del slot assays tenemos dos opciones: Forma general, usando el nombre del assay que queremos ver: m <- assay(sce, "counts") Una opción más corta, pero sólo funciona cuando el assay se llama “counts” m <- counts(sce) 1.12 Agregando más assays Se pueden guardar varias versiones de los datos de cuentas. sce <- scuttle::logNormCounts(sce) sce Observa el slot assays, notas algo diferente? También se pueden conocer los assays disponibles: assayNames(sce) 1.13 Un vistazo al flujo de trabajo "],["control-de-calidad.html", "2 Control de calidad 2.1 Material y Diapositivas 2.2 Enfoques o Ideas principales 2.3 ¿Por qué hay problemas con los datos? 2.4 Preguntas Básicas en Control de Calidad 2.5 La mala calidad en los datos puede ser debida a varios factores 2.6 Recomendaciones 2.7 Tipos de filtros 2.8 Parámetros empleados para evaluar la calidad con la función addPerCellQC 2.9 Ejemplo: linea celular 416 en ratón 2.10 ¿Cómo funciona isOutlier()? 2.11 Consideran el Batch 2.12 Visualización gráfica de las células de buena calidad 2.13 Identificando droplets vacíos con datos de PBMC 2.14 Visualización de los datos con ISEE 2.15 Detalles de la sesión de R", " 2 Control de calidad Dra. Evelia Coss 07 de agosto de 2023 2.1 Material y Diapositivas Diapositivas de Peter Hickey: Ve las diapositivas aquí. Curso 2021 impartido por Leonardo Collado Torres: Ver información aquí 2.2 Enfoques o Ideas principales Detectar células verdaderas y de alta calidad ✅🍪, de modo que cuando agrupemos nuestras células sea más fácil identificar poblaciones de tipos celulares distintos. Identificar las muestras fallidas e intentar salvar los datos o eliminarlas del análisis, además de intentar comprender por qué falló la muestra. 2.3 ¿Por qué hay problemas con los datos? Problemas con el rompimiento de las células. Fallos en la preparación de las bibliotecas (ineficiencias en la transcripción inversa, amplificacion por PCR, etc). Más de una célula durante la secuenciación (douplets o multiplets). Problemas en el alineamiento. 2.4 Preguntas Básicas en Control de Calidad Se responden durante el análisis de SingleCell RNA-Seq. ¿Cuántos droplets traen más de una célula? (douplets 🍪🍪 o multiplets 🍪🍪🍪). ¿Cuántas células murieron durante el proceso de secuenciacion? Cada droplets debe contener una sola célula 🍪. Figura obtenida de Single-Cell best practices. 2.5 La mala calidad en los datos puede ser debida a varios factores Una o varias células podemos encontrar: ⚠️ Baja cantidad de cuentas totales ⚠️ Baja cantidad de genes expresados ⚠️ Alta proporción de cuentas (reads) provenientes de la mitocondria ⚠️ Alta proporción de cuentas provenientes de las secuencias control (ERCC spike-in control transcripts) Mas informacion sobre ERCC spike-in control transcripts. 2.6 Recomendaciones Tener un correcto diseño experimental (evitar efecto bash). 👾 Correcta preparación de las muestras. 🎮 Analizar la calidad de los datos. 🍪 2.7 Tipos de filtros Fixed thresholds: Valores de corte fijos y estrictos (FDR < 0.5) ♠️ Adaptative thresholds: Valores de cortes adaptados al comportamiento de nuestros datos.♦️ 2.8 Parámetros empleados para evaluar la calidad con la función addPerCellQC La función addPerCellQC provenie del paquete scater. Agrega las siguientes métricas en cada célula y por cada gen dentro del mismo archivo. sum: Número de cuentas (lecturas) totales de cada célula. detected: Genes expresados con al menos una cuenta. altexps_ERCC_percent: Porcentaje de cuentas mapeadas de las secuencias control (ERCC spike-in control transcripts). subsets_Mito_percent: Porcentaje de cuentas mapeadas provenientes de la mitocondria. 2.9 Ejemplo: linea celular 416 en ratón Realizaremos las siguientes actividades con este ejemplo: Eliminar células de baja calidad. Comparar entre los tipos de filtros (Fixed thresholds y Adaptative thresholds). Filtrar células baja calidad. Visualización de datos crudos y filtrados. Línea celular de células mieloides progenitoras inmortalizadas de ratón usando SmartSeq2. 2.9.1 Paquetes e Importar los datos en R Los paquetes que vamos a emplear para esta sección son: library(scRNAseq) ## para descargar datos de ejemplo library(DropletUtils) ## para detectar droplets library(Matrix) ## para leer datos en formatos comprimidos library(AnnotationHub) ## para obtener información de genes library(scater) ## para gráficas y control de calidad library(BiocFileCache) ## para descargar datos library(EnsDb.Hsapiens.v86) ## Archivo de anotacion en humanos en Ensembl library(dplyr) ## Modificacion de archivos dataframe Cargar los datos empleando el paquete scRNAseq sce.416b <- LunSpikeInData(which = "416b") ## snapshotDate(): 2023-04-24 ## see ?scRNAseq and browseVignettes('scRNAseq') for documentation ## loading from cache ## see ?scRNAseq and browseVignettes('scRNAseq') for documentation ## loading from cache ## see ?scRNAseq and browseVignettes('scRNAseq') for documentation ## loading from cache ## snapshotDate(): 2023-04-24 ## see ?scRNAseq and browseVignettes('scRNAseq') for documentation ## loading from cache ## snapshotDate(): 2023-04-24 ## loading from cache # Conversion a factor, evitemos mensajes de error sce.416b$block <- factor(sce.416b$block) El paquete scRNAseq contiene múltiples data sets compilados en funciones, para saber más da click aquí. 2.9.2 Anotación de genes ah <- AnnotationHub() ## snapshotDate(): 2023-04-24 query(ah, c("Mus musculus", "Ensembl", "v97")) ## AnnotationHub with 1 record ## # snapshotDate(): 2023-04-24 ## # names(): AH73905 ## # $dataprovider: Ensembl ## # $species: Mus musculus ## # $rdataclass: EnsDb ## # $rdatadateadded: 2019-05-02 ## # $title: Ensembl 97 EnsDb for Mus musculus ## # $description: Gene and protein annotations for Mus musculus based on Ensembl version 97. ## # $taxonomyid: 10090 ## # $genome: GRCm38 ## # $sourcetype: ensembl ## # $sourceurl: http://www.ensembl.org ## # $sourcesize: NA ## # $tags: c("97", "AHEnsDbs", "Annotation", "EnsDb", "Ensembl", "Gene", "Protein", "Transcript") ## # retrieve record with 'object[["AH73905"]]' # Anotacion de genes con la localizacion de cada cromosoma ens.mm.v97 <- ah[["AH73905"]] # solo un cromosoma ## loading from cache location <- mapIds(ens.mm.v97, keys=rownames(sce.416b), keytype="GENEID", column="SEQNAME") ## Warning: Unable to map 563 of 46604 requested IDs. # deteccion de genes mitocondriales is.mito <- which(location=="MT") 2.9.3 Análisis de calidad con addPerCellQC Al imprimir la variable sce.416b podemos observar que es de tipo SingleCellExperiment. # Agregar la informacion de la calidad por cada gen y celula en un mismo archivo # Identificar genes mitocondriales sce.416b <- addPerCellQC(sce.416b, subsets = list(Mito = is.mito) ) sce.416b ## class: SingleCellExperiment ## dim: 46604 192 ## metadata(0): ## assays(1): counts ## rownames(46604): ENSMUSG00000102693 ENSMUSG00000064842 ... ENSMUSG00000095742 CBFB-MYH11-mcherry ## rowData names(1): Length ## colnames(192): SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 ... ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 ## colData names(21): Source Name cell line ... altexps_SIRV_percent total ## reducedDimNames(0): ## mainExpName: endogenous ## altExpNames(2): ERCC SIRV Podemos observar la informacion de este data frame usando colData: # observar la informacion contenida en el dataframe colData(sce.416b) ## DataFrame with 192 rows and 21 columns ## Source Name cell line cell type single cell well quality ## <character> <character> <character> <character> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 SLX-9555.N701_S502.C.. 416B embryonic stem cell OK ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 SLX-9555.N701_S503.C.. 416B embryonic stem cell OK ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 SLX-9555.N701_S504.C.. 416B embryonic stem cell OK ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 SLX-9555.N701_S505.C.. 416B embryonic stem cell OK ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 SLX-9555.N701_S506.C.. 416B embryonic stem cell OK ## ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S505... 416B embryonic stem cell OK ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S506... 416B embryonic stem cell OK ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S507... 416B embryonic stem cell OK ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S508... 416B embryonic stem cell OK ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 SLX-11312.N712_S517... 416B embryonic stem cell OK ## genotype phenotype strain spike-in addition ## <character> <character> <character> <character> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. wild type phenotype B6D2F1-J ERCC+SIRV ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. wild type phenotype B6D2F1-J ERCC+SIRV ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. wild type phenotype B6D2F1-J ERCC+SIRV ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J ERCC+SIRV ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J ERCC+SIRV ## ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J Premixed ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J Premixed ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J Premixed ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. induced CBFB-MYH11 o.. B6D2F1-J Premixed ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 Doxycycline-inducibl.. wild type phenotype B6D2F1-J Premixed ## block sum detected subsets_Mito_sum subsets_Mito_detected ## <factor> <numeric> <numeric> <numeric> <numeric> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 20160113 865936 7618 78790 20 ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 20160113 1076277 7521 98613 20 ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 20160113 1180138 8306 100341 19 ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 20160113 1342593 8143 104882 20 ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 20160113 1668311 7154 129559 22 ## ... ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 20160325 776622 8174 48126 20 ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 20160325 1299950 8956 112225 25 ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 20160325 1800696 9530 135693 23 ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 20160325 46731 6649 3505 16 ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 20160325 1866692 10964 150375 29 ## subsets_Mito_percent altexps_ERCC_sum altexps_ERCC_detected altexps_ERCC_percent ## <numeric> <numeric> <numeric> <numeric> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 9.09882 65278 39 6.80658 ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 9.16242 74748 40 6.28030 ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 8.50248 60878 42 4.78949 ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 7.81190 60073 42 4.18567 ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 7.76588 136810 44 7.28887 ## ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 6.19684 61575 39 7.17620 ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 8.63302 94982 41 6.65764 ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 7.53559 113707 40 5.81467 ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 7.50037 7580 44 13.48898 ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 8.05569 48664 39 2.51930 ## altexps_SIRV_sum altexps_SIRV_detected altexps_SIRV_percent total ## <numeric> <numeric> <numeric> <numeric> ## SLX-9555.N701_S502.C89V9ANXX.s_1.r_1 27828 7 2.90165 959042 ## SLX-9555.N701_S503.C89V9ANXX.s_1.r_1 39173 7 3.29130 1190198 ## SLX-9555.N701_S504.C89V9ANXX.s_1.r_1 30058 7 2.36477 1271074 ## SLX-9555.N701_S505.C89V9ANXX.s_1.r_1 32542 7 2.26741 1435208 ## SLX-9555.N701_S506.C89V9ANXX.s_1.r_1 71850 7 3.82798 1876971 ## ... ... ... ... ... ## SLX-11312.N712_S505.H5H5YBBXX.s_8.r_1 19848 7 2.313165 858045 ## SLX-11312.N712_S506.H5H5YBBXX.s_8.r_1 31729 7 2.224004 1426661 ## SLX-11312.N712_S507.H5H5YBBXX.s_8.r_1 41116 7 2.102562 1955519 ## SLX-11312.N712_S508.H5H5YBBXX.s_8.r_1 1883 7 3.350892 56194 ## SLX-11312.N712_S517.H5H5YBBXX.s_8.r_1 16289 7 0.843271 1931645 # Ver el nombre de las columnas colnames(colData(sce.416b)) ## [1] "Source Name" "cell line" "cell type" "single cell well quality" ## [5] "genotype" "phenotype" "strain" "spike-in addition" ## [9] "block" "sum" "detected" "subsets_Mito_sum" ## [13] "subsets_Mito_detected" "subsets_Mito_percent" "altexps_ERCC_sum" "altexps_ERCC_detected" ## [17] "altexps_ERCC_percent" "altexps_SIRV_sum" "altexps_SIRV_detected" "altexps_SIRV_percent" ## [21] "total" 2.9.4 Preguntas sobre los datos ¿Cuántas células detectadas se encuentran en el dataframe sce.416b? 1 ¿Cuántos genes fueron analizados con al menos una cuenta? 2 Podemos conocer estas respuestas observando la informacion contenida en sce.416b, en dimensiones. 2.9.5 Visualización de los datos crudos Genes detectados en cada uno de los bloques de secuenciación. plotColData(sce.416b, x = "block", y = "detected") Genes detectados por cada tratamiento en cada bloque de secuenciación. plotColData(sce.416b, x = "block", y = "detected", other_fields = "phenotype" ) + scale_y_log10() + # Cambiar la escala en Y a logaritmo facet_wrap(~phenotype) + # Dividir tratamiento labs(x = "Bloques de secuenciación", y="Genes detectados \\n(log)", title = "Genes detectados") # Etiquetas en X, Y y titulo 2.9.6 Filtro A: Fixed thresholds Para el filtrado y eliminación de las células de baja calidad emplearemos las variables sum, detected, altexps_ERCC_percent y subsets_Mito_percent. # --- Fixed thresholds --- # Valores de corte fijos y estrictos qc.lib <- sce.416b$sum < 100000 # menos de 100 mil cuentas (lecturas) qc.nexprs <- sce.416b$detected < 5000 # menos de 5 mil genes qc.spike <- sce.416b$altexps_ERCC_percent > 10 # 10 % de las cuentas alineando a ERCC qc.mito <- sce.416b$subsets_Mito_percent > 10 # 10 % alineando al genoma mitocondrial discard <- qc.lib | qc.nexprs | qc.spike | qc.mito # si falla alguno de estos eliminarlo # secuencias control = (ERCC spike-in control transcripts) # Resumen del número de células # Número de células eliminadas por cada filtro DataFrame( LibSize = sum(qc.lib), NExprs = sum(qc.nexprs), SpikeProp = sum(qc.spike), MitoProp = sum(qc.mito), Total = sum(discard) ) ## DataFrame with 1 row and 5 columns ## LibSize NExprs SpikeProp MitoProp Total ## <integer> <integer> <integer> <integer> <integer> ## 1 3 0 19 14 33 2.9.7 Filtro B: Adaptative thresholds Valores de cortes adaptados al comportamiento de nuestros datos. # --- Adaptative thresholds --- ## Usando isOutlier() para determinar los valores de corte qc.lib2 <- isOutlier(sce.416b$sum, log = TRUE, type = "lower") qc.nexprs2 <- isOutlier(sce.416b$detected, log = TRUE, type = "lower" ) qc.spike2 <- isOutlier(sce.416b$altexps_ERCC_percent, type = "higher" ) qc.mito2 <- isOutlier(sce.416b$subsets_Mito_percent, type = "higher" ) discard2 <- qc.lib2 | qc.nexprs2 | qc.spike2 | qc.mito2 # Extraemos los límites de valores (thresholds) attr(qc.lib2, "thresholds") ## lower higher ## 434082.9 Inf attr(qc.nexprs2, "thresholds") ## lower higher ## 5231.468 Inf # Obtenemos un resumen del número de células # eliminadas por cada filtro DataFrame( LibSize = sum(qc.lib2), NExprs = sum(qc.nexprs2), SpikeProp = sum(qc.spike2), MitoProp = sum(qc.mito2), Total = sum(discard2) ) ## DataFrame with 1 row and 5 columns ## LibSize NExprs SpikeProp MitoProp Total ## <integer> <integer> <integer> <integer> <integer> ## 1 4 0 1 2 6 2.9.8 Preguntas por resolver ¿Cuántos células se descartan con cada filtro? ¿Cuántas células se comparten entre ambos filtros? ¿Cúal filtro fue más estricto? ¿Existen células que el filtro adaptativo excluyera y que no lo hiciera el filtro estricto? Para contestar estas preguntas podemos emplear: addmargins(table(discard, discard2)) ## discard2 ## discard FALSE TRUE Sum ## FALSE 159 0 159 ## TRUE 27 6 33 ## Sum 186 6 192 2.10 ¿Cómo funciona isOutlier()? Supongamos que la mayor parte del conjunto de datos está formado por células de alta calidad 1 (Opcional: log-transformar la métrica QC) 1. Calcular la mediana de la métrica QC Calcular la desviación absoluta de la mediana (MAD2) de la QC Identifique los valores atípicos como aquellas celdas con una métrica QC a más de 3 MAD3 de la mediana en la dirección “problemática”. Puede controlar cuántas MAD son aceptables Puede decidir qué dirección es problemática QC = Quality Control 1 But we’ll relax that assumption in a few moments 2 MAD is similar to standard deviation 3 Loosely, 3 MADs will retain 99% of non-outliers values that follow a Normal distribution. Figura explicativa, Diapositiva 24. 2.11 Consideran el Batch ## Determino el bloque (batch) de muestras batch <- paste0(sce.416b$phenotype, "-", sce.416b$block) ## Versión de isOutlier() que toma en cuenta los bloques de muestras qc.lib3 <- isOutlier(sce.416b$sum, log = TRUE, type = "lower", batch = batch ) qc.nexprs3 <- isOutlier(sce.416b$detected, log = TRUE, type = "lower", batch = batch ) qc.spike3 <- isOutlier(sce.416b$altexps_ERCC_percent, type = "higher", batch = batch ) qc.mito3 <- isOutlier(sce.416b$subsets_Mito_percent, type = "higher", batch = batch ) discard3 <- qc.lib3 | qc.nexprs3 | qc.spike3 | qc.mito3 # Extraemos los límites de valores (thresholds) attr(qc.lib3, "thresholds") ## induced CBFB-MYH11 oncogene expression-20160113 induced CBFB-MYH11 oncogene expression-20160325 ## lower 461073.1 399133.7 ## higher Inf Inf ## wild type phenotype-20160113 wild type phenotype-20160325 ## lower 599794.9 370316.5 ## higher Inf Inf # Obtenemos un resumen del número de células # eliminadas por cada filtro DataFrame( LibSize = sum(qc.lib3), NExprs = sum(qc.nexprs3), SpikeProp = sum(qc.spike3), MitoProp = sum(qc.mito3), Total = sum(discard3) ) ## DataFrame with 1 row and 5 columns ## LibSize NExprs SpikeProp MitoProp Total ## <integer> <integer> <integer> <integer> <integer> ## 1 5 4 6 2 9 2.12 Visualización gráfica de las células de buena calidad Usaremos el filtro estricto y visualizaremos la distribución de los datos. # Reducir el nombre en los fenotipos / tratamientos sce.416b_edited <- sce.416b sce.416b_edited$phenotype <- ifelse(grepl("induced", sce.416b_edited$phenotype), "induced", "wild type") # Verificar unique(sce.416b_edited$phenotype) ## [1] "wild type" "induced" # Agregar columna de genes descartados sce.416b_edited$discard <- discard # Visualizacion grafica plotColData(sce.416b_edited, x="block", y="sum", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + labs(x = "Bloques de secuenciacion", y="Cuentas totales", title = "Numero de cuentas") # Etiquetas en X, Y y titulo Visualizacion de todas las variables en una sola gráfica. # Visualizacion grafica gridExtra::grid.arrange( plotColData(sce.416b_edited, x="block", y="sum", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + scale_y_log10() + labs(x = "Bloques de secuenciacion", y="Cuentas totales", title = "Numero de cuentas"), # Etiquetas en X, Y y titulo plotColData(sce.416b_edited, x="block", y="detected", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + scale_y_log10() + labs(x = "Bloques de secuenciacion", y="Genes expresados", title = "Numero de genes /n(log)"), # Etiquetas en X, Y y titulo plotColData(sce.416b_edited, x="block", y="subsets_Mito_percent", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + labs(x = "Bloques de secuenciacion", y="Porcentaje de genes mitocondriales /n(%)", title = "Contenido mitocondrial"), # Etiquetas en X, Y y titulo plotColData(sce.416b_edited, x="block", y="altexps_ERCC_percent", colour_by="discard", other_fields="phenotype") + facet_wrap(~phenotype) + labs(x = "Bloques de secuenciacion", y="Porcentaje de ERCC /n(%)", title = "Contenido de ERCC"), # Etiquetas en X, Y y titulo, ncol=1 ) Otra visualización gráfica es: plotColData( sce.416b_edited, x = "sum", y = "subsets_Mito_percent", colour_by = "discard", other_fields = c("block", "phenotype") ) + facet_grid(block ~ phenotype) 2.13 Identificando droplets vacíos con datos de PBMC 2.13.1 Conceptos básicos Descripción gráfica de la tecnología Next GEM de 10x Genomics. Fuente: 10x Genomics. Opciones algorítmicas para detectar los droplets vacíos. Fuente: Lun et al, Genome Biology, 2019. 2.13.2 Información de los datos El dataset proviene de células humanas, con un total de 4,340 células con buena calidad. Para más información consulta la página web en 10Xgenomics. A continuación te presento el reporte de este dataset. Captura del reporte de secuenciación del dataset. 10Xgenomics realiza un alineamiento genómico con STAR y emplea CellRanger para realizar la limpieza y cuantificación de los datos. Encontrado la información dividia en dos carpetas importantes: Gene/cell matrix (raw): Contiene toda la información posterior al alineamiento, sin limpiar. Contiene toda la información, contemplando la presencia de doplets vacíos. Gene/cell matrix (filtered): Contiene los datos filtrados por CellRanger. Dejo a tu consideración la posibilidad de emplear alguno de estos archivos. Ambas carpetas contienen 3 archivos importantes para el análisis de los datos: barcode.tsv = Secuencia que define a cada célula por identificadores de cada célula. feature.tsv = Genes identificadores, se les midió expresión. matrix.mtx = Unión entre las secuencias y genes. 2.13.3 Importar datos en R Almacenaremos la información de 10Xgenomics en la memoria Cache de la computadora y posteriormente lo almacenaremos en una variable. # Datos crudos, sin procesar bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) # Archivos contenidos en Temporales test_dir <- tempdir() test_dir <- paste0(test_dir, "/pbmc4k/raw_gene_bc_matrices/GRCh38") list.files(test_dir) # Encontraremos 3 tipos de archivos: barcodes.tsv, genes.tsv y matrix.mtx ## [1] "barcodes.tsv" "genes.tsv" "matrix.mtx" # Cargar datos fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) # Cargar datos de 10Xgenomics de CellRanger sce.pbmc ## class: SingleCellExperiment ## dim: 33694 737280 ## metadata(1): Samples ## assays(1): counts ## rownames(33694): ENSG00000243485 ENSG00000237613 ... ENSG00000277475 ENSG00000268674 ## rowData names(2): ID Symbol ## colnames(737280): AAACCTGAGAAACCAT-1 AAACCTGAGAAACCGC-1 ... TTTGTCATCTTTAGTC-1 TTTGTCATCTTTCCTC-1 ## colData names(2): Sample Barcode ## reducedDimNames(0): ## mainExpName: NULL ## altExpNames(0): Contiene 737280 droplets, aún sin filtrar y evaluando un total de 33,694 genes en este dataset. Si quisieras descargar estos mismos datos pero filtrados, te dejo la ruta: # Datos filtrados, sin celulas muertas, sin un alto contenido mitocondrial, sin droplets vacios o con multiples celulas bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_filtered_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) 2.13.4 Visualización de droplets vacíos bcrank <- barcodeRanks(counts(sce.pbmc)) bcrank ## DataFrame with 737280 rows and 3 columns ## rank total fitted ## <numeric> <integer> <numeric> ## AAACCTGAGAAACCAT-1 219086 1 NA ## AAACCTGAGAAACCGC-1 504862 0 NA ## AAACCTGAGAAACCTA-1 219086 1 NA ## AAACCTGAGAAACGAG-1 504862 0 NA ## AAACCTGAGAAACGCC-1 219086 1 NA ## ... ... ... ... ## TTTGTCATCTTTACAC-1 150232 2 NA ## TTTGTCATCTTTACGT-1 26415 33 NA ## TTTGTCATCTTTAGGG-1 504862 0 NA ## TTTGTCATCTTTAGTC-1 504862 0 NA ## TTTGTCATCTTTCCTC-1 219086 1 NA # Mostremos solo los puntos únicos para acelerar # el proceso de hacer esta gráfica uniq <- !duplicated(bcrank$rank) plot( bcrank$rank[uniq], bcrank$total[uniq], log = "xy", xlab = "Rank", ylab = "Total UMI count", cex.lab = 1.2) ## Warning in xy.coords(x, y, xlabel, ylabel, log): 1 y value <= 0 omitted from logarithmic plot # Agregarle los puntos de corte abline( h = metadata(bcrank)$inflection, col = "darkgreen", lty = 2) abline( h = metadata(bcrank)$knee, col = "dodgerblue", lty = 2) legend( "bottomleft", legend = c("Inflection", "Knee"), col = c("darkgreen", "dodgerblue"), lty = 2, cex = 1.2) UMI = Secuencia única de cada unión en la bead (unique molecular identifiers). Encontremos los droplets vacíos usando emptyDrops(). Los siguientes pasos demoran un tiempo. ## Usemos DropletUtils para encontrar los droplets set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) # Revisa ?emptyDrops para una explicación de por qué hay valores NA summary(e.out$FDR <= 0.001) ## Mode FALSE TRUE NA's ## logical 1006 4283 731991 set.seed(100) limit <- 100 all.out <- emptyDrops(counts(sce.pbmc), lower = limit, test.ambient = TRUE) # Idealmente, este histograma debería verse uniforme. # Picos grandes cerca de cero indican que los _barcodes_ # con un número total de cuentas menor a "lower" no son # de origen ambiental. hist(all.out$PValue[all.out$Total <= limit & all.out$Total > 0], xlab = "P-value", main = "", col = "grey80") 2.13.5 Anotación de genes y eliminación de doples vacíos # Anotación de los genes rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) ## Warning: Unable to map 144 of 33694 requested IDs. # Detección de _droplets_ con células set.seed(100) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] 2.13.6 Control de calidad # Obtener las estadisticas en un archivo aparte stats <- perCellQCMetrics(sce.pbmc, subsets = list(Mito = which(location == "MT")) ) high.mito <- isOutlier(stats$subsets_Mito_percent, type = "higher" ) # Eliminar secuencias con alto contenido de genes mitocondriales sce.pbmc <- sce.pbmc[, !high.mito] 2.14 Visualización de los datos con ISEE Github de iSEE. Workshop de iSEE 2.15 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:41:55 EDT" proc.time() ## user system elapsed ## 1485.533 117.620 95964.475 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── El dataset cuenta con 192 células, sce.416b↩︎ El dataset cuenta con 46,604 genes detectados, sce.416b↩︎ "],["normalización-de-datos.html", "3 Normalización de datos 3.1 Material 3.2 Motivación 3.3 Datos 3.4 Normalización por escalamiento (scaling normalization) 3.5 Normalización por deconvolución (deconvolution) 3.6 Transformación logarítmica 3.7 Otras normalizaciones 3.8 Dónde estamos 3.9 Adicionales 3.10 Agradecimientos 3.11 Detalles de la sesión de R", " 3 Normalización de datos Instructora: Dra Laura Lucila Gómez Romero 3.1 Material Diapositivas de Peter Hickey: Ve las diapositivas aquí Capítulo de OSCA: Ve el capítulo del libro OSCA aquí 3.2 Motivación Al igual que con otras tecnologías, single-cell RNA-seq (scRNA-seq) puede presentar diferencias sistemáticas en la cobertura de las librerías de scRAN-seq. Típicamente se debe a diferencias técnicas en procesos como la captura de cDNA, la eficiencia de la amplificación por PCR. La normalización tiene como objetivo remover estas diferencias sistemáticas para que no interfieran cuando comparamos los perfiles de expresión entre células. Al normalizar los datos, las diferencias observadas entre poblaciones celulares o condiciones son debido a la biología y no por factores técnicos. La normalización es diferente a la corrección por lote . El proceso de normalización se lleva a cabo sin importar la estructura de los lotes y sólo considera sesgos técnicos, los cuales tienden a afectar los genes en una manera medianamente similar, por ejemplo: la eficiencia de la amplificación por PCR debido al contenido de GC o la longitud del gene. ¿Qué es correción por lote (batch effect correction)? Da un ejemplo. “Large single-cell RNA sequencing (scRNA-seq) projects usually need to generate data across multiple batches due to logistical constraints. However, the processing of different batches is often subject to uncontrollable differences, e.g., changes in operator, differences in reagent quality. This results in systematic differences in the observed expression in cells from different batches, which we refer to as “batch effects”. Batch effects are problematic as they can be major drivers of heterogeneity in the data, masking the relevant biological differences and complicating interpretation of the results” -OSCA ¿Cuáles son las diferencias entre correción por lote y normalización? “Normalization occurs regardless of the batch structure and only considers technical biases, while batch correction - as the name suggests - only occurs across batches and must consider both technical biases and biological differences. Technical biases tend to affect genes in a similar manner, or at least in a manner related to their biophysical properties (e.g., length, GC content), while biological differences between batches can be highly unpredictable” -OSCA 3.3 Datos Usaremos el dataset de Zeisel. Tipos celulares en cerebro de ratón (oligodendrocitos, microglias, neuronas, etc.) Procesado con STRT-seq (similar a CEL-seq), un sistema de microfluido. 3005 células y 18441 genes. Contiene UMIs. library("scRNAseq") sce.zeisel <- ZeiselBrainData(ensembl = TRUE) sce.zeisel ## class: SingleCellExperiment ## dim: 18441 3005 ## metadata(0): ## assays(1): counts ## rownames(18441): ENSMUSG00000029669 ENSMUSG00000046982 ... ENSMUSG00000064337 ENSMUSG00000065947 ## rowData names(2): featureType originalName ## colnames(3005): 1772071015_C02 1772071017_G12 ... 1772066098_A12 1772058148_F03 ## colData names(10): tissue group # ... level1class level2class ## reducedDimNames(0): ## mainExpName: endogenous ## altExpNames(2): ERCC repeat 3.3.1 Primero se debe hacer el control de calidad Eliminando células de baja calidad: Outliers bajos para log(cuenta total) Outliers bajos para log(número de features detectados) Outliers altos para el porcentaje de cuentas de conjuntos de genes especificados (mitocondriales, transcritos spike-in) # Control de calidad library("scater") unfiltered <- sce.zeisel is.mito <- which(rowData(sce.zeisel)$featureType == "mito") stats <- perCellQCMetrics(sce.zeisel, subsets = list(Mt = is.mito)) qc <- quickPerCellQC(stats, percent_subsets = c("altexps_ERCC_percent", "subsets_Mt_percent") ) colSums(as.data.frame(qc)) ## low_lib_size low_n_features high_altexps_ERCC_percent high_subsets_Mt_percent ## 0 3 66 128 ## discard ## 190 sce.zeisel <- sce.zeisel[, !qc$discard] 3.4 Normalización por escalamiento (scaling normalization) La normalización por escalamiento es la estrategia más simple y usada. Suposición: Cualquier sesgo específico en cada célula afecta a todos los genes de igual manera a través de escalar por el promedio esperado de cuentas para dicha célula. Se realiza de la siguiente manera: Estima un “size factor” para cada célula. Este factor representa el sesgo relativo en esa célula. Divide las cuentas de los genes de cada célula entre su correspondiente “size factor”. \\[ CuentasNormalizadas = Cuentas / Size factor\\] Los valores de expresión normalizados pueden ser usados por análisis posteriores como clustering o reducción de dimensiones. 3.4.1 Normalizacion por tamaño de biblioteca (Library Size normalization) Tamaño de biblioteca (Library Size): La suma total de las cuentas a tráves de todos los genes en una célula. Asumimos que este valor escala con cualquier sesgo específico en cada célula. \\[Library Size_{cell} = \\sum_{n=1}^{j} gene\\] Donde \\(j\\) es el número total de genes y \\(gene\\) es el número de cuentas por gen en la célula \\(cell\\). Para escalar los datos ocuparemos un factor de escalamiento llamado Library Size factor. Este valor se calcula a partir de escalar el tamaño de la biblioteca, tal que el promedio de los Library Size factor en todas las células sea igual a 1. \\[ mean(Library Size factor) = 1 \\] Lo que nos permite que los valores normalizados están en la misma escala y pueden ser útiles para la interpretación. # Estimar factores de normalización lib.sf.zeisel <- librarySizeFactors(sce.zeisel) # Examina la distribución de los tamaños de librerías # que acabamos de estimar summary(lib.sf.zeisel) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0.1754 0.5682 0.8669 1.0000 1.2758 4.0651 hist(log10(lib.sf.zeisel), xlab = "Log10[Library Size factor]", col = "grey80") ¿A qué crees que se deba la variación en los factores de escalamiento? ## Calculando el tamaño de las librerias ls.zeisel <- colSums(counts(sce.zeisel)) plot(ls.zeisel, lib.sf.zeisel, log="xy", xlab="Library size", ylab="Size factor") 3.4.2 Puntos finales La normalización por tamaño de biblioteca asume que no hay un sesgo de composición, es decir, si existe un grupo de genes cuya expresión aumenta entonces debe existir otro grupo de genes para los que la expresión disminuye en la misma magnitud, esto generalmente no es verdad para los experimentos de scRNA-seq. Para algunos análisis exploratorios, la precisión de la normalización no es un punto mayor a considerar. La normalizacion por tamaño de biblioteca suele ser suficiente en algunas ocasiones donde se busca identificar clusters y los marcadores de los clusters, dado que el sesgo por composición normalmente no afecta la separación de los clusters, sólo la magnitud. Sin embargo, esta falta de precisión podría afectar cuando se busca obtener estimaciones y estadísticas a nivel de genes individuales. 3.5 Normalización por deconvolución (deconvolution) El problema causado por el sesgo de composición y cómo eliminarlo ha sido estudiado en bulk RNA-seq por métodos como DESeq2::estimateSizeFactorsFromMatrix() y edgeR::calcNormFactors(). En ambos casos, se asume que la mayoría de genes no estarán diferencialmente expresados entre las muestras (en nuestro caso células) y cualquier diferencia entre los genes no diferencialmente expresados representa un sesgo el cual se remueve utilzando el factor de normalización calculado. Sin embargo, en single-cell RNA-seq se tienen muchas cuentas bajas y ceros debido a limitaciones en la tecnología, las cuales no necesariamente indican ausencia de expresión. Para este fenómento no están preparados los métodos utilizados en bulk RNA-seq. La normalización por deconvolución (o normalización scran): Junta las cuentas de varias células (pool) para incrementar el tamaño de las cuentas, reduciendo ceros y cuentas bajas. Aplica los métodos de normalización que corrigen el sesgo de composición. Repiten esto para conjuntos sobrelapantes de células para obtener size factors en pool. Deconvoluciona estos size factors en pool para obtener size factors para cada célula. # Normalización por deconvolución (deconvolution) library("scran") # Pre-clustering (establece una semilla para obtener resultados reproducibles) set.seed(100) clust.zeisel <- quickCluster(sce.zeisel) # Calcula factores de tamaño para la deconvolución (deconvolution) deconv.sf.zeisel <- calculateSumFactors(sce.zeisel, clusters = clust.zeisel, min.mean = 0.1) El pre-clustering mejora la estimación de los size factors al normalizar células similares juntas. # Examina la distribución de los factores de tamaño summary(deconv.sf.zeisel) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0.1282 0.4859 0.8248 1.0000 1.3194 4.6521 hist(log10(deconv.sf.zeisel), xlab = "Log10[Deconvolution size factor]", col = "grey80" ) plot(lib.sf.zeisel, deconv.sf.zeisel, xlab = "Library size factor", ylab = "Deconvolution size factor", log = "xy", pch = 16, col=as.integer(factor(sce.zeisel$level1class)) ) abline(a = 0, b = 1, col = "red") 3.5.1 Puntos finales La normalización por deconvolución (deconvolution) mejora los resultados para análisis posteriores de una manera más precisa que los métodos para bulk RNA-seq. El método scran::calculateSumFactors algunas veces calcula factores negativos o ceros lo cual altera la matriz de expresión normalizada. ¡Checa los factores que calculas! Si obtienes factores negativos intenta variar el número de clusters. summary(deconv.sf.zeisel) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0.1282 0.4859 0.8248 1.0000 1.3194 4.6521 3.6 Transformación logarítmica Una vez calculados los factores de normalización con computeSumFactors(), podemos calcular las cuentas en escala logarítmica usando logNormCounts(). ¿Qué es lo que hace esta función? Divide las cuentas de cada gene por el size factor correspondiente para esa célula (estos serían los valores normalizados) y entonces le aplica una transformción logarítmica a estos valores normalizados. Típicamente agrega una pseudo-cuenta de 1 para evitar calcular log(0). Estas cuentas en escala log se conocen como: valores de expresión normalizados en escala logarítmica (log-transformed normalized expression values). sce.zeisel ## class: SingleCellExperiment ## dim: 18441 2815 ## metadata(0): ## assays(1): counts ## rownames(18441): ENSMUSG00000029669 ENSMUSG00000046982 ... ENSMUSG00000064337 ENSMUSG00000065947 ## rowData names(2): featureType originalName ## colnames(2815): 1772071015_C02 1772071017_G12 ... 1772063068_D01 1772066098_A12 ## colData names(10): tissue group # ... level1class level2class ## reducedDimNames(0): ## mainExpName: endogenous ## altExpNames(2): ERCC repeat # Normalization # Esto agrega el "sizeFactor" como parte del objeto # set.seed(100) # clust.zeisel <- quickCluster(sce.zeisel) sce.zeisel <- computeSumFactors(sce.zeisel, cluster=clust.zeisel, min.mean=0.1) sce.zeisel ## class: SingleCellExperiment ## dim: 18441 2815 ## metadata(0): ## assays(1): counts ## rownames(18441): ENSMUSG00000029669 ENSMUSG00000046982 ... ENSMUSG00000064337 ENSMUSG00000065947 ## rowData names(2): featureType originalName ## colnames(2815): 1772071015_C02 1772071017_G12 ... 1772063068_D01 1772066098_A12 ## colData names(11): tissue group # ... level2class sizeFactor ## reducedDimNames(0): ## mainExpName: endogenous ## altExpNames(2): ERCC repeat # Log transformation sce.zeisel <- scater::logNormCounts(sce.zeisel) assayNames(sce.zeisel) ## [1] "counts" "logcounts" 3.6.1 Motivación, ¿Por qué hacemos esta transformación? ¿Qué gen es más interesante? Gen X: el promedio de expresión en el tipo celular A: 50 y B: 10 Gen Y: el promedio de expresión en el tipo celular A: 1100 y B: 1000 50 - 10 ## [1] 40 1100 - 1000 ## [1] 100 log(50) - log(10) ## [1] 1.609438 log(1100) - log(1000) ## [1] 0.09531018 Exacto, Gen X 3.6.2 Lluvia de ideas ¿Qué pasa cuando hacemos la transformación logarítmica? ¿Qué es una pseudo-cuenta? ¿Por qué se usa? ¿Qué valor de pseudo-cuenta usa logNormCounts()? 3.7 Otras normalizaciones Te invitamos a leer más sobre otras formas de normalizar, para empezar puedes consultar el siguiente curso del Sanger Institute. Si estas interesad@ en diferencias en el contenido total de RNA en cada célula, checa la normalización por spike-ins. La cual asume que los spike-ins fueron añadidos en un nivel constante en cada célula. Si tienes resultados donde el library size está asociado a tus datos a pesar de haber normalizado, checa la opción de downsample=TRUE dentro de la función de logNormCounts(). Si te gustaría tener factores de normalización específicos para cada gen que tomen en cuenta la varianza, checa las funciones varianceStabilizingTransformation() de DESeq2 o sctransform de Seurat. 3.8 Dónde estamos 3.9 Adicionales [1] 2018 BioInfoSummer Workshop [2] HBC training 3.10 Agradecimientos Este curso está basado en el libro Orchestrating Single Cell Analysis with Bioconductor de Aaron Lun, Robert Amezquita, Stephanie Hicks y Raphael Gottardo, además del curso de scRNA-seq para WEHI creado por Peter Hickey. Y en el material de la comunidadbioinfo/cdsb2020 con el permiso de Leonardo Collado-Torres. 3.11 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:42:24 EDT" proc.time() ## user system elapsed ## 1511.348 119.377 95994.018 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── "],["selección-de-genes-altamente-variables.html", "4 Selección de genes altamente variables 4.1 Diapositivas de Peter Hickey 4.2 Motivación 4.3 Selección de features (genes) 4.4 Dataset ilustrativo: PBMC4k 10X sin filtrar 4.5 Dataset ilustrativo: 416B 4.6 Cuantificando la varianza por gen 4.7 Coeficiente de variación de las cuentas 4.8 Varianza de los log-counts vs coeficiente de variación 4.9 Cuantificando el ruido técnico 4.10 En la ausencia de spike-ins 4.11 Recordemos propiedades de los datos de sce.416b 4.12 Considerando factores experimentales 4.13 Seleccionando genes altamante variables (high-variable genes, HVGs) 4.14 Poniendo todo junto 4.15 Resumen y recomendaciones 4.16 Recomendaciones para empezar 4.17 Detalles de la sesión de R", " 4 Selección de genes altamente variables José Antonio Ovando 08 de agosto de 2023 4.1 Diapositivas de Peter Hickey Ver las diapositivas originales aquí 4.2 Motivación Usualmente usamos datos scRNA-seq para caracterizar la heterogeneidad entre células Para hacer esto, usamos métodos como el clustering y la reducción de dimensionalidad Esto involucra resumir las diferencias por gen en una sola medida de (dis)similitud entre un par de células ¿Cuáles genes deberíamos usar para calcular esta medida de (dis)similitud? 4.3 Selección de features (genes) La elección de los features tiene un mayor impacto en qué tan similares decidimos que son las células ➕ Features que contienen información útil biológica ➖ Features que contienen ruido aleatorio 👉 Efectos laterales al reducir la dimensionalidad de los datos Deseamos seleccionar los genes altamente variables (High Variable Genes HVGs). Genes con una variación incrementada en comparación con otros genes que están siendo afectados por ruido técnico u otra variación biológica que no es de nuestro interés. 4.4 Dataset ilustrativo: PBMC4k 10X sin filtrar 4.4.1 Descargar datos # Usemos datos de pbmc4k library(BiocFileCache) bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) library(DropletUtils) library(Matrix) fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) sce.pbmc ## class: SingleCellExperiment ## dim: 33694 737280 ## metadata(1): Samples ## assays(1): counts ## rownames(33694): ENSG00000243485 ENSG00000237613 ... ENSG00000277475 ENSG00000268674 ## rowData names(2): ID Symbol ## colnames(737280): AAACCTGAGAAACCAT-1 AAACCTGAGAAACCGC-1 ... TTTGTCATCTTTAGTC-1 TTTGTCATCTTTCCTC-1 ## colData names(2): Sample Barcode ## reducedDimNames(0): ## mainExpName: NULL ## altExpNames(0): Dataset “Células mononucleares humanas de sangre periférica” de 10X Genomics Descripción aquí 3 4.4.2 Anotación # Anotación de los genes library(scater) rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) library(EnsDb.Hsapiens.v86) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) # Detección de _droplets_ con células set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] 4.4.3 Control de calidad # Control de calidad stats <- perCellQCMetrics(sce.pbmc, subsets = list(Mito = which(location == "MT")) ) high.mito <- isOutlier(stats$subsets_Mito_percent, type = "higher" ) sce.pbmc <- sce.pbmc[, !high.mito] # Normalización de los datos library(scran) set.seed(1000) clusters <- quickCluster(sce.pbmc) sce.pbmc <- computeSumFactors(sce.pbmc, cluster = clusters) sce.pbmc <- logNormCounts(sce.pbmc) 4.5 Dataset ilustrativo: 416B library(scRNAseq) sce.416b <- LunSpikeInData(which = "416b") sce.416b$block <- factor(sce.416b$block) Línea celular de células mieloides progenitoras inmortalizadas de ratón usando SmartSeq2 https://osca.bioconductor.org/lun-416b-cell-line-smart-seq2.html 4 # gene-annotation library(AnnotationHub) ens.mm.v97 <- AnnotationHub()[["AH73905"]] rowData(sce.416b)$ENSEMBL <- rownames(sce.416b) rowData(sce.416b)$SYMBOL <- mapIds(ens.mm.v97, keys = rownames(sce.416b), keytype = "GENEID", column = "SYMBOL" ) rowData(sce.416b)$SEQNAME <- mapIds(ens.mm.v97, keys = rownames(sce.416b), keytype = "GENEID", column = "SEQNAME" ) library(scater) rownames(sce.416b) <- uniquifyFeatureNames( rowData(sce.416b)$ENSEMBL, rowData(sce.416b)$SYMBOL ) # quality-control mito <- which(rowData(sce.416b)$SEQNAME == "MT") stats <- perCellQCMetrics(sce.416b, subsets = list(Mt = mito)) qc <- quickPerCellQC(stats, percent_subsets = c("subsets_Mt_percent", "altexps_ERCC_percent"), batch = sce.416b$block ) sce.416b <- sce.416b[, !qc$discard] # normalization library(scran) sce.416b <- computeSumFactors(sce.416b) sce.416b <- logNormCounts(sce.416b) 4.6 Cuantificando la varianza por gen 4.6.1 Varianza de los log-counts El enfoque más simple para cuantificar la variación per-feature es simplemente calcular la varianza de los log-counts ➕ Selección del feature basado en los log-counts (que serán usadas en los análisis más adelante) ⚠️ La transformación log no logra la estabilización de la varianza perfecta, así que se requiere modelar la relación de la varianza-media de los features. 4.6.2 Enfoque simple Calcular la varianza de los log-counts para cada gen (ignorando grupos experimentales) Ordenar los genes del más-al-menos variable 4.6.3 Un enfoque más sofisticado Calcular la varianza de los log-counts para cada gen (ignorando grupos experimentales) Modelar la relación entre la media y la varianza de los log-counts para estimar la variación técnica Estimar la varianza biológica sustrayendo la varianza técnica de la varianza total Ordenar los genes de la variable de mayor-a-menor biológicamente 4.6.4 Supuestos # Varianza de las log-counts library(scran) dec.pbmc <- modelGeneVar(sce.pbmc) 🤓 El supuesto es que a cualquier abundancia dada, la abundancia de los perfiles de expresión de la mayoría de los genes están dominados por el ruido aleatorio técnico 🤓 Por lo consiguiente, una tendencia representa un estimado del ruido técnico como una función de la abundancia 🤓 Podemos entonces descomponer la varianza total de cada gen en un componente técnico y uno biológico 🤓 Genes con una gran varianza biológica son considerados interesantes 4.6.5 Visualizando la media y varianza # Visualicemos la relación entre la media y la varianza fit.pbmc <- metadata(dec.pbmc) plot(fit.pbmc$mean, fit.pbmc$var, xlab = "Mean of log-expression", ylab = "Variance of log-expression" ) curve(fit.pbmc$trend(x), col = "dodgerblue", add = TRUE, lwd = 2) 4.6.6 Ordenando genes interesantes # Ordenemos por los genes más interesantes para checar # los datos dec.pbmc[order(dec.pbmc$bio, decreasing = TRUE), ] ## DataFrame with 33694 rows and 6 columns ## mean total tech bio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## LYZ 1.94129 4.99949 0.824172 4.17532 1.44008e-250 2.83205e-246 ## S100A9 1.92243 4.48842 0.824008 3.66441 1.25315e-193 6.16112e-190 ## S100A8 1.68566 4.35303 0.814526 3.53850 6.89502e-185 2.71195e-181 ## HLA-DRA 2.09063 3.73576 0.819396 2.91636 7.27124e-125 1.19164e-121 ## CD74 2.90080 3.34898 0.786799 2.56218 6.72905e-105 6.96492e-102 ## ... ... ... ... ... ... ... ## PTMA 3.83144 0.474774 0.733464 -0.258690 0.990672 1 ## HLA-B 4.49970 0.479899 0.748285 -0.268386 0.991626 1 ## EIF1 3.23434 0.471616 0.766366 -0.294750 0.994844 1 ## TMSB4X 6.07476 0.408677 0.719095 -0.310419 0.998006 1 ## B2M 5.94601 0.311508 0.690710 -0.379202 0.999875 1 4.7 Coeficiente de variación de las cuentas El coeficiente de variación de las cuentas al cuadrado (CV2) es una alternativa a la varianza de los log-counts 👉 Se calcula usando las cuentas en lugar de los log-counts 🤓 CV es el ratio de la desviación estándar a la media y está muy relacionada con el parámetro de dispersión de la distribución binomial negativa usada en edgeR y DESeq2 4.7.1 Coeficiente de variación # Coeficiente de variación dec.cv2.pbmc <- modelGeneCV2(sce.pbmc) 🤓 Modela la relación de la media de la varianza cuando se considera la relevancia de cada gen 🤓 Asume que la mayoría de los genes contienen ruido aleatorio y que la tendencia captura la mayoría de la variación técnica 🤓 Genes con un gran CV2 que se desvían fuertemente de la tendencia es probable que representen genes afectados por la estructura biológica 🤓 Usa la tasa (en lugar de la diferencia) del CV2 a la tendencia 4.7.2 Visualizando el coeficiente de variación # Visualicemos la relación con la media fit.cv2.pbmc <- metadata(dec.cv2.pbmc) plot(fit.cv2.pbmc$mean, fit.cv2.pbmc$cv2, log = "xy" ) curve(fit.cv2.pbmc$trend(x), col = "dodgerblue", add = TRUE, lwd = 2 ) 4.7.3 Genes por coeficiente de variación # Ordenemos por los genes más interesantes para checar # los datos dec.cv2.pbmc[order(dec.cv2.pbmc$ratio, decreasing = TRUE ), ] ## DataFrame with 33694 rows and 6 columns ## mean total trend ratio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## GNG11 1.0300722 694.193 1.39084 499.117 0 0 ## PTK7 0.0710992 3664.385 17.32128 211.554 0 0 ## RNF208 0.0721694 3558.419 17.06755 208.490 0 0 ## TUBA8 0.0723199 3544.014 17.03246 208.074 0 0 ## ARHGAP6 0.0777368 3074.612 15.86022 193.857 0 0 ## ... ... ... ... ... ... ... ## AC023491.2 0 NaN Inf NaN NaN NaN ## AC233755.2 0 NaN Inf NaN NaN NaN ## AC233755.1 0 NaN Inf NaN NaN NaN ## AC213203.1 0 NaN Inf NaN NaN NaN ## FAM231B 0 NaN Inf NaN NaN NaN 4.8 Varianza de los log-counts vs coeficiente de variación Generalmente se usa la varianza de los log-counts Ambas son medidas efectivas para cuantificar la variación en la expresión génica CV2 tiende a tener otorgar rangos altos a genes altamente variables (HGVs) con bajos niveles de expresión Éstos son dirigidos por una sobreregulación en subpoblaciones raras Puede asignar un alto rango a genes que no son de nuestro interés con varianza baja absoluta La variación descrita por el CV2 de las cuentas es menos relevante para los procedimientos que operan en los log-counts 4.9 Cuantificando el ruido técnico Previamente, ajustamos una línea de tendencia a todos los genes endógenos y asumimos que la mayoría de los genes no están dominados por ruido técnico En la práctica, todos los genes expresados tienen algún nivel de variabilidad biológica diferente de cero (e.g., transcriptional bursting) Esto sugiere que nuestros estimados de los componentes técnicos estarán inflados probablemente 👉 Es mejor que pensemos estos estimados como una variación técnica más la variación biológica que no es interesante 🤔 Pero que tal si un grupo de genes a una abundancia particular es afectado por un proceso biológico? E.g., fuerte sobre regulación de genes específicos de un tipo celular podrían conllevar a un enriquecimiento de HVGs en abundancias altas. Esto inflaría la tendencia y compromete la detección de los genes relevantes ¿Cómo podemos evitar este problema? Podemos revisar dos enfoques: Cuando tenemos spike-ins Cuando no tenemos spike-ins 4.9.1 En la presencia de spike-ins dec.spike.416b <- modelGeneVarWithSpikes( sce.416b, "ERCC" ) # Ordering by most interesting genes for # inspection. dec.spike.416b[order(dec.spike.416b$bio, decreasing = TRUE ), ] ## DataFrame with 46604 rows and 6 columns ## mean total tech bio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## Lyz2 6.61097 13.8497 1.57131 12.2784 1.48993e-186 1.54156e-183 ## Ccl9 6.67846 13.1869 1.50035 11.6866 2.21855e-185 2.19979e-182 ## Top2a 5.81024 14.1787 2.54776 11.6310 3.80015e-65 1.13040e-62 ## Cd200r3 4.83180 15.5613 4.22984 11.3314 9.46221e-24 6.08573e-22 ## Ccnb2 5.97776 13.1393 2.30177 10.8375 3.68706e-69 1.20193e-66 ## ... ... ... ... ... ... ... ## Rpl5-ps2 3.60625 0.612623 6.32853 -5.71590 0.999616 0.999726 ## Gm11942 3.38768 0.798570 6.51473 -5.71616 0.999459 0.999726 ## Gm12816 2.91276 0.838670 6.57364 -5.73497 0.999422 0.999726 ## Gm13623 2.72844 0.708071 6.45448 -5.74641 0.999544 0.999726 ## Rps12l1 3.15420 0.746615 6.59332 -5.84670 0.999522 0.999726 👉 Ajusta la tendencia solo con los spike-ins (que deberían estar afectados solamente por variación técnica) plot(dec.spike.416b$mean, dec.spike.416b$total, xlab = "Mean of log-expression", ylab = "Variance of log-expression" ) fit.spike.416b <- metadata(dec.spike.416b) points(fit.spike.416b$mean, fit.spike.416b$var, col = "red", pch = 16 ) curve(fit.spike.416b$trend(x), col = "dodgerblue", add = TRUE, lwd = 2 ) 4.10 En la ausencia de spike-ins set.seed(0010101) dec.pois.pbmc <- modelGeneVarByPoisson(sce.pbmc) # Ordering by most interesting genes for inspection. dec.pois.pbmc[order(dec.pois.pbmc$bio, decreasing = TRUE), ] ## DataFrame with 33694 rows and 6 columns ## mean total tech bio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## LYZ 1.94129 4.99949 0.625290 4.37420 0 0 ## S100A9 1.92243 4.48842 0.628977 3.85944 0 0 ## S100A8 1.68566 4.35303 0.669965 3.68307 0 0 ## HLA-DRA 2.09063 3.73576 0.594291 3.14146 0 0 ## CD74 2.90080 3.34898 0.418950 2.93003 0 0 ## ... ... ... ... ... ... ... ## COX6A1 0.905824 0.579594 0.633121 -0.0535269 0.883561 0.968946 ## NEDD8 0.842764 0.558542 0.612707 -0.0541655 0.893881 0.978680 ## NDUFA1 0.863339 0.557910 0.619832 -0.0619222 0.920683 1.000000 ## SAP18 0.766806 0.515749 0.582464 -0.0667157 0.946979 1.000000 ## SUMO2 1.362264 0.612538 0.694805 -0.0822664 0.952613 1.000000 👉 Realiza algunas asunciones estadísticas acerca del ruido 🤓 Las cuentas UMI típicamente muestran una variación cercana a Poisson si solo consideramos ruido técnico de la preparación de las librerías y la secuenciación ⚠️ modelGeneVarByPoisson() realiza simulaciones, por lo que necesitamos “ajustar la “semilla” para obtener resultados reproducibles 🤓 modelGeneVarByPoisson() pueden también simular una variación binomial negativa (variación de Poisson sobredispersada) plot(dec.pois.pbmc$mean, dec.pois.pbmc$total, pch = 16, xlab = "Mean of log-expression", ylab = "Variance of log-expression" ) curve(metadata(dec.pois.pbmc)$trend(x), col = "dodgerblue", add = TRUE ) 🤓 La línea de tendencia basada puramente en ruido técnico tiende a producir componentes “biológicos” más grandes por los genes altamente expresados, que frecuentemente incluyen los genes “house-keeping” 🤔 Necesitas considerar si tales genes son “interesantes” o no en tu dataset de interés 4.11 Recordemos propiedades de los datos de sce.416b Este dataset consiste de células de una línea celular de células inmortalizadas mieloides progenitoras de ratón utilizando SmartSeq2 Una cantidad constante de spike-in ERCC RNA se agregó a cada lisado celular antes de la prepatación de la librería Descripción aquí Lun, A. T. L., Calero-Nieto, F. J., Haim-Vilmovsky, L., Göttgens, B. & Marioni, J. C. Assessing the reliability of spike-in normalization for analyses of single-cell RNA sequencing data. Genome Res. 27, 1795–1806 (2017) 4.12 Considerando factores experimentales Los datos que contienen múltiples batches muy seguido presentan efecto de bloque que pueden crear HGVs artificiales Se debe identificar los HGVs en cada batch y combinarlos en una única lista de HGVs # calculando la variacion por bloque dec.block.416b <- modelGeneVarWithSpikes(sce.416b, "ERCC", block = sce.416b$block ) dec.block.416b[order( dec.block.416b$bio, decreasing = TRUE ), ] ## DataFrame with 46604 rows and 7 columns ## mean total tech bio p.value FDR ## <numeric> <numeric> <numeric> <numeric> <numeric> <numeric> ## Lyz2 6.61235 13.8619 1.58416 12.2777 0.00000e+00 0.00000e+00 ## Ccl9 6.67841 13.2599 1.44553 11.8143 0.00000e+00 0.00000e+00 ## Top2a 5.81275 14.0192 2.74571 11.2734 3.89855e-137 8.43398e-135 ## Cd200r3 4.83305 15.5909 4.31892 11.2719 1.17783e-54 7.00721e-53 ## Ccnb2 5.97999 13.0256 2.46647 10.5591 1.20380e-151 2.98405e-149 ## ... ... ... ... ... ... ... ## Gm12816 2.91299 0.842574 6.67730 -5.83472 0.999989 0.999999 ## Gm5786 2.90717 0.879485 6.71686 -5.83738 0.999994 0.999999 ## Rpl9-ps4 3.26421 0.807057 6.64932 -5.84226 0.999988 0.999999 ## Gm13623 2.72788 0.700296 6.63875 -5.93845 0.999998 0.999999 ## Rps12l1 3.15425 0.750775 6.70033 -5.94955 0.999995 0.999999 ## per.block ## <DataFrame> ## Lyz2 6.35652:13.3748:2.08227:...:6.86819:14.3490:1.08605:... ## Ccl9 6.68726:13.0778:1.65923:...:6.66956:13.4420:1.23184:... ## Top2a 5.34891:17.5972:3.91642:...:6.27659:10.4411:1.57501:... ## Cd200r3 4.60115:15.7870:5.55587:...:5.06496:15.3948:3.08197:... ## Ccnb2 5.56701:15.4150:3.46931:...:6.39298:10.6362:1.46362:... ## ... ... ## Gm12816 2.86995:0.624143:7.43036:...:2.95604:1.061004:5.92424:... ## Gm5786 2.96006:0.902872:7.49911:...:2.85427:0.856098:5.93462:... ## Rpl9-ps4 3.60690:0.543276:7.36805:...:2.92151:1.070839:5.93058:... ## Gm13623 2.83129:0.852901:7.39442:...:2.62447:0.547692:5.88308:... ## Rps12l1 3.14399:0.716670:7.57246:...:3.16452:0.784881:5.82819:... Al calcular tendencias específicas por batch se tomarán en cuenta las diferencias en la relación media-varianza entre batches Se deben obtener estimados de los componentes biológico y técnico para cada gene específicos de cada batch, los cuales se promedian entre los batches para crear una única lista de HVGs 4.13 Seleccionando genes altamante variables (high-variable genes, HVGs) Hasta ahora hemos ordenado los genes del más al menos interesantemente variable ¿Qué tanto debemos de bajar en la lista para seleccionar nuestros HVGs? Para responder esta pregunta debemos tomar en cuenta lo siguiente: elegir un subset más grande: Reduce el riesgo de desechar señal biológica Incrementa el ruido por la inclusión de genes irrelevantes Es difícil determinar el balance óptimo porque el rudio en un contexto podría ser una señal útil en otro contexto Discutiremos algunas estrategias para seleccionar HVGs 4.13.1 Seleccionando HVGs sobre la métrica de varianza La estrategia más simple es seleccionar los top-X genes con los valores más grandes para la métrica relevante de varianza, por ejemplo, la varianza biológica más grande calculada con scran::modelGeneVar() Pro: El usuario puede controlar directamente el número de HVGs Contra: ¿Qué valor de X se debe usar? # Works with modelGeneVar() output hvg.pbmc.var <- getTopHVGs(dec.pbmc, n = 1000) str(hvg.pbmc.var) ## chr [1:1000] "LYZ" "S100A9" "S100A8" "HLA-DRA" "CD74" "CST3" "TYROBP" "IGKC" "CCL5" "S100A4" "HLA-DRB1" "NKG7" ... # Works with modelGeneVarWithSpikes() output hvg.416b.var <- getTopHVGs(dec.spike.416b, n = 1000) str(hvg.416b.var) ## chr [1:1000] "Lyz2" "Ccl9" "Top2a" "Cd200r3" "Ccnb2" "Gm10736" "Hbb-bt" "Mcm5" "Cenpa" "Birc5" "Cd200r4" "Mcm6" ... # Also works with modelGeneCV2() but note `var.field` hvg.pbmc.cv2 <- getTopHVGs(dec.cv2.pbmc, var.field = "ratio", n = 1000 ) str(hvg.pbmc.cv2) ## chr [1:1000] "GNG11" "PTK7" "RNF208" "TUBA8" "ARHGAP6" "PDZK1IP1" "CTB-55O6.8" "NDST2" "GUCY1B3" "MAP1LC3A" "HYI" ... 4.13.1.1 Estrategias para seleccionar X Asume que, por ejemplo, no más del 5% de los genes están diferencialmente expresados entre las células de nuestra población: Establece X como el 5% de los genes Normalmente no conocemos el número de genes diferencialmente expresados desde antes, por lo tanto, solo hemos cambiado un número arbitrario por otro número arbitrario RECOMENDACIÓN: Si decides utilizar los top-X HGVs, elige un valor de X y procede con el resto del análisis con la intención de regresar más adelante y probar otros valores, en vez de dedicarle mucho esfuerzo a encontrar el valor óptimo 4.13.2 Seleccionando HVGs de acuerdo a su significancia estadística Establece un límite fijo en alguna métrica de significancia estadística. Por ejemplo: algunos de los métodos reportan un p-valor para cada gene, entonces selecciona todos los genes con un p-valor ajustado menor que 0.05 Recuerda que las pruebas estadísticas siempre dependen del tamaño de la muestra Ventajas: * Fácil de implementar * Menos predecible que la estrategia de los top-X Desventajas: * Podría priorizar genes con significancia estadística fuerte en vez de significancia biológica fuerte # Works with modelGeneVar() output hvg.pbmc.var.2 <- getTopHVGs(dec.pbmc, fdr.threshold = 0.05) str(hvg.pbmc.var.2) ## chr [1:629] "LYZ" "S100A9" "S100A8" "HLA-DRA" "CD74" "CST3" "TYROBP" "IGKC" "CCL5" "S100A4" "HLA-DRB1" "NKG7" ... # Works with modelGeneVarWithSpikes() output hvg.416b.var.2 <- getTopHVGs(dec.spike.416b, fdr.threshold = 0.05 ) str(hvg.416b.var.2) ## chr [1:2568] "Lyz2" "Ccl9" "Top2a" "Cd200r3" "Ccnb2" "Gm10736" "Hbb-bt" "Mcm5" "Cenpa" "Birc5" "Cd200r4" "Mcm6" ... # Also works with modelGeneCV2() but note `var.field` hvg.pbmc.cv2.2 <- getTopHVGs(dec.cv2.pbmc, var.field = "ratio", fdr.threshold = 0.05 ) str(hvg.pbmc.cv2.2) ## chr [1:1706] "GNG11" "PTK7" "RNF208" "TUBA8" "ARHGAP6" "PDZK1IP1" "CTB-55O6.8" "NDST2" "GUCY1B3" "MAP1LC3A" "HYI" ... 4.13.3 Seleccionando genes por arriba de la tendencia media-varianza Selecciona todos los genes con una varianza biológica positiva Este es un extremo del equilibrio sesgo-varianza que minimiza el sesgo con el costo de maximizar el ruido Si seguimos esta aproximación, estamos: Dándole a la estructura secundaria de la población una oportunidad de manifestarse Capturando más ruido, lo cual puede reducir la resolución de poblaciones bien separadas enmascarando la señal secundaria que intentamos preservar Funciona mejor si tenemos datasets altamente heterogeneos que contienen muchos tipos celulares diferentes # Works with modelGeneVar() output hvg.pbmc.var.3 <- getTopHVGs(dec.pbmc, var.threshold = 0) str(hvg.pbmc.var.3) ## chr [1:12852] "LYZ" "S100A9" "S100A8" "HLA-DRA" "CD74" "CST3" "TYROBP" "IGKC" "CCL5" "S100A4" "HLA-DRB1" "NKG7" ... # Works with modelGeneVarWithSpikes() output hvg.416b.var.3 <- getTopHVGs(dec.spike.416b, var.threshold = 0 ) str(hvg.416b.var.3) ## chr [1:11087] "Lyz2" "Ccl9" "Top2a" "Cd200r3" "Ccnb2" "Gm10736" "Hbb-bt" "Mcm5" "Cenpa" "Birc5" "Cd200r4" "Mcm6" ... # Also works with modelGeneCV2() but note `var.field` and # value of `var.threshold` hvg.pbmc.cv2.3 <- getTopHVGs(dec.cv2.pbmc, var.field = "ratio", var.threshold = 1 ) str(hvg.pbmc.cv2.2) ## chr [1:1706] "GNG11" "PTK7" "RNF208" "TUBA8" "ARHGAP6" "PDZK1IP1" "CTB-55O6.8" "NDST2" "GUCY1B3" "MAP1LC3A" "HYI" ... 4.13.4 EJERCICIO: Dibujando los HVGs Para este ejercicio tendrás que repetir la gráfica que muestra la tendencia de la relación media-varianza (ejeX: media de la expresión, ejeY: varianza de la expresión) incluyendo la línea de tendencia obtenida con alguna de las funciones vistas en la primer parte de la clase (modelGeneVar, modelGeneVarWithSpikes, modelGeneCV2). En esta gráfica, deberás colorear los puntos que corresponden a los HGVs obtenidos con algunos de los enfoques revisados RESPUESTA plot(fit.pbmc$mean, fit.pbmc$var, xlab = "Mean of log-expression", ylab = "Variance of log-expression" ) points(fit.pbmc$mean[hvg.pbmc.var], fit.pbmc$var[hvg.pbmc.var], col = "orange") curve(fit.pbmc$trend(x), col = "dodgerblue", add = TRUE, lwd = 2) 4.13.5 Seleccionando genes de interés a priori Una estrategia contundente es usar sets predefinidos de genes de interés. No hay vergüenza en aprovechar el conocimiento biológivo previo Sin embargo, limita nuestra capacidad de descubrir aspectos nuevos o inesperados de la variación. Por lo tanto, considera esta como una estrategia complementaria a otros tipo de estrategias de selección de HGVs También podrías eliminar listas pre-definidas de genes: Genes de proteínas ribosomales o genes mitocondriales son conocidos por encontrarse dentro de los genes más variables y por interferir con análisis posteriores Sin embargo, tampoco hay que pecar de prevacido, espera a que estos genes demuestren ser problemáticos para removerlos 4.14 Poniendo todo junto # Elegimos el 10% de los genes con con componente biologico de variacion mayor dec.pbmc <- modelGeneVar(sce.pbmc) chosen <- getTopHVGs(dec.pbmc, prop = 0.1) str(chosen) ## chr [1:1285] "LYZ" "S100A9" "S100A8" "HLA-DRA" "CD74" "CST3" "TYROBP" "IGKC" "CCL5" "S100A4" "HLA-DRB1" "NKG7" ... Después de esto tenemos varias opciones para imponer nuestra selección de HGVs durante el resto del análisis: Hacer un subset de SCE para quedarnos únicamente con los HGVs Especificar los HGVs en funciones posteriores Magia (altExps) 4.14.1 Quedándonos sólo con los HGVs sce.pbmc.hvg <- sce.pbmc[chosen, ] sce.pbmc.hvg ## class: SingleCellExperiment ## dim: 1285 3968 ## metadata(1): Samples ## assays(2): counts logcounts ## rownames(1285): LYZ S100A9 ... ZNF770 TMEM106C ## rowData names(2): ID Symbol ## colnames(3968): AAACCTGAGACAGACC-1 AAACCTGAGGCATGGT-1 ... TTTGTCAGTTAAGACA-1 TTTGTCATCCCAAGAT-1 ## colData names(3): Sample Barcode sizeFactor ## reducedDimNames(0): ## mainExpName: NULL ## altExpNames(0): PRO: Te aseguras de que los métodos posteriores sólo usen estos genes para sus cálculos CONTRA: Los genes no-HGVs son eliminados del nuevo objeto SingleCellExperiment, lo cual hace menos conveniente la interrogación del dataset completo sobre genes que no son HGVs 4.14.2 Especificando los HGVs # Example of specifying HVGs in a downstream function # Performing PCA only on the chosen HVGs. library(scater) sce.pbmc <- runPCA(sce.pbmc, subset_row = chosen) sce.pbmc ## class: SingleCellExperiment ## dim: 33694 3968 ## metadata(1): Samples ## assays(2): counts logcounts ## rownames(33694): RP11-34P13.3 FAM138A ... AC213203.1 FAM231B ## rowData names(2): ID Symbol ## colnames(3968): AAACCTGAGACAGACC-1 AAACCTGAGGCATGGT-1 ... TTTGTCAGTTAAGACA-1 TTTGTCATCCCAAGAT-1 ## colData names(3): Sample Barcode sizeFactor ## reducedDimNames(1): PCA ## mainExpName: NULL ## altExpNames(0): Mantiene el objeto SingleCellExperiment original y especifica los genes para usar en funciones posteriores mediante un argumento adicional como subset_row PRO: Es útil si el análisis usa varios conjuntos de HGVs en diferentes pasos CONTRA: Podría ser inconveniente especificar repetidamente el mismo conjunto de HGVs en diferentes pasos 4.14.3 Witchcraft (Brujería) # Add the full SCE to the subsetted data SCE altExp(sce.pbmc.hvg, "original") <- sce.pbmc sce.pbmc.hvg ## class: SingleCellExperiment ## dim: 1285 3968 ## metadata(1): Samples ## assays(2): counts logcounts ## rownames(1285): LYZ S100A9 ... ZNF770 TMEM106C ## rowData names(2): ID Symbol ## colnames(3968): AAACCTGAGACAGACC-1 AAACCTGAGGCATGGT-1 ... TTTGTCAGTTAAGACA-1 TTTGTCATCCCAAGAT-1 ## colData names(3): Sample Barcode sizeFactor ## reducedDimNames(0): ## mainExpName: NULL ## altExpNames(1): original altExp(sce.pbmc.hvg, "original") ## class: SingleCellExperiment ## dim: 33694 3968 ## metadata(1): Samples ## assays(2): counts logcounts ## rownames(33694): RP11-34P13.3 FAM138A ... AC213203.1 FAM231B ## rowData names(2): ID Symbol ## colnames(3968): AAACCTGAGACAGACC-1 AAACCTGAGGCATGGT-1 ... TTTGTCAGTTAAGACA-1 TTTGTCATCCCAAGAT-1 ## colData names(3): Sample Barcode sizeFactor ## reducedDimNames(1): PCA ## mainExpName: NULL ## altExpNames(0): Utilizando el sistema de “experimento alternartivo” en la clase SingleCellExperiment PRO: Evita algunos problemas a largo plazo cuando el dataset original no está sincronizado con el conjunto filtrado por HVGs CONTRA: Ralentiza todos los análisis subsecuentes 4.15 Resumen y recomendaciones Es fácil atorarse en este paso debido a la variedad de opciones disponibles Elige un conjunto de HVGs y continúa con el análisis, recuerda regresar para probar la robustez de tus resultados usando una forma diferente para seleccionar los HVGs Si tienes spike-ins, trata de usarlos. No obstante, recuerda que los spike-ins no pueden capturar todas las fuentes de variación técnica 4.16 Recomendaciones para empezar Para CEL-Seq2: scran::modelGeneVarWithSpikes() Para 10X: scran::modelGeneVarByPoisson() Si quieres irte por el lado de conservar demasiados genes: scran::getTopHVGs(dec, var.threshold=0) Y realiza una comparación rápida con, por lo menos, el top-1000 HVGs Regresa al paso de selección de HVG para eliminar genes problemáticos tantas veces como sea necesario 4.17 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:43:17 EDT" proc.time() ## user system elapsed ## 1559.011 121.615 96046.530 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Zheng, G. X. Y. et al. Massively parallel digital transcriptional profiling of single cells. Nat. Commun. 8, 14049 (2017).↩︎ Lun, A. T. L., Calero-Nieto, F. J., Haim-Vilmovsky, L., Göttgens, B. & Marioni, J. C. Assessing the reliability of spike-in normalization for analyses of single-cell RNA sequencing data. Genome Res. 27, 1795–1806 (2017)).↩︎ "],["reducción-de-dimensiones.html", "5 Reducción de dimensiones 5.1 Diapositivas de Peter Hickey 5.2 Motivación 5.3 Reducción de dimensionalidad 5.4 Dataset ilustrativo: Zeisel 5.5 Dataset ilustrativo: 10x PBMC4k no filtradas 5.6 Análisis de Componentes Principales 5.7 Reducción de dimensionalidad para visualización 5.8 Dónde estamos 5.9 Detalles de la sesión de R", " 5 Reducción de dimensiones Instructora: Laura Gómez-Romero 5.1 Diapositivas de Peter Hickey Contenido adaptado de: aquí 5.2 Motivación El siguiente paso en el análisis de scRNA-seq usualmente consiste en identificar grupos de células “similares”. Por ejemplo: un análisis de clustering busca identificar células con un perfil transcriptómico similar al calcular distancias entre ellas. Si tuviéramos un dataset con dos genes podríamos hacer una gráfica de dos dimensiones para identificar clusters de células. Pero… tenemos decenas de miles de genes : Reducción de dimensionalidad 5.3 Reducción de dimensionalidad Es posible porque la expresión de diferentes genes estaría correlacionada si estos genes son afectados por el mismo proceso biológico. Por lo tanto, no necesitamos almacenar información independiente para genes individuales. Podemos comprimir múltiples “features” (genes) en una única dimensión. Ventajas: Reduce trabajo computacional en análisis posteriores. Reduce el ruido al “promediar” mútiples genes obteniendo una representación más precisa de los patrones en los datos. Permite una graficación efectiva en dos dimensiones. 5.4 Dataset ilustrativo: Zeisel library(scRNAseq) sce.zeisel <- ZeiselBrainData(ensembl = TRUE) # Estos datos contienen tipos celulares previamente anotados table(sce.zeisel$level1class) ## ## astrocytes_ependymal endothelial-mural interneurons microglia oligodendrocytes ## 224 235 290 98 820 ## pyramidal CA1 pyramidal SS ## 939 399 Estudio de tipos celulares en el cerebro de ratón (oligodendrocitos, microglia, neuronas, etc) procesados con el sistema STRT-seq (similar a CEL-Seq) Descripción aquí Zeisel, A. et al. Brain structure. Cell types in the mouse cortex and hippocampus revealed by single-cell RNA-seq. Science 347, 1138-1142 (2015) # Quality control # Descartar celulas con alto contenido mitocondrial o con alto porcentaje de spike-ins library(scater) is.mito <- which(rowData(sce.zeisel)$featureType == "mito") stats <- perCellQCMetrics(sce.zeisel, subsets = list(Mt = is.mito) ) qc <- quickPerCellQC(stats, percent_subsets = c("altexps_ERCC_percent", "subsets_Mt_percent") ) sce.zeisel <- sce.zeisel[, !qc$discard] # normalization # encontramos unos clusters rápidos para las células y usamos esa información para calcular los factores de tamaño library(scran) set.seed(1000) clusters <- quickCluster(sce.zeisel) sce.zeisel <- computeSumFactors(sce.zeisel, cluster = clusters ) sce.zeisel <- logNormCounts(sce.zeisel) # variance-modelling dec.zeisel <- modelGeneVarWithSpikes( sce.zeisel, "ERCC" ) top.zeisel <- getTopHVGs(dec.zeisel, n = 2000) ¿Cómo se está modelando la relación media varianza? ¿Cómo se están obteniendo los HGVs? 5.5 Dataset ilustrativo: 10x PBMC4k no filtradas library(BiocFileCache) bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) library(DropletUtils) library(Matrix) fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) Dataset “Células mononucleares humanas de sangre periférica” de 10X Genomics Descripción aquí Zheng, G. X. Y. et al. Massively parallel digital transcriptional profiling of single cells. Nat. Commun. 8, 14049 (2017) # gene-annotation library(scater) rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) library(EnsDb.Hsapiens.v86) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) # cell-detection set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] # quality-control stats <- perCellQCMetrics(sce.pbmc, subsets = list(Mito = which(location == "MT")) ) high.mito <- isOutlier(stats$subsets_Mito_percent, type = "higher" ) sce.pbmc <- sce.pbmc[, !high.mito] # normalization library(scran) set.seed(1000) clusters <- quickCluster(sce.pbmc) sce.pbmc <- computeSumFactors(sce.pbmc, cluster = clusters) sce.pbmc <- logNormCounts(sce.pbmc) # variance modelling set.seed(1001) dec.pbmc <- modelGeneVarByPoisson(sce.pbmc) top.pbmc <- getTopHVGs(dec.pbmc, prop = 0.1) ¿Cómo se está modelando la relación media varianza? ¿Cómo se están obteniendo los HGVs? 5.6 Análisis de Componentes Principales PCA es el arma principal de la reducción de dimensionalidad. PCA descubre las combinaciones (lineales) de “features” que capturan la cantidad más grande de variación En un PCA, la primer combinación lineal (componente principal) se elige tal que permite capturar la mayor varianza a través de las células. El siguiente PC se elige tal que es “ortogonal” al primero y captura la cantidad más grande de la variación restante, y así sucesivamente… 5.6.1 PCA aplicado a datos de scRNA-seq Podemos realizar reducción de dimensionalidad al aplicar PCA en la matriz de cuentas transformadas (log-counts matrix) y restringiendo los análisis posteriores a los primeros PCs (top PCs). Esto puede reducir nuestro dataset de 20,000 dimensiones a, digamos, 10, sin perder demasiada información. La técnica de PCA tiene muchas propiedades teóricas bien estudiadas. Hay varias formas rápidas de realizar PCA en datasets grandes. 5.6.2 Suposiciones de PCA aplicadas a los datos de scRNA-seq Los procesos biológicos afectan múltiples genes en una manera coordinada. Los primeros PCs probablemente representan la estructura biológica dado que más variación puede ser capturada considerando el comportamiento correlacionado de muchos genes. Se espera que el ruido técnico azaroso afecte cada gen independientemente. Consideración: Los primeros PCs capturarón “batch effects” (efectos de lote) que afectan muchos genes en una manera coordinada ## Aplicar PCA en la matriz de cuentas transformadas (log-counts matrix) library(scran) library(scater) set.seed(100) sce.zeisel <- runPCA(sce.zeisel, subset_row = top.zeisel ) ¿Estamos corriendo el análisis sobre todos los genes de nuestro dataset? Por default, runPCA() usa un método rápido aproximado que realiza simulaciones, por lo tanto, es necesario ‘configurar la semilla’ para obtener resultados reproducibles. 5.6.3 Eligiendo el número de PCs Esta elección en análoga a la elección del número de highly variable genes (HGV). Elegir más PCs evitará descartar señal biológica a expensas de retener más ruido Es común seleccionar un número de PCs “razonable” pero arbitrario (10-50), continuar con el análisis y regresar para checar la robustez de los resultados en cierto rango de valores. Ahora exploraremos algunas estrategias guiadas por los datos (data-driven) para hacer esta selección. 5.6.3.1 Usando el punto del codo library(PCAtools) percent.var <- attr(reducedDim(sce.zeisel), "percentVar") chosen.elbow <- PCAtools::findElbowPoint(percent.var) plot(percent.var, xlab = "PC", ylab = "Variance explained (%)") abline(v = chosen.elbow, col = "red") Una heurística simple es elegir el número de PCs basado en el porcentaje de varianza explicado por PCs sucesivos. 5.6.3.2 Basados en la estructura de la población Esta es una aproximación heurística más sofisticada que usa el número de clusters como un proxy del número de subpoblaciones. choices <- getClusteredPCs(reducedDim(sce.zeisel)) chosen.clusters <- metadata(choices)$chosen plot(choices$n.pcs, choices$n.clusters, xlab = "Number of PCs", ylab = "Number of clusters" ) abline(a = 1, b = 1, col = "red") abline(v = chosen.clusters, col = "grey80", lty = 2) Supongamos que esperamos d subpoblaciones de células, en ese caso, necesitamos d-1 dimensiones para garantizar la separación de todas las subpoblaciones. Pero… en un escenario real realmente no sabes cuántas poblaciones hay… Intenta con un rango para d y únicamente considera valores que produzcan a lo más d+1 clusters Cuando se seleccionan más clusters con menos dimensiones se produce ‘overclustering’. Elige una d que maximice el número de clusters sin caer en ‘overclustering’. Ventaja: Es una solución pragmática que soluciona el equilibrio sesgo-varianza en los análisis posteriores (especialmente en el análisis de clustering). Desventaja: Hace suposiciones fuertes sobre la naturaleza de las diferencias biológicas entre los clusters, y de hecho supone la existencia de clusters, los cuales podrían no existir en algunos procesos biológicos como la diferenciación. 5.6.4 Juntando todo set.seed(100) # Calcula y almacena todos los posibles PCs sce.zeisel <- runPCA(sce.zeisel, subset_row = top.zeisel) # Selecciona y almacena el conjunto reducido de PCs: # ... por el método del codo reducedDim(sce.zeisel, "PCA_elbow") <- reducedDim( sce.zeisel, "PCA" )[, 1:chosen.elbow] # ... basado en la estructura poblacional reducedDim(sce.zeisel, "PCA_clusters") <- reducedDim( sce.zeisel, "PCA" )[, 1:chosen.clusters] 5.6.5 EJERCICIO Realiza un PCA para los datos sce.pbmc. Elige el número de PCs a conservar utilizando el método del codo. Elige el número de PCs a conservar utilizando la estructura de la población. Agrega esta información al objeto sce.pbmc. 5.6.6 Usando el ruido técnico Otra técnica de reducción de dimensiones consiste en conservar todos los PCs hasta que el % de variación explicado alcance algun límite (por ejemplo, basado en la estimación de la variación técnica). denoisePCA() automáticamente selecciona el número de PCs. Por default, denoisePCA() realiza algunas simulaciones, por lo tanto necesitamos ‘configurar la semilla’ para obtener resultados reproducibles. library(scran) set.seed(111001001) denoised.pbmc <- denoisePCA(sce.pbmc, technical = dec.pbmc, subset.row = top.pbmc ) dim(reducedDim(denoised.pbmc, "PCA")) ## [1] 3968 8 La dimensionalidad del output es el límite inferior para el número de PCs requeridos para explicar toda la variación biológica. Lo que significa que cualquier número menor de PCs definitivamente descartará algún aspecto de la señal biológica. Esto no grantiza que los PCs retenidos capturen toda la señal biológica Esta técnica usualmente retiene más PCs que el método del punto del codo scran::denoisePCA() internamente limita el numero de PCs, por default 5-50, para evitar la selección de excesivamente pocos PCs (cuando el ruido técnico es alto relativo al ruido biológico) o excesivamente muchos PCs (cuando el ruido técnico es demasiado bajo). 5.6.6.1 ¿Qué pasa si calculamos la relación media-varianza con la función modelGeneVar para el dataset sce.pbmc (anteriormente usamos la función modelGeneVarByPoisson para este propósito)? dec.pbmc2 <- modelGeneVar(sce.pbmc) denoised.pbmc2 <- denoisePCA(sce.pbmc, technical = dec.pbmc2, subset.row = top.pbmc ) dim(reducedDim(denoised.pbmc2)) ## [1] 3968 5 scran::denoisePCA() tiende a funcionar mejor cuando la relación media-varianza refleja el ruido técnico verdadero, i.e estimado por scran::modelGeneVarByPoisson() o scran::modelGeneVarWithSpikes() en vez de scran::modelGeneVar(). El dataset PBMC está cerca de este límite inferior: el ruido técnico es alto relativo al ruido biológico. 5.6.6.2 ¿Qué pasa si calculamos el número de PCs usando el ruido técnico para el dataset sce.zeisel? set.seed(001001001) denoised.zeisel <- denoisePCA(sce.zeisel, technical = dec.zeisel, subset.row = top.zeisel ) dim(reducedDim(denoised.zeisel)) ## [1] 2815 50 Los datos de cerebro de Zeisel están cerca de este límite superior: el ruido técnico es demasiado bajo dim(reducedDim(denoised.zeisel, "PCA")) ## [1] 2815 50 dim(reducedDim(denoised.zeisel, "PCA_elbow")) ## [1] 2815 7 dim(reducedDim(denoised.zeisel, "PCA_clusters")) ## [1] 2815 15 5.7 Reducción de dimensionalidad para visualización 5.7.1 Motivación Los algoritmos de clustering, así como la mayoría de los algoritmos, operan fácilmente sobre 10-50 (a lo más) PCs, pero ese número es aún demasiado para la visualización. Por lo tanto, necesitamos estrategias adicionales para la reducción de dimensionalidad si queremos visualizar los datos. 5.7.2 Visualizando con PCA plotReducedDim(sce.zeisel, dimred = "PCA") plotReducedDim(sce.zeisel, dimred = "PCA", colour_by = "level1class" ) PCA es una técnica lineal, por lo tanto, no es eficiente para comprimir diferencias en más de 2 dimensiones en los primeros 2 PCs. 5.7.3 Retos y resumen de la visualización con PCA plotReducedDim(sce.zeisel, dimred = "PCA", ncomponents = 4, colour_by = "level1class" ) Ventajas: PCA es predecible y no introducirá estructura artificial en los datos. Es determínistico y robusto a cambios pequeños en los valores de entrada. Desventajas: Usualmente la visualización no es suficiente para visualizar la naturaleza compleja de los datos de scRNA-seq. 5.7.4 Visualización con t-SNE set.seed(00101001101) sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA") plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class") t-stochastic neighbour embedding (t-SNE) es la visualización por excelencia de datos de scRNA-seq. Intenta encontrar una representación (no-lineal) de los datos usando pocas dimensiones que preserve las distancias entre cada punto y sus vecinos en el espacio multi-dimensional 5.7.4.1 Retos de la visualización con t-SNE set.seed(100) sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA", perplexity = 30 ) plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class" ) 5.7.4.2 Preguntas ¿Qué pasa si vuelves a correr runTSNE() sin especificar la semilla? ¿Qué pasa si especificas la semilla pero cambias el valor del parámetro perplexity? 5.7.4.3 Continuando Baja perplejidad favorece la resolución de la estructura fina, posiblemente al grado de que la visualización parece ruido random. set.seed(100) sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA", perplexity = 5) p1 <- plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class") sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA", perplexity = 20) p2 <- plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class") sce.zeisel <- runTSNE(sce.zeisel, dimred = "PCA", perplexity = 80) p3 <- plotReducedDim(sce.zeisel, dimred = "TSNE", colour_by = "level1class") library("patchwork") p1 + p2 + p3 El siguiente foro discute la selección de parámetros para t-SNE con cierta profundidad. No sobreinterpretes los resultados de t-SNE como un ‘mapa’ de las identidades de las células individuales. Algunos componentes aleatorios y la selección de parámetros cambiarán la visualización. La interpretación puede ser engañada por el tamaño y posición de los clusters. t-SNE infla clusters densos y comprime clusters escasos. t-SNE no está obligado a preservar las localizaciones relativas de clusters no-vecinos (no puedes interpretar distancias no locales). Aún así: t-SNE es una herramienta probada para visualización general de datos de scRNA-seq y sigue siendo muy popular 5.7.5 Visualización con UMAP Uniform manifold approximation and project (UMAP) es una alternativa a t-SNE. Así como t-SNE, UMAP intenta encontrar una representación (no lineal) de pocas dimensiones de los datos que preserve las distancias entre cada punto y sus vecinos en el espacio multi-dimensional. t-SNE y UMAP están basados en diferentes teorías matemáticas. set.seed(1100101001) sce.zeisel <- runUMAP(sce.zeisel, dimred = "PCA") plotReducedDim(sce.zeisel, dimred = "UMAP", colour_by = "level1class" ) Comparado con t-SNE: UMAP tiende a encontrar clusters visualmente más compactos. Intenta preservar más de la estructura global que t-SNE. Tiende a ser más rápido que t-SNE, lo cual puede ser importante para datasets grandes. La diferencia desaparece cuando se aplican sobre los primeros PCs. 5.7.5.1 Preguntas ¿Qué pasa si vuelves a correr runUMAP() sin especificar la semilla? ¿Qué pasa si especificas la semilla pero cambias el valor del parámetro n_neighbors? 5.7.5.2 Continuando Igual que para t-SNE, es necesario configurar una semilla y diferentes valores para los parámetros cambiaron la visualización. Si el valor para los parámetros n_neighbors o min_dist es demasiado bajo entonces el ruido aleatorio se interpretará como estructura de alta-resolución, si son demasiado altos entonces se perderá la estructura fina. TIP: Trata un rango de valores para cada parámetro para asegurarte de que no comprometen ninguna de las conclusiones derivadas de la gráfica UMAP o t-SNE 5.7.6 Interpretando las gráficas Recuerda: Reducción de dimensionalidad para la visualización de los datos necesariamente involucra descartar información y distorsionar las distancias entre las células. No sobre interpretes las gráficas bonitas. 5.7.7 Resumen y recomendaciones Las gráficas de t-SNE y UMAP son herramientas diagnóstico importantes, por ejemplo: para checar si dos clusters son realmente subclusters vecinos o si un cluster puede ser dividido en más de un cluster. Es debatible cuál visualización, t-SNE o UMAP, es más útil o estéticamente agradable. Está bien elegir aquella que funcione mejor para tu análisis (tomando en cuenta que tratarás la gráfica únicamente como una herramienta de visualización/diagnóstico y que no llegarás a ninguna conclusión fuerte basado únicamente en la gráfica). 5.8 Dónde estamos 5.9 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:45:27 EDT" proc.time() ## user system elapsed ## 1683.500 125.169 96176.687 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── "],["clustering.html", "6 Clustering 6.1 Dataset ilustrativo: 10X PBMC4k no filtrado 6.2 Motivación 6.3 ¿Por qué no realizamos el clustering sobre las coordenadas de t-SNE/UMAP? 6.4 ¿Cuál es el verdadero clustering? 6.5 Clustering basado en grafos 6.6 Evaluando la separación de los clusters 6.7 Otros métodos de clustering 6.8 Evaluando la estabilidad de los clusters 6.9 Subclustering 6.10 Resumen y recomendaciones 6.11 Dónde estamos 6.12 Detalles de la sesión de R", " 6 Clustering Instructora: Laura Gómez-Romero Este contenido está basado en las diapositivas de Peter Hickey. Ve las diapositivas aquí. Y en el curso de OSCA, lee el material aquí 6.1 Dataset ilustrativo: 10X PBMC4k no filtrado library(BiocFileCache) bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) library(DropletUtils) library(Matrix) fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) Dataset de células mononucleares de sangre periférica humana (PBMC) de 10X Genomics Descripción aquí Zheng, G. X. Y. et al. Massively parallel digital transcriptional profiling of single cells. Nat. Commun. 8, 14049 (2017) # gene-annotation library(scater) rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) library(EnsDb.Hsapiens.v86) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) # cell-detection set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] # quality-control stats <- perCellQCMetrics(sce.pbmc, subsets = list(Mito = which(location == "MT")) ) high.mito <- isOutlier(stats$subsets_Mito_percent, type = "higher" ) sce.pbmc <- sce.pbmc[, !high.mito] # normalization library(scran) set.seed(1000) clusters <- quickCluster(sce.pbmc) sce.pbmc <- computeSumFactors(sce.pbmc, cluster = clusters) sce.pbmc <- logNormCounts(sce.pbmc) # variance modelling set.seed(1001) dec.pbmc <- modelGeneVarByPoisson(sce.pbmc) top.pbmc <- getTopHVGs(dec.pbmc, prop = 0.1) # dimensionality-reduction set.seed(10000) sce.pbmc <- denoisePCA(sce.pbmc, subset.row = top.pbmc, technical = dec.pbmc ) set.seed(100000) sce.pbmc <- runTSNE(sce.pbmc, dimred = "PCA") set.seed(1000000) sce.pbmc <- runUMAP(sce.pbmc, dimred = "PCA") ¿Para qué sirve el método que estamos usando para reducir la dimensionalidad de los datos? ¿Los HGVs están almacenados en nuestro objeto sce.pbmc? 6.2 Motivación Clustering es un procedimiento no supervisado par definir grupos de células con perfiles de expresión similares Su propósito principal es resumir los datos en un formato digerido susceptible a interpretación humana Nos permite asignar etiquetas (por ejemplo, tipos celulares) a las células 6.3 ¿Por qué no realizamos el clustering sobre las coordenadas de t-SNE/UMAP? Las técnicas de t-SNE/UMAP han comprimido datos altamente multi-dimensionales en dos dimensiones Esta compresión inevitablemente ha provocado la perdida de información Por lo tanto, agrupamos sobre los PCs y después visualizamos las identidades de los clusters en la gráfica t-SNE/UMAP 6.4 ¿Cuál es el verdadero clustering? Un cluster no implica un tipo celular Nosotros podemos definir tantos clusters como queramos y podemos utilizar el algoritmo que más nos acomode El clustering, como un microscopio, simplemente es una herramienta para explorar los datos Preguntar por el mejor clustering es similar a preguntar cuál es la mejor magnificación en un microscopio sin contenido 6.5 Clustering basado en grafos 6.5.1 Antecedentes El clustering basado en grafos fue popularizado (más no inventado) por su uso en Seurat Objetivo: Construir un grafo en el que cada nodo es una célula que está conectada a sus vecinos más cercanos (otras células con perfiles de expresión similares) en el espacio multidimensional 6.5.2 Gráfica de los k vecinos más cercanos (k-nearest neighbour -KNN- graph) Ilustremos como funciona para 20 células 6.5.3 Gráfica de los vecinos más próximos compartidos (SNN) De una gráfica KNN se puede construir una gráfica SNN. En este tipo de grafo, dos células estarán conectadas por una arista si comparten alguno de sus vecinos más próximos. 6.5.4 Gráfica SNN con pesos en las aristas Podemos asignar pesos a cada arista del grafo, basándonos en la similaridad de las células involucradas, dándole pesos más altos a células que están más cercanamente relacionadas Para ver los distintos esquemas de pesado puedes consultar la documentación de la función makeSNNGraph del paquete bluster. Algunos ejemplos son: Rango: El peso entre dos nodos está dado por k-r/2 donde r es la suma más pequeña de los rangos (de proximidad, el vecino más cercano tiene el rango 1) para cualquiera de los vecinos compartidos Número: el peso entre dos nodos es igual al número de vecinos más próximos compartidos Jaccard: el peso entre dos nodos es igual a la similaridad de Jaccard entre los conjuntos de vecinos de estos nodos 6.5.5 Obteniendo comunidades a partir de una gráfica SNN pesada mediante un algoritmo de clustering A partir de una gráfica SNN pesada podemos aplicar algoritmos para identificar comunidades de células Una comunidad es un grupo de células que están más conectadas a células en el mismo grupo que lo que están a células de un grupo diferente Cada comunidad representa un cluster 6.5.6 Resumen de clustering basado en grafos La construcción y búsqueda de una red KNN es rápida, por lo tanto, es escalable para datasets grandes Debes evitar obtener conclusiones fuertes acerca de la forma de los clusters o la distribución de células dentro de cada cluster El algoritmo conecta cada célula con un número mínimo de células vecinas lo cual reduce, más no elimina, el riesgo de clusters no informativos Después de la construcción del grafo, no se almacena información adicional más alla de las células vecinas. Esto puede producir subclusters artificiales en regiones con muchas células 6.5.7 Detalles a considerar en la implementación ¿Cuántas céulas vecinas debo considerar durante la construcción del grafo? ¿Cómo debo pesar las aristas? ¿Cuál algoritmo de detección de comunidades se debe usar para definir los clusters? 6.5.8 Implementación library(scran) # Construir grafo usando k= 10 vecinos más cercanos en el espacio definido por el PCA g <- buildSNNGraph(sce.pbmc, k = 10, use.dimred = "PCA") # Identificar comunidades utilizando el método Walktrap clust <- igraph::cluster_walktrap(g)$membership # Visualizar clusters en una gráfica t-SNE library(scater) sce.pbmc$cluster <- factor(clust) plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster") ¿Qué pasa si utilizas una k más grande o más pequeña? library(scran) #Construir grafo usando k= 50 vecinos más cercanos en el espacio definido por el PCA g50 <- buildSNNGraph(sce.pbmc, k = 50, use.dimred = "PCA") # Identificar comunidades utilizando el método Walktrap clust50 <- igraph::cluster_walktrap(g50)$membership # Visualizar clusters en una gráfica t-SNE library(scater) sce.pbmc$cluster50 <- factor(clust50) plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster50") En esta implementación: La construcción de la red KNN se baso en la distancia Euclideana entre células La construcción de la red KNN implica que las aristas se crean entre todos los pares de células que comparten por lo menos un vecino Se utilizó el esquema de peso de: Xu and Su (2015) 6.5.9 Eligiendo un valor de k El valor de k puede ser toscamente interpretado como el tamaño anticipado de la subpoblación más pequeña Si una subpoblación tiene menos que (k+1) células entonces el método será forzado a construir aristas entre células de esa subpoblación y células de otras subpoblaciones, incrementando el riesgo de que la subpoblación en cuestión no forme su propio cluster 6.5.10 Una implementación diferente: estilo Seurat # Pesos definidos estilo Jaccard seguidos por clustering de Louvain # aka 'clustering estilo Seurat' g2 <- buildSNNGraph(sce.pbmc, k = 10, use.dimred = "PCA", type = "jaccard") clust2 <- igraph::cluster_louvain(g2)$membership sce.pbmc$cluster2 <- factor(clust2) plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster2") 6.5.11 Detalles de las implementaciones más comunes Pipelines basados en Seurat: Pesos basados en Jacard Clustering Louvain Pipelines basados en Scran: Pesos basados en Rangos Clustering Walktrap Para detalles sobre la seleccion de parámetros y comparaciones: visitar esta página. library("patchwork") ## Estilo scran vs estilo Seurat plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster") + plotReducedDim(sce.pbmc, "TSNE", colour_by = "cluster2") Figure 6.1: Estilo scran vs estilo Seurat. 6.5.12 Otras implementaciones Distintas métricas de distancia g.num <- buildSNNGraph(sce.pbmc, use.dimred = "PCA", type = "number") g.jaccard <- buildSNNGraph(sce.pbmc, use.dimred = "PCA", type = "jaccard") g.none <- buildKNNGraph(sce.pbmc, use.dimred = "PCA") Distintos métodos de clustering clust.louvain <- igraph::cluster_louvain(g)$membership clust.infomap <- igraph::cluster_infomap(g)$membership clust.fast <- igraph::cluster_fast_greedy(g)$membership clust.labprop <- igraph::cluster_label_prop(g)$membership clust.eigen <- igraph::cluster_leading_eigen(g)$membership 6.6 Evaluando la separación de los clusters Modularidad es una métrica natural para evaluar la separación entre comunidades/clusters La modularidad se define como la diferencia (escalada) entre el peso total observado de las aristas entre los nodos en el mismo cluster y el peso total esperado si los pesos fueran distribuidos aleatoriamente entre todos los pares de nodos Nosotros calcularemos un score de modularidad para cada cluster usando las tasas en vez de las diferencias, debido a que las tasas no se ven tan fuertemente influenciadas por el tamaño de los clusters library(bluster) # obteniendo la métrica de modularidad ratio <- pairwiseModularity(g, clust, as.ratio = TRUE) dim(ratio) ## [1] 19 19 library(pheatmap) pheatmap(log2(ratio + 1), cluster_rows = FALSE, cluster_cols = FALSE, color = colorRampPalette(c("white", "blue"))(100) ) Un dataset que contiene clusters bien separados debería contener la mayoría del peso total observado en las entradas diagonales, i.e la mayoría de las aristas ocurren entre células del mismo cluster Para más detalles sobre evaluación de la separación entre clusters visite esta página 6.7 Otros métodos de clustering Clustering por k-means PRO: Rápido Se debe especificar el número de clusters de antemano Favorece clusters esféricos Clustering jerárquico Produce un dendograma (árbol) representando las células y la similaridad entre subpoblaciones a varias resoluciones Demasiado lento para correrse en algo más grande que los datasets más pequeños de scRNA-seq 6.8 Evaluando la estabilidad de los clusters Una propiedad deseable de cualquier cluster es que éste sea estable a las perturbaciones en los datos de entrada, de esta manera: Pequeños cambios en el procesamiento de los datos no cambiarán el resultado Se incrementa la probabilidad de que las conclusiones puedan ser replicadas en un estudio independiente Uno puede hacer un proceso de bootstrap para evaluar la estabilidad de un algoritmo de clustering en un dataset dado y calcular la coasignación. La coasignación es la probabilidad de que células elegidas al azar del cluster X y Y sean asignadas al mismo cluster en la réplica del proceso de bootstrap myClusterFUN <- function(x) { g <- buildSNNGraph(x, use.dimred = "PCA", type = "jaccard") igraph::cluster_louvain(g)$membership } originals <- myClusterFUN(sce.pbmc) set.seed(0010010100) coassign <- bootstrapStability(sce.pbmc, FUN = myClusterFUN, clusters = originals ) pheatmap(coassign, cluster_row = FALSE, cluster_col = FALSE, color = rev(viridis::magma(100)) ) Probabilidad alta de coasignación indica que X es estable con respecto a su separación de Y. Queremos altas probabilidades de coasignación en la diagonal Debes considerar que el bootstraping solo considera el efecto del ruido de muestreo e ignora otros factores que pueden afectar la reproducibilidad (como efectos de batch) Además, una pobre separación puede ser altamente estable 6.9 Subclustering Mejora la resolución al repetir el proceso de feature selection y clustering dentro de un único cluster Se enfoca en los HGVs y PCs que son los más relevantes para un cluster específico Veamos como se comporta la expresión de ciertos genes en nuestros clusters CD3E, CCR7, CD69, y CD44 son marcadores de células T de memoria. g.full <- buildSNNGraph(sce.pbmc, use.dimred = "PCA") clust.full <- igraph::cluster_walktrap(g.full)$membership sce.pbmc$clust.full <- factor(clust.full) plotExpression(sce.pbmc, features = c("CD3E", "CCR7", "CD69", "CD44"), x = "clust.full", colour_by = "clust.full" ) De esta gráfica deducimos que las células T de memoria se encuentran en el cluster 10 Dentro de las células T de memoria, ¿dónde están las subpoblaciones CD4+ y CD8+? # Repetimos TODO el proceso de clustering en el subconjunto de células que hemos identificado como células T de memoria (cluster 10). memory <- 10 sce.memory <- sce.pbmc[, clust.full == memory] dec.memory <- modelGeneVar(sce.memory) sce.memory <- denoisePCA(sce.memory, technical = dec.memory, subset.row = getTopHVGs(dec.memory, prop = 0.1) ) g.memory <- buildSNNGraph(sce.memory, use.dimred = "PCA") clust.memory <- igraph::cluster_walktrap(g.memory)$membership sce.memory$clust.memory <- factor(clust.memory) plotExpression(sce.memory, features = c("CD8A", "CD4"), x = "clust.memory" ) Expresión de CD4 es bajo, por lo tanto, su cambio es modesto, pero la interpretación es clara Si tipos celulares o estados celulares se extienden sobre las fronteras de los clusters, entonces un subcluster podría representar contaminación de un tipo celular en un cluster separado 6.10 Resumen y recomendaciones Un cluster no implica un tipo celular Nosotros podemos definir tantos clusters como queramos y podemos utilizar el algoritmo que más nos acomode El clustering, como un microscopio, simplemente es una herramienta para explorar los datos Preguntar por el mejor clustering es similar a preguntar cuál es la mejor magnificación en un microscopio sin contenido Clustering basado en grafos es rápido y evita tener que hacer suposiciones fuertes sobre la forma de los clusters o la distribución de las células dentro de cada cluster: scran::buildSNNGraph() igraph::cluster_walktrap() o igraph::cluster_louvain() Modularidad y estabilidad de los clusters son diagnósticos útiles El proceso de subclustering podría mejorar la resolución dentro de clusters grandes 6.11 Dónde estamos 6.12 Detalles de la sesión de R ## Información de la sesión de R Sys.time() ## [1] "2023-08-08 17:46:48 EDT" proc.time() ## user system elapsed ## 1760.635 128.666 96258.125 options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-08 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── "],["identificación-de-genes-marcadores.html", "7 Identificación de genes marcadores 7.1 Diapositivas de Peter Hickey 7.2 Motivación 7.3 Dataset ilustrativo: PBMC4k 10X sin filtrar 7.4 Motivación - continuación 7.5 Prueba t modificada de Welch pareada 7.6 Ejemplo ilustrativo: CD3E como gen marcador en el dataset PBMC4k 10X 7.7 Aplicación estándar 7.8 Usando el log-fold change 7.9 Encontrando marcadores específicos de clústeres 7.10 Pruebas alternas 7.11 Prueba de rangos de Wilcoxon 7.12 Prueba binomial 7.13 Métodos de expresión diferencial personalizados 7.14 Problemas estadísticos 7.15 Detalles de la sesión de R Patrocinadores", " 7 Identificación de genes marcadores Instructora: Yalbi I. Balderas-Martínez. 7.1 Diapositivas de Peter Hickey Ver las diapositivas originales aquí 7.2 Motivación Ahora que hemos obtenido los clústeres, nos preguntamos, pero qué son? (e.g. ¿qué tipo celular es el clúster 1?) ¿Cuáles genes están dirigiendo el agrupamiento (e.g., ¿cuáles son los genes diferencialmente expresados entre los clústeres 1 y 2?) Idea: Mirar las diferencias en los perfiles de expresión de las células de los diferentes clústeres 7.3 Dataset ilustrativo: PBMC4k 10X sin filtrar # Usemos datos de pbmc4k library(BiocFileCache) bfc <- BiocFileCache() raw.path <- bfcrpath(bfc, file.path( "http://cf.10xgenomics.com/samples", "cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" )) untar(raw.path, exdir = file.path(tempdir(), "pbmc4k")) library(DropletUtils) library(Matrix) fname <- file.path(tempdir(), "pbmc4k/raw_gene_bc_matrices/GRCh38") sce.pbmc <- read10xCounts(fname, col.names = TRUE) Dataset “Células mononucleares humanas de sangre periférica” de 10X Genomics (Zheng, G.X.Y. et al, 2017) 5 7.3.1 Anotación # Anotación de los genes library(scater) rownames(sce.pbmc) <- uniquifyFeatureNames( rowData(sce.pbmc)$ID, rowData(sce.pbmc)$Symbol ) library(EnsDb.Hsapiens.v86) location <- mapIds(EnsDb.Hsapiens.v86, keys = rowData(sce.pbmc)$ID, column = "SEQNAME", keytype = "GENEID" ) # Detección de células set.seed(100) e.out <- emptyDrops(counts(sce.pbmc)) sce.pbmc <- sce.pbmc[, which(e.out$FDR <= 0.001)] 7.3.2 Control de calidad # Control de calidad stats <- perCellQCMetrics(sce.pbmc, subsets=list(Mito=which(location=="MT"))) high.mito <- isOutlier(stats$subsets_Mito_percent, type="higher") sce.pbmc <- sce.pbmc[,!high.mito] 7.3.3 Normalización de los datos library(scran) set.seed(1000) clusters <- quickCluster(sce.pbmc) sce.pbmc <- computeSumFactors(sce.pbmc, cluster=clusters) sce.pbmc <- logNormCounts(sce.pbmc) 7.3.4 Genes variables # Identificación de genes altamente variables set.seed(1001) dec.pbmc <- modelGeneVarByPoisson(sce.pbmc) top.pbmc <- getTopHVGs(dec.pbmc, prop = 0.1) 7.3.5 Reducción de dimensiones # Reducción de dimensiones set.seed(10000) sce.pbmc <- denoisePCA(sce.pbmc, subset.row=top.pbmc, technical=dec.pbmc) set.seed(100000) sce.pbmc <- runTSNE(sce.pbmc, dimred="PCA") set.seed(1000000) sce.pbmc <- runUMAP(sce.pbmc, dimred="PCA") 7.3.6 Clustering # Clustering g <- buildSNNGraph(sce.pbmc, k=10, use.dimred="PCA") clust <- igraph::cluster_walktrap(g)$membership sce.pbmc$cluster <- factor(clust) 7.4 Motivación - continuación ¿Algunos de estos genes están asociados con los resultados de clustering? # El gen 1 está asociado con el clustering? plotExpression(sce.pbmc, features = rownames(sce.pbmc)[1], x = "cluster", colour_by = "cluster" ) # El gen 2 está asociado con el clustering? plotExpression(sce.pbmc, features = rownames(sce.pbmc)[2], x = "cluster", colour_by = "cluster" ) # El gen 252 está asociado con el clustering? plotExpression(sce.pbmc, features = rownames(sce.pbmc)[2512], x = "cluster", colour_by = "cluster" ) # El gen CD3E está asociado con el clustering? plotExpression(sce.pbmc, features = "CD3E", x = "cluster", colour_by = "cluster" ) Ver una gráfica como una forma de encontrar los genes marcadores obviamente no nos sirve a gran escala Necesitamos un método estadístico para identificar estos genes marcadores 👉 La prueba t de Welch es una opción obvia para probar las diferencias en la expresión entre clústeres 7.5 Prueba t modificada de Welch pareada ➕ Rápidas y buenas propiedades estadísticas para un gran número de células (Soneson and Robinson, 2018) 6 ➕ Las comparaciones pareadas proveen un log-fold change para indicar cuáles clústeres son distinguidos por cada gen 🤔 ¿Por qué no comparar cada clúster con el promedio de todas las otras células? Sensible a la composición poblacional, una subpoblación dominante sola que dirige la selección de los marcadores top para cualquier otro clúster 7.6 Ejemplo ilustrativo: CD3E como gen marcador en el dataset PBMC4k 10X 7.6.1 Pruebas pareadas comparison logFC Pval 1 vs 2 1.50 1.7e-198 1 vs 3 -0.08 0.11 … … … 2 vs 1 1.39 1.7e-198 … … … 18 vs 17 0.11 0.46 K = 18 clústeres K!/K-2)! = 306 comparaciones * La mitad de ellas son redundantes 7.6.2 Combinando comparaciones del gen CD3E para el clúster 1 “Me interesa saber si el gen CD3 está diferencialmente expresado entre el clúster 1 y ..” cualquier (any) otro clúster = P = 1.3 x 10-205 (Simes adjusted P-value) todos (all) los otros clústeres = P = 0.11 (Berger’s intersection-union test) algunos (some) de los otros clústeres = P = 2.0 x 10-44 (mediana u otro cuantil, Holm-adjusted P-values) 7.6.3 Extendiendo a todos los genes # scran::pairwiseTTests() # scran::combineMarkers() M = 33,694 genes 🤓 K x M = 10,310,364 pruebas Comparaciones involucrando clúster 1… Comparaciones involucrando clúster … Comparaciones involucrando clúster 18 7.7 Aplicación estándar Para cada clúster, usar pruebas t de Welch para identificar los genes que están diferencialmente expresados entre éste y cualquier (any) otro clúster # scran::findMarkers() library(scran) markers.pbmc <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="t", pval.type="any") 7.7.1 Explorando los resultados chosen <- "9" interesting <- markers.pbmc[[chosen]] plotExpression(sce.pbmc, rownames(interesting)[1:4], x="cluster", colour_by="cluster") 7.7.2 Con un heatmap best.set <- interesting[interesting$Top <= 6,] logFCs <- as.matrix(best.set[,-(1:3)]) colnames(logFCs) <- sub("logFC.", "", colnames(logFCs)) library(pheatmap) pheatmap(logFCs, breaks=seq(-5, 5, length.out=101)) 👉 Usamos el campo Top para identificar un conjunto de genes que distinguen al clúster 9 de cualquier otro clúster. El conjunto de genes con Top <= X es la unión del top X genes (ordenados por p-value) de cada comparación de pares que involucran al cluster 9. Por ejemplo, el conjunto de todos los genes con valores Top 1 contienen el gen con el p-value mas pequeño de cada comparación. El conjunto de genes Top valor menor o igual a 10 contiene los 10 genes top de cada comparación. Se consolida en un ranking para cada clúster. 7.8 Usando el log-fold change 7.8.1 Sin especificar el lfc Para cada clúster, usa pruebas t de Welch para identificar los genes que están sobreexpresados entre éste y cualquier otro clúster # set direction = "up" to only consider upregulated genes as potential markers markers.pbmc.up <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="t", direction="up", pval.type="any") interesting.up <- markers.pbmc.up[[chosen]] 7.8.2 Usando el lfc Para cada clúster, usa pruebas t de Welch para identificar los genes que están sobreexpresados con un log-fold change (lfc) o al menos 1 entre éste y cualquier otro clúster markers.pbmc.up2 <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="t", direction="up", lfc=1, pval.type="any") interesting.up2 <- markers.pbmc.up2[[chosen]] 👉 La prueba t también nos permite especificar un log-fold change diferente de cero como la hipótesis nula 🤓 Es más riguroso que simplemente filtrar por log-fold change (TREAT) 7 7.8.3 Heatmap best.set <- interesting.up2[interesting.up2$Top <= 5,] logFCs <- as.matrix(best.set[,-(1:3)]) colnames(logFCs) <- sub("logFC.", "", colnames(logFCs)) pheatmap(logFCs, breaks=seq(-5, 5, length.out=101)) 👉 Los promedios están más centrados en un conjunto de genes marcadores candidatos que están sobreexpresados en el clúster 9 ⚠️ El incremento del rigor no se da sin costo ⚠️ Si el lfc es muy grande podría descartar genes útiles E.g., un gen sobreexpresado en una proporción pequeña de células en un clúster sigue siendo un marcador efectivo si el foco está en la especificidad más que en la sensibilidad 7.9 Encontrando marcadores específicos de clústeres 👉 Por defecto, scran::findMarkers() dará un alto rango a genes que están DE en cualquier comparación pareada 🤔 Quiero genes que son específicos de cada clúster 👉 Tú quieres genes que son DE en todas las comparaciones pareadas Para cada clúster, usa pruebas t de Welch para identificar genes que están sobreexpresados entre éste y todos los otros clústeres Considera todos los genes que están diferencialmente expresados en todas las comparaciones pareadas incluyendo al clúster de interés markers.pbmc.up3 <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, direction="up", pval.type="all") interesting.up3 <- markers.pbmc.up3[[chosen]] 🤓 Usa una prueba de unión-intersección para combinar los P-values que es el máximo P-value de todas las comparaciones pareadas. Un gen solo logrará un bajo nivel de P-value combinado si está fuertemente DE en todas las comparaciones - cuando funciona es muy efectivo - te da un pequeño conjunto de marcadores candidatos. Un gen que esté al mismo nivel que los demás clústeres no será detectado. No nos serviría para diferenciar en las poblaciones CD4 CD8. 7.9.1 Pros/cons de los genes marcadores específicos de los clústeres Poblacion Expresion_CD4 Expresion_CD8 DN(CD4-/CD8-) No No CD4+> Si No CD8+> No Si DP(CD4+/CD8+) Si Si 7.9.2 findMarkers con pval.type some Para cada clúster, usa pruebas t de Welch para identificar los genes que están sobreexpresados entre éste y algunos de los otros clústers. markers.pbmc.up4 <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, direction="up", pval.type="some") interesting.up4 <- markers.pbmc.up4[[chosen]] 👉 Si pval.type=\"all\" es muy estricto, entonces pval.type=\"any\" es muy generoso 🤓 Podemos entonces usar some. Aplica la corrección Holm-Bonferroni a los P-values y toma el mejor valor de en medio como el P-value combinado Prueba la hipótesis nula de que al menos 50% de las comparaciones pareadas no tienen DE Se aplica un rango para obtener el conjunto de los mejores marcadores ⚠️ Perderás algunas garantías ofrecidas por los otros métodos 7.10 Pruebas alternas 7.10.1 Motivación La prueba t no es la única forma de comparar dos grupos de mediciones 🤔 Quiero una prueba que pueda ser usada perfectamente para distinguir dos clústeres uno del otro 👉 Prueba de rangos Wilcoxon 🤔 Quiero identificar genes que son expresados más frecuentemente en un clúster que en otro 👉 Prueba Binomial 7.11 Prueba de rangos de Wilcoxon Evalúa directamente la separación entre la distribución de la expresión de los diferentes clústeres 🤓 Es proporcional al área bajo la curva (AUC), que es la probabilidad de que una célula al azar de un clúster tenga mayor que expresión que una célula al azar de otro clúster 👉 AUCs de 1 o 0 indican que los dos clústeres tienen distribuciones de expresión separadas 🤓 También se conoce como prueba Wilcoxon-Mann-Whitney (WMW) 7.11.1 findMarkers para Wilcoxon Para cada clúster, usa la prueba de rangos de Wilcoxon para identificar genes que están sobreexpresados entre éste y cualquier otro clúster markers.pbmc.wmw <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="wilcox", direction="up", pval.type="any") interesting.wmw <- markers.pbmc.wmw[[chosen]] 7.11.2 Heatmap de genes marcadores con Wilcoxon best.set <- interesting.wmw[interesting.wmw$Top <= 5,] AUCs <- as.matrix(best.set[,-(1:3)]) colnames(AUCs) <- sub("AUC.", "", colnames(AUCs)) pheatmap(AUCs, breaks=seq(0, 1, length.out=21), color=viridis::viridis(21)) 7.11.3 Resumen de la prueba de rangos de Wilcoxon ➕ Ofrece directamente la propiedad deseable de un gen marcador (i.e. que el gen distinga perfectamente entre dos clústeres) ➕ Es simétrico con respecto a las diferencias en el tamaño de los grupos comparados ➖ Es mucho más lento comparado con la prueba t (aunque esto en general no es un problema en la práctica) 7.12 Prueba binomial Es una prueba que identifica los genes que difieren en la proporción de células que se expresan entre clústeres Una definición mucho más estricta de genes marcadores 🤓 Convierte la expresión en una medida binaria de presencia/ausencia, por lo que toda la información cuantitativa es ignorada Desde una perspectiva práctica, puede ser más fácil para validar 7.12.1 findMarkers para binomial Para cada clúster, usa la prueba Binomial para identificar genes que están más frecuentemente expresados (sobreexpresados) en comparación con cualquier otro clúster markers.pbmc.binom <- findMarkers(sce.pbmc, groups=sce.pbmc$cluster, test.type="binom", direction="up", pval.type="any") interesting.binom <- markers.pbmc.binom[[chosen]] 🤓 El efecto en el tamaño se reporta como el log-fold change en la proporción de las células que se expresan entre clústeres 👉 Log-fold changes grandes positivos, indican que el gen está más frecuentemente expresado en un clúster comparado con otro 7.12.2 Visualizando genes marcadores de la prueba binomial top.genes <- head(rownames(interesting.binom)) plotExpression(sce.pbmc, x="cluster", features=top.genes) 7.12.3 Resumen de la prueba binomial La prueba Binomial no toma en cuenta la normalización ➕ Produce genes marcadores que pueden ser más fáciles de validar ➖ Ser más estricto puede llevar a la pérdida de buenos marcadores candidatos 7.13 Métodos de expresión diferencial personalizados 🤔 ¿Por qué no usar edgeR/DESeq2/limma-voom u otros métodos personalizados (e.g., MAST)? 👉 Claro que puedes! Checa OSCA 👉 Pero éstos son tal vez algo exagerados para identificar genes marcadores 🤓 Las células son nuestras “réplicas” para el propósito de identificar genes marcadores 🤓 edgeR/DESeq2/limma-voom hacen asunciones más fuertes acerca de los datos que es más probable que no se cumplan para células individuales en scRNA-seq 7.14 Problemas estadísticos 7.14.1 Invalidez de P-values Todas las estrategias de DE para detectar genes marcadores entre clústeres son estadísticamente defectuosas de alguna manera 🤓 “Dragado de datos”: El análisis DE se realiza usando los mismos datos usados para obtener los clústeres 👉 Las pruebas para genes DE entre clústeres producirá inevitablemente algunos resultados significativos y así es como los clústeres serán definidos! 👉 Aún cuando los P-values son defectuosos, el efecto no es muy dañino para la detección de genes ya que los P-values solo son usados para los rangos 🤓 No se pueden usar P-values para definir “diferencias significativas” entre los clústeres con respecto a un umbral de la tasa de error 7.14.2 Naturaleza de la replicación 👉 Idealmente, validar algunos de los marcadores con una población de células independientes (y idealmente usando una técnica diferente, e.g., hibridación fluorescente in situ o qPCR) 7.14.3 Comentarios adicionales 👉 La estrategia de análisis DE es que los marcadores son definidos relativo a subpoblaciones en el mismo dataset 👉 Si un gen se expresa uniformemente a través de la población no servirá como un marcador e.g., los marcadores de las células T no serán detectados si solamente hay células T en los datos usualmente no es un problema, ya que tenemos idea de las células que se capturaron 👉 Existen métodos de machine learning para hacer la identificación de los genes marcadores, pero la humilde prueba t sigue siendo muy buena 7.14.4 Resumen y recomendaciones 👉 Crea múltiples listas de genes marcadores con diferentes niveles de rigor 👉 La forma más simple de interpretar los genes marcadores es que son los sobreexpresados de “forma única”, o son “genes específicos de clústeres”, especialmente si queremos imponer un log-fold change mínimo 👉 Puedes requerir hacer una identificación de genes marcadores más enfocada, e.g., subset de los datos de solo 2 clústeres de interés y entonces correr scran::findMarkers() 7.15 Detalles de la sesión de R options(width = 120) sessioninfo::session_info() ## ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────── ## setting value ## version R version 4.3.1 (2023-06-16) ## os macOS Ventura 13.4.1 ## system aarch64, darwin20 ## ui RStudio ## language (EN) ## collate en_US.UTF-8 ## ctype en_US.UTF-8 ## tz America/New_York ## date 2023-08-06 ## rstudio 2023.06.0+421 Mountain Hydrangea (desktop) ## pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown) ## ## ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────── ## package * version date (UTC) lib source ## abind 1.4-5 2016-07-21 [1] CRAN (R 4.3.0) ## AnnotationDbi * 1.62.2 2023-07-02 [1] Bioconductor ## AnnotationFilter * 1.24.0 2023-05-08 [1] Bioconductor ## AnnotationHub * 3.8.0 2023-05-08 [1] Bioconductor ## beachmat 2.16.0 2023-05-08 [1] Bioconductor ## beeswarm 0.4.0 2021-06-01 [1] CRAN (R 4.3.0) ## Biobase * 2.60.0 2023-05-08 [1] Bioconductor ## BiocFileCache * 2.8.0 2023-05-08 [1] Bioconductor ## BiocGenerics * 0.46.0 2023-06-04 [1] Bioconductor ## BiocIO 1.10.0 2023-05-08 [1] Bioconductor ## BiocManager 1.30.21.1 2023-07-18 [1] CRAN (R 4.3.0) ## BiocNeighbors 1.18.0 2023-05-08 [1] Bioconductor ## BiocParallel 1.34.2 2023-05-28 [1] Bioconductor ## BiocSingular 1.16.0 2023-05-08 [1] Bioconductor ## BiocVersion 3.17.1 2022-12-20 [1] Bioconductor ## biomaRt 2.56.1 2023-06-11 [1] Bioconductor ## Biostrings 2.68.1 2023-05-21 [1] Bioconductor ## bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0) ## bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0) ## bitops 1.0-7 2021-04-24 [1] CRAN (R 4.3.0) ## blob 1.2.4 2023-03-17 [1] CRAN (R 4.3.0) ## bluster * 1.10.0 2023-05-08 [1] Bioconductor ## bookdown 0.34 2023-05-09 [1] CRAN (R 4.3.0) ## bslib 0.5.0 2023-06-09 [1] CRAN (R 4.3.0) ## cachem 1.0.8 2023-05-01 [1] CRAN (R 4.3.0) ## cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0) ## cluster 2.1.4 2022-08-22 [1] CRAN (R 4.3.1) ## codetools 0.2-19 2023-02-01 [1] CRAN (R 4.3.1) ## colorspace 2.1-0 2023-01-23 [1] CRAN (R 4.3.0) ## cowplot 1.1.1 2020-12-30 [1] CRAN (R 4.3.0) ## crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0) ## curl 5.0.1 2023-06-07 [1] CRAN (R 4.3.0) ## DBI 1.1.3 2022-06-18 [1] CRAN (R 4.3.0) ## dbplyr * 2.3.3 2023-07-07 [1] CRAN (R 4.3.0) ## DelayedArray 0.26.7 2023-07-28 [1] Bioconductor ## DelayedMatrixStats 1.22.1 2023-06-09 [1] Bioconductor ## digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0) ## dplyr * 1.1.2 2023-04-20 [1] CRAN (R 4.3.0) ## dqrng 0.3.0 2021-05-01 [1] CRAN (R 4.3.0) ## DropletUtils * 1.20.0 2023-05-08 [1] Bioconductor ## edgeR 3.42.4 2023-06-04 [1] Bioconductor ## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0) ## EnsDb.Hsapiens.v86 * 2.99.0 2023-07-29 [1] Bioconductor ## ensembldb * 2.24.0 2023-05-08 [1] Bioconductor ## evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0) ## ExperimentHub 2.8.1 2023-07-16 [1] Bioconductor ## fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0) ## farver 2.1.1 2022-07-06 [1] CRAN (R 4.3.0) ## fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0) ## filelock 1.0.2 2018-10-05 [1] CRAN (R 4.3.0) ## FNN 1.1.3.2 2023-03-20 [1] CRAN (R 4.3.0) ## generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0) ## GenomeInfoDb * 1.36.1 2023-07-02 [1] Bioconductor ## GenomeInfoDbData 1.2.10 2023-06-08 [1] Bioconductor ## GenomicAlignments 1.36.0 2023-05-08 [1] Bioconductor ## GenomicFeatures * 1.52.1 2023-07-02 [1] Bioconductor ## GenomicRanges * 1.52.0 2023-05-08 [1] Bioconductor ## ggbeeswarm 0.7.2 2023-04-29 [1] CRAN (R 4.3.0) ## ggplot2 * 3.4.2 2023-04-03 [1] CRAN (R 4.3.0) ## ggrepel * 0.9.3 2023-02-03 [1] CRAN (R 4.3.0) ## glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0) ## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.0) ## gtable 0.3.3 2023-03-21 [1] CRAN (R 4.3.0) ## HDF5Array 1.28.1 2023-05-08 [1] Bioconductor ## here 1.0.1 2020-12-13 [1] CRAN (R 4.3.0) ## highr 0.10 2022-12-22 [1] CRAN (R 4.3.0) ## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0) ## htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0) ## httpuv 1.6.11 2023-05-11 [1] CRAN (R 4.3.0) ## httr 1.4.6 2023-05-08 [1] CRAN (R 4.3.0) ## igraph 1.5.0.1 2023-07-23 [1] CRAN (R 4.3.0) ## interactiveDisplayBase 1.38.0 2023-05-08 [1] Bioconductor ## IRanges * 2.34.1 2023-07-02 [1] Bioconductor ## irlba 2.3.5.1 2022-10-03 [1] CRAN (R 4.3.0) ## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0) ## jsonlite 1.8.7 2023-06-29 [1] CRAN (R 4.3.0) ## kableExtra * 1.3.4 2021-02-20 [1] CRAN (R 4.3.0) ## KEGGREST 1.40.0 2023-05-08 [1] Bioconductor ## knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0) ## labeling 0.4.2 2020-10-20 [1] CRAN (R 4.3.0) ## later 1.3.1 2023-05-02 [1] CRAN (R 4.3.0) ## lattice 0.21-8 2023-04-05 [1] CRAN (R 4.3.1) ## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.0) ## lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0) ## limma 3.56.2 2023-06-04 [1] Bioconductor ## locfit 1.5-9.8 2023-06-11 [1] CRAN (R 4.3.0) ## magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0) ## Matrix * 1.6-0 2023-07-08 [1] CRAN (R 4.3.0) ## MatrixGenerics * 1.12.3 2023-07-30 [1] Bioconductor ## matrixStats * 1.0.0 2023-06-02 [1] CRAN (R 4.3.0) ## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.0) ## metapod 1.8.0 2023-04-25 [1] Bioconductor ## mime 0.12 2021-09-28 [1] CRAN (R 4.3.0) ## munsell 0.5.0 2018-06-12 [1] CRAN (R 4.3.0) ## patchwork * 1.1.2 2022-08-19 [1] CRAN (R 4.3.0) ## PCAtools * 2.12.0 2023-05-08 [1] Bioconductor ## pheatmap * 1.0.12 2019-01-04 [1] CRAN (R 4.3.0) ## pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0) ## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0) ## plyr 1.8.8 2022-11-11 [1] CRAN (R 4.3.0) ## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.0) ## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.3.0) ## progress 1.2.2 2019-05-16 [1] CRAN (R 4.3.0) ## promises 1.2.0.1 2021-02-11 [1] CRAN (R 4.3.0) ## ProtGenerics 1.32.0 2023-05-08 [1] Bioconductor ## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0) ## R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0) ## R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0) ## R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0) ## R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0) ## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.0) ## RColorBrewer 1.1-3 2022-04-03 [1] CRAN (R 4.3.0) ## Rcpp 1.0.11 2023-07-06 [1] CRAN (R 4.3.0) ## RCurl 1.98-1.12 2023-03-27 [1] CRAN (R 4.3.0) ## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0) ## restfulr 0.0.15 2022-06-16 [1] CRAN (R 4.3.0) ## rhdf5 2.44.0 2023-05-08 [1] Bioconductor ## rhdf5filters 1.12.1 2023-05-08 [1] Bioconductor ## Rhdf5lib 1.22.0 2023-05-08 [1] Bioconductor ## rjson 0.2.21 2022-01-09 [1] CRAN (R 4.3.0) ## rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0) ## rmarkdown 2.23 2023-07-01 [1] CRAN (R 4.3.0) ## rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0) ## Rsamtools 2.16.0 2023-06-04 [1] Bioconductor ## RSQLite 2.3.1 2023-04-03 [1] CRAN (R 4.3.0) ## rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0) ## rsvd 1.0.5 2021-04-16 [1] CRAN (R 4.3.0) ## rtracklayer 1.60.0 2023-05-08 [1] Bioconductor ## Rtsne 0.16 2022-04-17 [1] CRAN (R 4.3.0) ## rvest 1.0.3 2022-08-19 [1] CRAN (R 4.3.0) ## S4Arrays 1.0.5 2023-07-24 [1] Bioconductor ## S4Vectors * 0.38.1 2023-05-08 [1] Bioconductor ## sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0) ## ScaledMatrix 1.8.1 2023-05-08 [1] Bioconductor ## scales 1.2.1 2022-08-20 [1] CRAN (R 4.3.0) ## scater * 1.28.0 2023-04-25 [1] Bioconductor ## scran * 1.28.2 2023-07-23 [1] Bioconductor ## scRNAseq * 2.14.0 2023-04-27 [1] Bioconductor ## scuttle * 1.9.4 2023-01-23 [1] Bioconductor ## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0) ## shiny 1.7.4.1 2023-07-06 [1] CRAN (R 4.3.0) ## SingleCellExperiment * 1.22.0 2023-05-08 [1] Bioconductor ## sparseMatrixStats 1.12.2 2023-07-02 [1] Bioconductor ## statmod 1.5.0 2023-01-06 [1] CRAN (R 4.3.0) ## stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0) ## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.3.0) ## SummarizedExperiment * 1.30.2 2023-06-06 [1] Bioconductor ## svglite 2.1.1 2023-01-10 [1] CRAN (R 4.3.0) ## systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.3.0) ## tibble 3.2.1 2023-03-20 [1] CRAN (R 4.3.0) ## tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0) ## utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0) ## uwot 0.1.16 2023-06-29 [1] CRAN (R 4.3.0) ## vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0) ## vipor 0.4.5 2017-03-22 [1] CRAN (R 4.3.0) ## viridis 0.6.4 2023-07-22 [1] CRAN (R 4.3.0) ## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.0) ## webshot 0.5.5 2023-06-26 [1] CRAN (R 4.3.0) ## withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0) ## xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0) ## XML 3.99-0.14 2023-03-19 [1] CRAN (R 4.3.0) ## xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0) ## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.0) ## XVector 0.40.0 2023-05-08 [1] Bioconductor ## yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0) ## zlibbioc 1.46.0 2023-05-08 [1] Bioconductor ## ## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library ## ## ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Patrocinadores La presentación fue hecha con el paquete de R xaringan y configurada con xaringanthemer. Este curso está basado en el libro Orchestrating Single Cell Analysis with Bioconductor de Aaron Lun, Robert Amezquita, Stephanie Hicks y Raphael Gottardo, además del curso de scRNA-seq para WEHI creado por Peter Hickey. Puedes encontrar los archivos para este taller en comunidadbioinfo/cdsb2023. Descarga los materiales con usethis::use_course('comunidadbioinfo/cdsb2023') o revísalos en línea vía comunidadbioinfo.github.io/cdsb2023. Zheng, G. X. Y. et al. Massively parallel digital transcriptional profiling of single cells. Nat. Commun. 8, 14049 (2017).↩︎ Soneson C, Robinson MD. Bias, robustness and scalability in single-cell differential expression analysis. Nat Methods. 2018 Apr;15(4):255-261. doi: 10.1038/nmeth.4612. Epub 2018 Feb 26. PMID: 29481549.↩︎ McCarthy DJ, Smyth GK. Testing significance relative to a fold-change threshold is a TREAT. Bioinformatics. 2009 Mar 15;25(6):765-71. doi: 10.1093/bioinformatics/btp053. Epub 2009 Jan 28. PMID: 19176553; PMCID: PMC2654802.↩︎ "],["anotación-de-tipos-celulares.html", "8 Anotación de tipos celulares 8.1 Diapositivas 8.2 Introducción 8.3 Motivación 8.4 Aproximaciones para anotar 8.5 Paqueterías de R más “famosas” para anotar 8.6 Paqueterías de R con conjuntos de datos de referencia 8.7 Preparación del dataset", " 8 Anotación de tipos celulares Erick Cuevas 08 de agosto de 2023 8.1 Diapositivas div.color { border-radius: 5px; padding: 20px; margin: 30px 0px 30px;} div.red { background-color:#f67155; } div.orange{ background-color:#f0BB51;} div.pair { display: flex; flex-direction: row; justify-content: center; text-align:center; padding:0px} div.inside { width: 49%; padding: 0px} div.scroll { max-height: 400px; overflow-y: auto; background: #111111; border-radius:5px; padding: 10px; margin: 30px 0px 30px; color: #999999;} div.alert{color:#bd475d; background-color:transparent} 8.2 Introducción El análisis de secuenciación de ARN a nivel de célula única (scRNAseq) ha revolucionado nuestra capacidad para estudiar la heterogeneidad celular en diversos tejidos y condiciones. A diferencia de la secuenciación de ARN tradicional, que proporciona información promedio de todas las células en una muestra, el scRNAseq permite el estudio detallado de la expresión génica en células individuales. Esto ha abierto puertas a descubrimientos sin precedentes en biología celular, permitiendo identificar nuevos tipos celulares, estados transicionales y vías de señalización específicas de células. Dentro de este contexto, la anotación de clusters en scRNAseq es esencial. Una vez que se han identificado grupos o “clusters” de células con perfiles de expresión similares, es crucial determinar qué representan estas agrupaciones en términos biológicos. Es aquí donde entra en juego la anotación. 8.3 Motivación Identificación de Tipos y Subtipos Celulares: La principal motivación para anotar clusters es identificar y etiquetar tipos y subtipos celulares específicos dentro de una muestra. Esto es fundamental para entender la composición celular de un tejido y cómo esta composición puede cambiar en diferentes condiciones, como en enfermedades. Entender la Función Celular: Al anotar clusters, no solo identificamos qué tipo de célula es, sino que también podemos inferir su función actual basándonos en su perfil de expresión génica. Descubrimiento de Nuevos Tipos Celulares: En algunos casos, la anotación puede revelar grupos de células que no se ajustan a tipos celulares conocidos, lo que indica la posible existencia de un tipo celular previamente no descrito. Base para Análisis Posteriores: Una vez que se han anotado los clusters, se pueden realizar análisis más detallados, como estudios de vías de señalización, análisis de reguladores maestros o estudios de interacción celular. Comparación Entre Muestras y Condiciones: La anotación permite comparar la composición celular entre diferentes muestras, tejidos o condiciones, lo que es esencial para estudios comparativos y de enfermedades. 8.4 Aproximaciones para anotar Modo artístico. Usando conocimiento previo de genes marcadores ya publicados. Usando referencias de conjuntos de datos ya anotados. Combinando el modo artístico con referencias. Anclas con Seurat. 8.5 Paqueterías de R más “famosas” para anotar SingleR Seurat scCATCH cellassign SCINA Garnett 8.6 Paqueterías de R con conjuntos de datos de referencia SeuratData celldex scRNAseq Otros sitios interesantes para obtener conjuntos de datos de referencia: Azimuth Single Cell Expression Atlas GLIASEQ 8.7 Preparación del dataset El dataset tiene el ID en GEO GSE159677 OJO PARA FINES DEL TIEMPO DEL CURSO POR AHORA NO GENERAREMOS este dataset desde cero, este proceso realízalo cuando tengas memoria ram libre y no utilices tu equipo para otra cosa library(cowplot) library(ggplot2) library(scater) library(scds) library(SingleCellExperiment) #Carga de datos y re formato #Carga de las cuentas crudas #Recuerda cambiar el PATH o directorio a la ubicación de los datos fastq_dirs <- list.dirs("../datos_atherosclerosis/tom_alsaigh_2022/", recursive = FALSE, full.names = TRUE) names(fastq_dirs) <- basename(fastq_dirs) sce <- DropletUtils::read10xCounts(fastq_dirs) #Renombrar row/colData nombre de columnas y SCE dimnames names(rowData(sce)) <- c("ENSEMBL", "SYMBOL") names(colData(sce)) <- c("sample_id", "barcode") sce$sample_id <- factor(basename(sce$sample_id)) dimnames(sce) <- list( with(rowData(sce), paste(SYMBOL, sep = ".")), with(colData(sce), paste(barcode, sample_id, sep = "."))) # Agregamos la metadata md <- data.frame( Sample_ID = c("Patient1_AC", "Patient1_PA", "Patient2_AC", "Patient2_PA", "Patient3_AC", "Patient3_PA"), Age = c(82, 82, 87, 87, 65, 65), AHA_Classification = c("Type_VII_Calcified", "Type_VII_Calcified", "Type_VII_Calcified", "Type_VII_Calcified", "Type_VII_Calcified", "Type_VII_Calcified"), Region = c("Atherosclerotic_Core", "Proximal_Adjacent", "Atherosclerotic_Core", "Proximal_Adjacent", "Atherosclerotic_Core", "Proximal_Adjacent") ) m <- match(sce$sample_id, md$Sample_ID) sce$region <- md$Region[m] sce$AHA_Classification <- md$AHA_Classification[m] sce$sample_id <- md$Sample_ID[m] sce$Age <- md$Age[m] Hacemos ahora un pequeño proceso de limpieza y normalización #Remover genes no detectados sce <- sce[Matrix::rowSums(counts(sce) > 0) > 0, ] dim(sce) #Remover doublets #dividir SCE por muestra OJO esto podria ser por lotes cs_by_s <- split(colnames(sce), sce$sample_id) sce_by_s_2 <- lapply(cs_by_s, function(cs) sce[, cs]) #correr 'scds' sce_by_s_2 <- lapply(sce_by_s_2, function(u) scds::cxds_bcds_hybrid(scds::bcds(scds::cxds(u)))) #Eliminando doublets sce_by_s <- lapply(sce_by_s_2, function(u) { #Calcula numero de doublets (10x) n_dbl <- ceiling(0.01 * ncol(u)^2 / 1e3) #Elimina 'n_dbl' celulas con mayor scpre de doublet o <- order(u$hybrid_score, decreasing = TRUE) u[, -o[seq_len(n_dbl)]] }) #Integrar nuevamente al objeto SCE sce <- do.call(cbind, sce_by_s) #Calcular metricas QC (mito <- grep("MT-", rownames(sce), value = TRUE)) # sce <- perCellQCMetrics(sce, subsets = list(Mito=mito)) sce <- addPerCellQCMetrics(sce, subsets = list(Mito=mito)) sce <- addPerFeatureQCMetrics(sce) Filtración de células #Obtener outliers cols <- c("total", "detected", "subsets_Mito_percent") log <- c(TRUE, TRUE, FALSE) type <- c("both", "both", "higher") # Con esto decidimos que barcode desechar drop_cols <- paste0(cols, "_drop") for (i in seq_along(cols)){ colData(sce)[[drop_cols[i]]] <- isOutlier(sce[[cols[i]]], nmads = 2.5, type = type[i], log = log[i], batch = sce$sample_id) } # Muestra un resumen de los barcodes que se eliminaran sapply(drop_cols, function(i) sapply(drop_cols, function(j) sum(sce[[i]] & sce[[j]]))) cd <- data.frame(colData(sce)) ps <- lapply(seq_along(cols), function (i) { p <- ggplot(cd, aes_string(x = cols[i], alpha = drop_cols[i])) + geom_histogram(bins = 100, show.legend = FALSE) + scale_alpha_manual(values = c("FALSE" = 1, "TRUE" = 0.4)) + facet_wrap(~sample_id, ncol = 1, scales = "free") + theme_classic() + theme(strip.background = element_blank()) if (log[i]) p <- p + scale_x_log10() return(p) }) plot_grid(plotlist = ps, ncol = 3) layout(matrix(1:2, nrow = 1)) ol <- Matrix::rowSums(as.matrix(colData(sce)[drop_cols])) != 0 x <- sce$total y <- sce$detected LSD::heatscatter(x, y, log="xy", main = "unfiltered", xlab = "Total counts", ylab = "Non-zero features") LSD::heatscatter(x[!ol], y[!ol], log="xy", main = "filtered", xlab = "Total counts", ylab = "Non-zero features") #Generar resumen de celulas a mantener ns <- table(sce$sample_id) ns_fil <- table(sce$sample_id[!ol]) print(rbind( unfiltered = ns, filtered = ns_fil, "%" = ns_fil / ns * 100)) #Eliminar celulas outlier sce <- sce[, !ol] dim(sce) #count > 1 sce <- sce[Matrix::rowSums(counts(sce) > 1) >= 20, ] dim(sce) Agrupamiento, toma en cuenta que esta parte podría demorar bastante. #Load packages library(cowplot) library(Seurat) library(SingleCellExperiment) library(ggplot2) #INTEGRATE #Crear SeuratObject so <- CreateSeuratObject( counts = counts(sce), meta.data = data.frame(colData(sce)), project = "Alsaigh_10x_data") #Dividir por muestra cells_by_sample <- split(colnames(sce), sce$sample_id) so <- lapply(cells_by_sample, function(i) subset(so, cells = i)) #Normalizar, encontrar genes variables, escalar so <- lapply(so, NormalizeData, verbose = FALSE) so <- lapply(so, FindVariableFeatures, nfeatures = 2e3, selection.method = "vst", do.plot = FALSE, verbose = FALSE) so <- lapply(so, ScaleData, verbose = FALSE) #Encontrar anclas # Estas anclas nos ayudaran despues para integrar todo con la funcion IntegrateData. as <- FindIntegrationAnchors(so, verbose = TRUE) so <- IntegrateData(anchorset = as, dims = seq_len(30), verbose = TRUE) #Escalar datos integrados DefaultAssay(so) <- "integrated" so <- ScaleData(so, display.progress = FALSE) #Reducción de dimension so <- RunPCA(so, npcs = 100, verbose = FALSE) #Cambiar numbero de PCs usedos so <- RunTSNE(so, reduction = "pca", dims = seq_len(20), seed.use = 1, do.fast = TRUE, verbose = FALSE) so <- RunUMAP(so, reduction = "pca", dims = seq_len(20), seed.use = 1, verbose = FALSE) #CLUSTERING so <- FindNeighbors(so, reduction = "pca", dims = seq_len(20), verbose = FALSE) for (res in c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1)){ so <- FindClusters(so, resolution = res, random.seed = 1, verbose = FALSE) } Para los ejercicios de la presentación descarga los siguientes archivos https://drive.google.com/file/d/1HbJ0syxTcxkI1aG6dIQ6hkJ7SrLHCLfl/view?usp=drive_link https://drive.google.com/file/d/1gJ2raTr8BhLsjeW3n1sdKko0qLYE2g5n/view?usp=drive_link "],["nuevas-funcionalidades-de-rstudio-quarto..html", "9 Nuevas funcionalidades de RStudio, Quarto. 9.1 Diapositivas", " 9 Nuevas funcionalidades de RStudio, Quarto. Erick Cuevas 09 de agosto de 2023 9.1 Diapositivas "],["control-de-versiones-con-github-y-rstudio.html", "10 Control de versiones con GitHub y RStudio 10.1 Diapositivas 10.2 ¿Por qué hacer control de versiones de nuestros proyectos? 10.3 Git 10.4 Recomendaciones para sus proyectos 10.5 Proyectos colaborativos 10.6 GitHub 10.7 Manual de sobreviviencia con Git Y GitHub en RStudio (en caso de ser necesario) 10.8 Cómo clonar un repositorio y tener conección/permisos para modificarlo? 10.9 Credenciales HTTPS en Cache 10.10 Conectando RStudio con Git y Github. 10.11 GitHub primero, RStudio después… 10.12 Rmarkdown en GitHub 10.13 RStudio primero y GitHub también 10.14 Proyecto existente, GitHub al final 10.15 Git basics: commands 10.16 Merge conflics 10.17 Merge conflics 10.18 En resumen", " 10 Control de versiones con GitHub y RStudio Dra. Alejandra Medina Rivera 09 de agosto de 2023 div.color { border-radius: 5px; padding: 20px; margin: 30px 0px 30px;} div.red { background-color:#f67155; } div.orange{ background-color:#f0BB51;} div.pair { display: flex; flex-direction: row; justify-content: center; text-align:center; padding:0px} div.inside { width: 49%; padding: 0px} div.scroll { max-height: 400px; overflow-y: auto; background: #111111; border-radius:5px; padding: 10px; margin: 30px 0px 30px; color: #999999;} div.alert{color:#bd475d; background-color:transparent} Este documento se basa en “Happy Git with R” de Jenny Bryan, los STAT 545 TAs, Jim Hester https://happygitwithr.com 10.1 Diapositivas 10.2 ¿Por qué hacer control de versiones de nuestros proyectos? ✅ Los proyectos suelen cambiar y crecer. 💾 Es díficil saber cuáles fueron todos los cambios a lo largo del tiempo (en especial tiempos largos, hazlo por tu yo del futuro!). 🤔 Las colaboraciones se pueden complicar sin un buen control de versiones. 🔐 Seguridad. 10.3 Git Git es un sistema de control de versiones Git funciona con GitHub, Bitbucket o GitLab ¿Por qué usar Git en vez de solo renombrar los archivos? ✅✅Por qué es mejor tener una filogenia del archivo. Git es un sistema de control de versiones distribuido, gratuito y de código abierto, diseñado para manejar todo tipo de proyectos, desde los más pequeños hasta los más grandes, con rapidez y eficiencia. Git es fácil de aprender y ocupa poco espacio con un rendimiento rapidísimo. Supera a las herramientas SCM como Subversion, CVS, Perforce y ClearCase con características como la ramificación local barata, las cómodas áreas de preparación y los múltiples flujos de trabajo. 10.3.1 Git vs controles de versión a mano Con Git cada contribuidor tiene una copia del repositorio central, con todos los archivos y la historia de los cambios por los que han pasado. Excuse me, do you have a moment to talk about version control?, Jennifer Bryan, 2017 ⚠️ NO OLVIDES TENER INSTALADO Git, en caso de que aún no lo hayas instalado, lo puedes descargar en el siguiente enlace https://git-scm.com/downloads. Para conocer la localización y la versión de Git que tienes en tu computadora, corre el siguiente comando en la terminal: which git y git --version 10.4 Recomendaciones para sus proyectos Dedicar un directorio Es mejor organizarlo en un RStudio Project Hacer un repositorio de Git Trabajen como siempre, solo además de guardar, recuerden hacer commit De vez en vez hagan push de sus cambios cuando los hayan verificado. 10.5 Proyectos colaborativos GitHub se parece más a un GoogleDoc que a un Word Document. Es fácil que los colaboradores hagan cambios y también es fácil saber quién hizo que. El owner del proyecto puede dar permisos a los diferentes colaboradores. También existen organizaciones, esto puede ser útil para manejar los permisos de grupos grandes de colaboración. 10.6 GitHub GitHub es una plataforma para guardar proyectos, hace uso de Git. Su principal utilidad es para generar código fuente de programas. ⚠️ NO OLVIDES TENER UNA CUENTA EN GITHUB, en caso de que aún no lo hayas hecho, puedes ir la página de GitHub y seleccionar join. Es indispensable tu usuario para los ejercicios que siguen. También existen otras plataformas como Bitbucked y GitLab, las cuales funcionan de manera similar a GitHub. 10.7 Manual de sobreviviencia con Git Y GitHub en RStudio (en caso de ser necesario) Por cualquier problema con la conexión entre RStudio y Git, siempre ten en cuenta la ubicación de dónde se instaló Git. Puedes usar en la terminal which git (Mac y Linux) O bien usar en la terminal where git (Windows) Recuerda que la terminal (o línea de comandos ó consola ó shell ó bash) es un programa en tu computadora que funciona para correr otros programas. Desde RStudio puedes abrir la terminal, lo cual es muy conveniente si estás trabajando en un proyecto. Puedes abrir una terminal con: Tools > Terminal (abre la terminal dentro del IDE de RStudio) Tools > Shell (abre una terminal externa a RStudio) 10.8 Cómo clonar un repositorio y tener conección/permisos para modificarlo? Git puede comunicarse con un servidor remoto usando uno de dos protocolos, HTTPS o SSH, y cada protocolo usa credenciales diferentes. La recomendación actual de GitHub es usar HTTPS porque es la manera más fácil de configurar y tiene operabilidad en multiples redes y plataformas. Es menos probable que HTTPS sea bloqueado por un firewall. Una conexión HTTPS permite que credential.helper almacene en caché su contraseña. (por tanto puedes configurar tu usuario y contraseña en tu equipo de uso) Es más sencillo acceder a un repositorio desde cualquier lugar, ya que solo necesitas los detalles de tu cuenta (no se requieren claves SSH) para escribir en el repositorio. Usualmente cuando inicies un proyecto colaborativo con GitHub inicializa el ropositorio con un README. Copia el HTTPS URL para clonar el repositorio en la terminal git clone https://github.com/TU-USUARIO/TU-REPOSITORIO.git. 10.9 Credenciales HTTPS en Cache Para usar HTTPS debes crear un token de acceso personal, PAT (PERSONAL ACCESS TOKEN), esa será tu credencial para HTTPS. Es una alternativa al uso de contraseñas para la autenticación en GitHub. Como precaución de seguridad, GitHub elimina automáticamente los tokens de acceso personales que no se han usado durante un año. ¿Cómo crear un token? Ve a tu perfil de GitHub, dale click a la imagen de perfil (usualmente en la esquina superior derecha), y busca la opción de settings ó configuración según sea la configuración de idioma que tengas. Da click a continuación en Developer settings ó Parámetros del desarrollador. En la barra lateral izquierda da click en Tokens de acceso personal. Haz click en Generar un nuevo token. Asígna un nombre descriptivo a tu token. Selecciona los alcances o permisos que deseas otorgarle a este token. Para usar tu token para acceder a repositorios desde la línea de comando, selecciona repo. (Recomendados: repo, user, workflow ) Finalmente haz click en generar token. Listo, copia y pega tu token en el lugar dónde siempre lo puedas volver a copiar, ya que por razones de seguridad, una vez salgas de la página no podrás volver a ver el token. Nota: Preserva tus tokens de la misma manera que tus contraseñas y no se las reveles a nadie. Una vez que tengas un token, puedes ingresarlo en lugar de tu contraseña cuando realices operaciones de Git a través de HTTPS. El punto final es que una vez configurada una PAT, varios paquetes de R, incluidos usethis y gh, podrán trabajar con la API de GitHub en su nombre, de forma automática. Por lo tanto, una PAT configurada correctamente significa que todo esto funcionará a la perfección: - Operaciones HTTPS remotas a través de la línea de comando Git y, por lo tanto, a través de RStudio - Operaciones HTTPS remotas a través del paquete gert R y, por lo tanto, usethis - Operaciones de la API de GitHub a través del paquete gh R y, por lo tanto, usethis Probar el repositorio Clonado Después de hacer clone Usa estos comandos para verificar tu repositorio y revisar desde dónde se está sincorinzando. cd myrepo ls -la head README.md git remote show origin Probemos haciendo un cambio en el README echo "Something I want to add to the README in my local computer" >> README.md git status Qué pasó? Ahora tenemos que decirle a git que queremos seguir los cambios de ese archivo Vamos a commit los cambios y luego a subir (push) los mismos a GitHub git add README.md git commit -m "A commit from my local computer" git push Recuerda tu TOKEN!! ¿Cómo crear un token desde R? Puedes ir directamente a la página de GitHub a la parte para generar tu token de acceso personal mediante la siguiente función: usethis::create_github_token() Y con las opciones que se mencionaban anteriormente puedes configurar y crear tu PAT. Si lo que quieres es especificar tu PAT en RStudio, las siguientes funciones te serán útiles: library(gitcreds) gitcreds_set() library(credentials) set_github_pat() Para eliminar credenciales utiliza la función credentials::git_credential_forget() 10.9.1 Actividad Ejecuta los códigos y genera tu PAT, recuerda no perderlo! 10.10 Conectando RStudio con Git y Github. Para lo que sigue a continuación, deberías tener esto: Tener una cuenta en GitHub R y RStudio actualizados Git instalado Saber que desde la terminal puedes hacer push y pull 10.11 GitHub primero, RStudio después… Crea un repositorio en GitHub: mi_repositorio > Public > YES initialize this repository with a README > clicken el gran botón verde “Create repository” En RStudio crea un nuevo proyecto: File > New Project > Version Control > Git. Ahi pega el URL del repositorio https://github.com/mi_usuario/mi_repositorio.git. Da click en Create Project. Esto nos generará los siguientes elementos: Un directorio nuevo Un repositorio Git enlazado a al repositorio de GitHub Un proyecto en RStudio Con este procedimiento ya no es necesario preocuparse por configurar controles remotos Git y rastrear ramas en la línea de comandos. 10.11.1 Actividad Genera un repositorio con el nombre que desees. Y conéctalo a RStudio. Cerciorate de que el archivo README se encuentre en tu nueva carpeta. Usa la función usethis::use_r(\"titulo_de_un_script\") y observa lo que sucede. PAUSA ¿Cómo comento y doy push/pull desde RStudio? 10.11.2 Comentar, pull y push Con la flecha azul podemos hacer pull (RECUERDA HACERLO ANTES DE HACER UN PUSH), y con la flecha verde un push. Para poder comentar y hacer push debemos marcar con una flechita mediante un click en las pequeñas cajas blancas de la columna Staged, damoc click en commit lo cual no abre la siguiente ventana. Volvemos a dar click en commit, y finalizamos con push (flecha verde). 10.12 Rmarkdown en GitHub Creemos un Rmakrdown y subámoslo a GitHub Ahora hay que agregarlo al repositorio (add), stage and commit. Subieron el hmlt? Qué tal se ve? No se ve como queremos, verdad? Para eso necesitamos recuperar el .md. El .md es un resultado intermedio de crear el html desde Rmd. Tenemos que cambiar el header para esto --- title: "RmarkwondTest" output: html_document: keep_md: true --- 10.12.1 Actividad Usa el código dir.create(\"mis_imagenes\") en la consola de tu sesión de RStudio (la que está vinculada a tu repositorio). Ejecuta el siguiente código quitando los #: install.packages("MASS") library (MASS) data(MASS::cats) # pdf("mis_imagenes/cats_plot.pdf") ggplot(cats, aes(x = Sex)) + geom_bar(fill = "orange", color = "black") + theme_classic() + xlab("Sexo") + ylab("Número de Gatos") + ggtitle("Gatos") # dev.off() Comenta y da push a los cambios que realizaste en el repositorio. 10.13 RStudio primero y GitHub también Usa uno de los proyectos que hayas generado en las sesiones anteriores, PERO, que no esté enlazado a GitHub. Ahora veremos como conectar un proyecto de R existente con GitHub. Realiza los pasos que hicimos en GitHub primero, RStudio después pero asegurate de crear un repositorio con un nuevo nombre. Y LISTO!! usa un simple ctrl + c, ó mv ó click derecho + copiar ó el método que prefieras para mover o copiar archivos. Copia los archivos de tu antigüo proyecto al proyecto nuevo. Solo haz commit y push y listo, lo que tenía en tu antigüo proyecto ya está enlazado a GitHub. 10.14 Proyecto existente, GitHub al final Supongamos que tenemos un proyecto de R existente en algún lugar de nuestra computadora. NOTA: Para generar proyecto de RStudio desde la consola puedes utilizar el siguiente código: usethis::create_project() O en RStudio con File > New Project > Existing Directory Si su proyecto ya es un proyecto de RStudio, ejecútelo. ¿Ya es un repositorio de Git? La presencia del panel de Git debería alertarlo. Si es así, ha terminado. Sino este es el primer camino a seguir: Con el páquete usethis usa la función usethis::use_git En RStudio ve a Tools > Project Options > Git/SVN. Dentro de Version control system, selecciona Git. Y da click a “Yes” cuando aparezca “Confirm New Git Repository?”. Si usaste RStudio o usethis, el proyecto debería reiniciarse en RStudio. Hazlo tu mismo si hizo git init. RStudio ahora debería tener un panel Git. 10.14.1 Breviario cultural con los PATs Si usas el paquete usethis Y has configurado un token de acceso personal (PAT) de GitHub has esto en R: usethis::use_github() Esto creará un nuevo repositorio en GitHub, lo agregará como un control remoto, configurará una rama de seguimiento y lo abrirá en su navegador. Lea la ayuda de use_github() para conocer sus argumentos y consejos sobre cómo configurar una PAT. Esto es extremadamente útil para una variedad de flujos de trabajo que llaman a la API de GitHub. Considere configurar esto si usa usethis, devtools o gh con regularidad. Volviendo al tema de Proyecto existente, GitHub al final. Otra opción que se puede hacer para conectar un proyecto existen a GitHub es ir a hacer un repositorio a GitHub PERO ten en cuenta los siguientes cambios: Elije un nombre de repositorio; probablemente debería coincidir con el nombre de su proyecto y directorio local. NO inicialice este repositorio con un archivo README. Todo lo demás es igual a los pasos que hacíamos en GitHub primero, RStudio después… Ahora ve a tu proyecto de RStudio, has clic en los “dos cuadros de color púrpura y un cuadrado blanco” en el panel de Git. Has clic en “Agregar control remoto”. Pegue la URL aquí y elija un nombre remoto, casi con certeza el origin. Ahora “ADD”. Pasado esto deberiamos volver en el cuadro de diálogo “New Branch”. Ingresa “master” como el nombre de la rama y asegúrate de que la opción “Sync branch with remote” esté marcada. Haz clic en “Create”. En el siguiente cuadro de diálogo elije “overwrite”. Ahora solo haz commit/pull/push y cérciorate que FUNCIONE!! 10.15 Git basics: commands Fetch Commits git fetch Create and Switch to a branch git branch [branch-name] git checkout [branch-name] 10.16 Merge conflics A veces, no tan a veces también, las cosas no salen bien a la primera Merging (Fusionar) es una de esas cosas Cuando bajamos un cambio o fusionamos branches esto puede pasar. Primera regla: NO ENTRAR EN PANICO!!! Revisen el status del repositorio. Qué archivo tiene conflicto? 10.17 Merge conflics Abran ese archivo y busquen los problemas de merge. Es fácil, se ven así: <<<<<<< HEAD:index.html <div id="footer">contact : email.support@github.com</div> ======= <div id="footer"> please contact us at support@github.com </div> >>>>>>> issue-5:index.html Editen esa sección, dejen una versión final. Hagan commit y push Si entran en pánico? Aborten la misión! git merge --abort t 10.18 En resumen ¡QUE LA FUERZA TE ACOMPAÑE! "],["solución-de-problemas-con-las-versiones-de-paquetes-de-rstudio..html", "11 Solución de problemas con las versiones de paquetes de Rstudio. 11.1 Diapositivas", " 11 Solución de problemas con las versiones de paquetes de Rstudio. Yalbi Balderas 09 de agosto de 2023 11.1 Diapositivas "],["keynote-convirtiendo-tu-flujo-de-análisis-en-un-paquete-de-rbioconductor..html", "12 Keynote: Convirtiendo tu flujo de análisis en un paquete de R/Bioconductor. 12.1 Diapositivas", " 12 Keynote: Convirtiendo tu flujo de análisis en un paquete de R/Bioconductor. Dr. Leonardo Collado Torres 02 de agosto de 2022 12.1 Diapositivas Puedes encontrar las diapositivas aquí. "],["documentación-de-funciones.html", "13 Documentación de funciones 13.1 Diapositivas 13.2 Links importantes: 13.3 ¿Qué es la documentación de una función y por qué es importante? 13.4 Generacion de la documentacion con ayuda del paquete roxygen 13.5 Antes de empezar…✏️ 13.6 Generacion de un bloque de documentacion con ayuda del paquete roxygen. 13.7 Otros campos de la documentacion.", " 13 Documentación de funciones Andrés Arredondo Cruz 09 de agosto de 2023 13.1 Diapositivas 13.2 Links importantes: Esta lección está basada en algunos manuales sobre documentación: Una viñeta del cranproject El manual de paqutes de r En esta viñeta de cranproject 13.3 ¿Qué es la documentación de una función y por qué es importante? 🙇️ Es la información complementaria que el desarrollador escribe sobre una función y que se accede con ? seguido el nombre de una función actual de un paquete p.ej. ?unafuncion. 📁 La documentación se almacena como un archivo .Rd (“R documentation) en la carpeta man/. 🔎 La documentación usa una síntesis especial, que es distinta a la de r y que está ligeramente basada en LaTeX. 📄 Se puede renderizar como html, pdf o texto sin formato según se necesite. 13.4 Generacion de la documentacion con ayuda del paquete roxygen En un paquete de r y en cualquier ecosistema de devtools no editamos un documento .Rd manualmente. La documentación usa una síntesis parecida a LaTex que puede ser fácil de estropear. Por ventaja existen paquetes como roxigen2. Usar roxigen nos permite usar comentarios especiales sobre el inicio de la función, esto nos da un par de ventajas: ✅ La documentación y la función estarán en un mismo lugar, por lo que si editas la función será mas fácil recordar actualizar la documentcion también. 🎉 Puedes usar markdown en lugar de la síntesis especial para los archivos .Rd 13.5 Antes de empezar…✏️ Vamos a crear un función para nuestro paquete. Supongamos que para nuestro paquete necesitamos una función que calcule la moda. Esta es una forma sencilla de calcular la moda: getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } unique(serievector): Crea un vector que contiene únicamente los valores únicos de la serie de números serievector. match(serievector, uniqv): Encuentra la posición de cada valor de serievector en el vector único uniqv. tabulate(match(serievector, uniqv)): Cuenta cuántas veces aparece cada valor en la serie serievector. which.max(tabulate(match(serievector, uniqv))): Encuentra el índice del valor máximo en el vector de frecuencias. uniqv[which.max(tabulate(match(serievector, uniqv)))]: Devuelve el valor correspondiente al índice calculado, que es la moda. Creamos un ejemplo para ver que funcione: serie_numeros <- c(1, 2, 2, 2, 2, 3, 3, 4, 4, 4) resultado <- getmode(serie_numeros) print(resultado) ## [1] 2 Bien ahora si podemos podemos empezar a usar el paquete de roxygen para documentar nuestra función.. comencemos. 13.6 Generacion de un bloque de documentacion con ayuda del paquete roxygen. Podemos insertar un esqueleto de comentarios de roxygen para ver su síntesis. Colocamos el cursor en algún lugar de la definición de nuestra función y buscamos en la pestaña Código > Insertar Roxygen Skeleton. #' Title #' #' @param serievector #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ahora ya tenemos un esqueleto de la documentación que nos da una ventaja para su creación. Las líneas de comentarios de Roxygen siempre comienzan con #', el habitual para un comentario # mas un ' Veamos los comentarios de uno por uno: Empezamos con el titulo. Se sugiere poner en el titulo las acciones principales que realiza la función en este caso por ejemplo podremos usar: #' @title Encontrar la Moda de una Serie de Números #' #' @param serievector #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Muy bien!. El siguiente comentario que podemos ver es @param. Pero antes, vamos a añadir una pequeña descripción de la función y como usarla. Primero añadimos la pequeña descripción con @description: #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' @param serievector #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ahora vamos a añadir el comentario @usage que nos indica como puedes mandar a llamar la función. #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' @usage getmode(serievector) #' @param serievector #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ahora si vamos a añadir una pequeña descripción de nuestros argumentos. Si tuviéramos mas de un parámetro en nuestra función podríamos llamar las veces que sea necesario el comentario de parámetro con @param, veamoslo. Ahora añadimos una pequeña descripción a nuestro único parámetro que es serievector: #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Después, podemos añadir un comentario de detalles de la función con @details. Por ejemplo, si en nuestro ejemplo tuviéramos ciertos valores no numéricos en nuestro vector de entrada, por ejemplo letras, ¿nuestra función podría leerlas?, o si le diéramos un vector sin caracteres ¿que pasaría?, veamos: serie_numeros <- c(0,2,2,"d", "d","d") resultado <- getmode(serie_numeros) print(resultado) ## [1] "d" serie_numeros <- c() resultado <- getmode(serie_numeros) print(resultado) ## NULL Entonces, esto es un ejemplo de lo que podríamos poner en el comentario @details. Hagamoslo describiendo esto. En details podemos agregar detalles un poco mas específicos que en la descripción de la función #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @details si tu vector de entrada puede ser interpretado alternando números y #' letras escritas entre comillas "". Si un vector esta vacío, dará como #' resultado un NULL. #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ya casi terminamos de llenar nuestra documentación, pero antes vamos a ver algunos otros arrobas que pudieran ser importantes. El @import e @importfrom importan funciones de otros paquetes en caso de que las necesitemos, el primero importa todas las funciones del paquete que que solicites, y el segundo importa solo algunas funciones especificas. En nuestra función no necesitamos llamar funciones de otros paquetes puesto que todas las que usamos están en r base. Pero imaginemos que tu función, por ejemplo necesita leer un archivo .tsv con la función read_tsv del paquete readr y después reconvertir la tabla resultante en un archivo con write.table pero solo necesitas esa función del paquete utils, entonces haríamos: #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @details si tu vector de entrada puede ser interpretado alternando números y #' letras escritas entre comillas "". Si un vector esta vacío, dará como #' resultado un NULL. #' @import readr #' @importFrom utils write.table #' @return #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Así podemos importar las funciones que necesitemos de otros paquetes y se incluirán en la documentación y se cargaran automáticamente al cargar tu paquete. :eyes::exclamation: Para un correcto funcionamiento de tu paquete y al estar los paquetes necesarios incluidos en la documentación, no será necesario llamarlos de la forma ``library(“apackage”)```. Entonces llegamos a la sección @return. Esta descripción le servirá al usuario del paquete para conocer cual sera el resultado de la función, que puede ser un archivo, una tabla, un numero,etc. Entonces retomando la función que usamos al inicio, vamos a escribir una descripción corta del resultado de la función getmode(). #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @details si tu vector de entrada puede ser interpretado alternando números y #' letras escritas entre comillas "". Si un vector esta vacío, dará como #' resultado un NULL. #' @return El carácter con mas frecuencia de el vector de entrada. #' @export #' #' @examples getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Por ultimo tenemos @export que es el encargado de renderizar la documentación para que pueda aparecer en la ventana de Ayuda (abajo a la derecha). esta opción la dejamos para funciones principales que el usuario va a utilizar, aunque puede que existan alguna funciones internas que no queremos que el usuario vea. En ese caso vamos a usar @noRd en lugar de este. Antes de terminar podemos incluir ejemplos de como funciona nuestra función para un mejor entendimiento, pongamos los que ya realizamos: #' @title Encontrar la Moda de una Serie de Números #' #' @description Esta función lee una serie de números en forma de vector y #' encuentra el elemento que mas se repite, es decir la moda. #' #' @param serievector Es una serie de números en forma de un vector simple de r. #' #' @details si tu vector de entrada puede ser interpretado alternando números y #' letras escritas entre comillas "". Si un vector esta vacío, dará como #' resultado un NULL. #' @return El carácter con mas frecuencia de el vector de entrada. #' @export #' #' @examples #' serie_números <- c(1, 2, 2, 2, 2, 3, 3, 4, 4, 4) #' resultado <- getmode(serie_números) #' print(resultado) getmode <- function(serievector) { uniqv <- unique(serievector) uniqv[which.max(tabulate(match(serievector, uniqv)))] } Ahora si, una vez teniendo listo el bloque de comentarios para la documentación, vamos a ejecutar devtools::load_all() para cargar nuestras funciones y hecho esto, ejecutamos devtools::document() o presionamos Ctrl/Cmd + Shift + D para convertir los comentarios en archivo .Rd y poder renderizarlo. 💯 Listo, tenemos nuestra documentación para una función. Así se verá cuando el paquete esté terminado. 13.7 Otros campos de la documentacion. @seealso para indicar funciones relacionadas y facilitar la búsqueda de funciones. @references añade algunas referencias. @author para especificar el autor de la función. "],["diseño-de-pruebas.html", "14 Diseño de pruebas 14.1 Diapositivas", " 14 Diseño de pruebas Mirna Vázquez Rosas-Landa 10 de agosto de 2023 14.1 Diapositivas "],["creación-de-viñetas.html", "15 Creación de viñetas 15.1 Diapositivas 15.2 ¿Qué es una viñeta? 15.3 Características de una vignette 15.4 ¿Cómo consultar la viñeta de un paquete? 15.5 ¿Cómo crear una viñeta? 15.6 ¿Cómo guardar y actualizar la viñeta? 15.7 Veamos un ejemplo 15.8 Actividad", " 15 Creación de viñetas Joselyn Cristina Chávez Fuentes 10 de agosto de 2023 15.1 Diapositivas 15.2 ¿Qué es una viñeta? Es una guía extendida sobre cómo funciona el paquete. Es recomendable que muestre cómo utilizar las funciones del paquete, aplicado en un flujo de trabajo; por ejemplo: el análisis estadístico de una encuesta o el análisis de expresión diferencial de genes. Podemos estructurarlo como haríamos con la escritura de un capítulo de libro o de un artículo científico: debe mostrar el problema a resolver y la metodología paso a paso sobre cómo el paquete lo resuelve. Si el paquete contiene funciones que se complementan entre sí para alcanzar un fin específico, entonces debes mostrar su uso de forma compartamentalizada. 15.3 Características de una vignette Debe mostrar un flujo de análisis explotando el potencial de tu paquete. Implementa tantas funciones de tu paquete como sea posible, pero no es necesario que incluya todas. Los datos a usar deben ser pequeños o fáciles de acceder. Puedes crear múltiples viñetas para mostrar diferentes casos de análisis y cubrir una mayor cantidad de funciones. 15.4 ¿Cómo consultar la viñeta de un paquete? browseVignettes(package = "ggplot2") 15.5 ¿Cómo crear una viñeta? biocthis::use_bioc_vignette("mi_vignette") Esta función tendrá tres efectos: Generar el directorio vignettes en caso que no exista. Agregar dependencias en el archivo DESCRIPTION (por ejemplo, knitr necesario para construir viñetas dentro del paquete). Abrir un templado en formato .Rmd para comenzar a escribir la viñeta, que se va a guardar en vignettes/mi_vignette.Rmd 15.6 ¿Cómo guardar y actualizar la viñeta? Una vez que se ha generado el archivo vignettes/mi_vignette.Rmd se hacen las modificaciones necesarias. Puedes usar el comando: edit_file("vignettes/mi_vignette.Rmd") Para guardar los cambios debes hacer click en el botón Knit o utiliza la combinación de teclas Ctrl/Cmd-Shift-K. 15.7 Veamos un ejemplo Busca la viñeta del paquete regutools en la página de Bioconductor https://bioconductor.org/packages/release/bioc/html/regutools.html 15.8 Actividad Escribe una viñeta que muestre cómo utilizar las funciones para cargar y filtrar los datos de pbmc. "],["compilación-e-instalación-de-paquetes.html", "16 Compilación e instalación de paquetes 16.1 Diapositivas 16.2 Metadatos de una paquetería 16.3 Licencias 16.4 Paqueterías de código fuente 16.5 ¿En dónde podemos encontrar el código fuente de un paquete? 16.6 Instalando la última versión en desarrollo 16.7 Instalando paquetes desde GitHub 16.8 Instalando un paquete local 16.9 Contribuyendo código", " 16 Compilación e instalación de paquetes Joselyn Cristina Chávez Fuentes 10 de agosto de 2023 16.1 Diapositivas 16.2 Metadatos de una paquetería Los metadatos de la paquetería se encuentran en el archivo DESCRIPTION. 16.2.1 Description El campo Description describe lo que hace tu paquetería. Suele ser extenso, si requieres escribir múltiples líneas, deben estar indentadas. Por ejemplo: # Description: Este paquete contiene todas las funciones generadas en el curso # de escritura de paqueterías en R. También contiene las funciones que cada # participante propuso para solucionar un problema relacionado con su trabajo. 16.2.2 Dependencias Las dependencias son las paqueterías que tu paquete necesita para funcionar. La lista de paquetes se escribe separada por comas y es recomendado que se escriban en orden alfabético. Existen tres tipos: Imports: Son paquetes que deben instalarse para que tu paquete funcione y por tanto se van a instalar en el momento que instales el paquete. Internamente existe una función que evalúa si los paquetes se encuentran instalados o no y solamente instala los faltantes. Esta dependencia hace solamente la instalación pero no ejecuta library(), por lo que los paquetes requeridos deberán ser cargados dentro de la escritura del paquete. Depends: Son paquetes que obligatoriamente deben estar para que tu paquetería funcione pero no se instalarán de manera automática. Aquí también se indica la versión de R requerida para el funcionamiento del paquete. Los paquetes que se listen aquí se van a cargar al mismo tiempo que se ejecute el library(mipaquete). Suggests: Se refiere a los paquetes que tu paquete puede utilizar y aprovechar para ser más poderoso en el análsis pero no los necesita para funcionar. Por ejemplo, paquetes que contienen sets de datos para hacer pruebas o análisis de práctica. Nota Importante Se recomienda listar los paquetes necesarios para el funcionamiento de nuestro paquete en Imports porque cuando se ponen en Depends se cargan los paquetes completos y probablemente solamente requerimos una o dos funciones. Cargar demasiados paquetes completos, sin ser necesario, sólo hace que nuestro paquete se vuelva pesado y lento. Es mejor llamar particularmente a las funciones usando la sintaxis explícita: Biostrings::translate() 16.2.3 ¿Cómo añadir dependencias? Usando usethis: usethis::use_package("ggplot2", type = "Imports") Editando manualmente el archivo DESCRIPTION. 16.3 Licencias Establece quién puede usar tu paquete. Existen diversas licencias pero hablaremos sobre las 3 más comunes: MIT (Massachusetts Institute of Technology): es simple y permisiva. Permite a cualquier persona usar y distribuir tu paquetería con una sola restricción: la distribución debe incluir la declaración de licencia del autor. Existe un texto base al cual se le pueden añadir cláusulas o excepciones. Este es un ejemplo: GPL-2 (General Public License): Permite usar y distribuir tu código con la condición que si se genera una versión modificada de tu código, su distribución debe ser también bajo esta licencia. Aunque está enfocada a la distribución de código abierto, permite dejar en claro quién es el autor del material y evitar la apropiación del código por terceros. Un ejemplo de la aplicación de esta licencia es el desarrollo de Linux. CCO: Esta licencia implica que cedes todos los derechos y el código puede ser utilizado con cualquier fin, excepto fines comerciales. Es el más utilizado en los paquetes. Concede el derecho a utilizar y distribuir el material sin requerir el permiso del autor. 16.4 Paqueterías de código fuente En algunas ocasiones necesitaremos instalar paquetes que no se encuentran compilados, por ejemplo: Paquetes en desarrollo de CRAN o Bioconductor. Versiones anteriores de paquetes de CRAN o Bioconductor. Paquetes que no se encuentran depositados en CRAN o Bioconductor, sino en repositorios personales como GitHub. Paquetes que estás desarrollando de forma local. El paquete remotes será de gran utilidad. Regularmente, los paquetes que instalamos desde algún repositorio como CRAN o Bioconductor son paquetes binarios que ya se encuentran compilados previamente. Existen algunas funciones que nos permiten instalar paquetes desde código fuente. Anteriormente, se solían utilizar las funciones install_* del paquete devtools; sin embargo, recientemente se creó el paquete remotes que contiene las mismas funciones pero está específicamente diseñado para ayudarnos a trabajar con paquetes desde código fuente. 16.5 ¿En dónde podemos encontrar el código fuente de un paquete? Si el paquete se encuentra disponible en CRAN, puedes encontrar el link al código fuente en la sección URL. Si el paquete se encuentra disponible en Bioconductor, puedes encontrar el link al código fuente en la sección Package Archives Si el paquete se encuentra en GitHub o GitLab, necesitarás conocer el nombre de usuario y el nombre del paquete. 16.6 Instalando la última versión en desarrollo Si el paquete se encuentra depositado en CRAN podemos usar la función remotes::install_dev("pkgname") Por ejemplo, para instalar la versión en desarrollo de dplyr usaremos el comando remotes::install_dev("dplyr") Si el paquete se encuentra en Bioconductor usaremos la siguiente función: remotes::install_bioc("pkgname") Por ejemplo, para instalar la versión en desarrollo de regutools, el paquete desarrollado por miembros de la CDSB, usaremos el comando remotes::install_bioc("regutools") 16.7 Instalando paquetes desde GitHub Para poder instalar un paquete desde GitHub necesitaremos conocer el usuario del creador y el nombre del repositorio. remotes::install_github("usuario/repositorio") Por ejemplo, para instalar el paquete starwarssay desarrollado por Erick Cuevas (Erickcufe) utilizaremos el siguiente comando: remotes::install_github("Erickcufe/starwarssay") Independientemente de si el paquete se encuentra en CRAN, Bioconductor, o ninguno de ellos, podemos instalar un paquete depositado en una cuenta de GitHub. Para poder instalar un paquete desde GitHub necesitaremos conocer el usuario del creador y el nombre del repositorio donde se encuentra depositado el paquete. Con esta información usaremos la siguiente función: 16.8 Instalando un paquete local Paso 1: Abre el proyecto del paquete que estás desarrollando. Paso opcional: Ejecuta la documentación si realizaste algún cambio. devtools::document() Paso 2: Construye el paquete: devtools::build() Paso 3: Instala el paquete desde tu proyecto actual: devtools::install() 16.9 Contribuyendo código Una ventaja de descargar el paquete de forma local es que puedes realizar cambios, probar que funciona de manera local y después contribuir (haciendo un pull-request). Usemos el paquete saludo Clona el repositorio en tu computadora. git clone https://github.com/ComunidadBioInfo/saludo.git Ahora puedes abrir el proyecto del paquete y agregar tu código. "],["proyectos-colaborativos-1.html", "17 Proyectos colaborativos 17.1 Propuesta 1 17.2 Propuesta 2 17.3 Propuesta 3 17.4 Propuesta 4 17.5 Propuesta 5", " 17 Proyectos colaborativos 17.1 Propuesta 1 Crea un paquete que implemente el análisis de expresión diferencial. Evalúa el funcionamiento del paquete en el análisis de placas calcificadas de Aterogénesis. Puedes descargar los datos de: https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE159677 17.2 Propuesta 2 Realiza la anotación de tipos celulares del sistema inmune en una muestra de médula ósea usando los marcadores propuestos por Human Cell Atlas. Puedes descargar los datos de single-cell de: https://www.10xgenomics.com/resources/datasets/20-k-bone-marrow-mononuclear-cells-bmmn-cs-5-ht-v-2-0-2-high-6-1-0 17.3 Propuesta 3 Realiza el análisis y anotación de tipos celulares en un dataset de cáncer de próstata. Puedes descargar los datos de: https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE157703 17.4 Propuesta 4 Crear un paquete que implemente el análisis de enriquecimiento de los genes diferencialmente expresados. Evalúa el funcionamiento del paquete en el análisis de células neoplásticas en glioblastoma humano. Puedes descargar los datos de: https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE84465 Consulta el artículo original en: https://www.sciencedirect.com/science/article/pii/S2211124717314626?via%3Dihub#app3 17.5 Propuesta 5 Desarrolla un paquete para facilitar la visualización de los tipos celulares de alguno de los datasets mencionados previamente. "],["404.html", "Page not found", " Page not found The page you requested cannot be found (perhaps it was moved or renamed). You may want to try searching to find the page's new location, or use the table of contents to find the page you are looking for. "]]
diff --git "a/docs/selecci\303\263n-de-genes-altamente-variables.html" "b/docs/selecci\303\263n-de-genes-altamente-variables.html"
index e246bd5..5300f1c 100644
--- "a/docs/selecci\303\263n-de-genes-altamente-variables.html"
+++ "b/docs/selecci\303\263n-de-genes-altamente-variables.html"
@@ -1196,10 +1196,10 @@ 

4.16 Recomendaciones para empezar

4.17 Detalles de la sesión de R

## Información de la sesión de R
 Sys.time()
-
## [1] "2023-08-08 17:26:43 EDT"
+
## [1] "2023-08-08 17:43:17 EDT"
proc.time()
##      user    system   elapsed 
-##  1068.631   101.742 95052.699
+## 1559.011 121.615 96046.530
options(width = 120)
 sessioninfo::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────