--- title: "Introducción a easyLSEA" author: "Autores de easyLSEA" date: "`r Sys.Date()`" output: rmarkdown::html_vignette: toc: true toc_depth: 3 vignette: > %\VignetteIndexEntry{Introducción a easyLSEA} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE ) ``` ## Descripción general **easyLSEA** proporciona un pipeline completo para el Análisis de Enriquecimiento de Conjuntos de Lípidos (LSEA, por sus siglas en inglés) en R. A partir de una tabla de abundancias lipídicas diferenciales, el paquete anota los lípidos en grupos biológicos, evalúa si dichos grupos están sistemáticamente desplazados entre condiciones, y genera visualizaciones listas para publicación: bubble plots, gráficos de distribución y análisis de cadenas de ácidos grasos. El paquete implementa dos motores de enriquecimiento complementarios: - **Kolmogorov–Smirnov (KS)** — evalúa si la distribución completa de logFC de un conjunto lipídico difiere del fondo. Es sensible a efectos moderados distribuidos entre muchos miembros del conjunto. - **fgsea** — evalúa si los miembros del conjunto se concentran en los extremos de la lista ordenada. Es sensible a un número pequeño de lípidos fuertemente regulados. Ejecutar ambos motores y comparar sus resultados (análisis de convergencia) ofrece una imagen más completa de la remodelación lipídica que cualquier método por separado. --- ## Instalación Instalar la versión estable desde CRAN: ```{r install-cran} install.packages("easyLSEA") ``` O la versión de desarrollo desde GitHub: ```{r install-github} # install.packages("remotes") remotes::install_github("DavidGO464/easyLSEA") ``` Para activar el motor fgsea, instalar la dependencia opcional de Bioconductor: ```{r install-fgsea} BiocManager::install("fgsea") ``` --- ## Formato de los datos de entrada `easyLSEA` espera un `data.frame` con al menos las siguientes columnas: | Columna | Descripción | |---------|-------------| | `LipidName` | Identificador del lípido en notación abreviada estándar (e.g. `PC 36:4`, `TG 54:3`) | | `logFC` | Cambio en log2 (caso vs referencia) | | `P.Value` | p-valor crudo (sin ajustar) — usado para el ranking pi-valor de fgsea | Columnas adicionales que se usan cuando están presentes: | Columna | Uso | |---------|-----| | `adj.P.Val` | Conteo de lípidos significativamente alterados | | `Confidence_rank` | Filtrado por confianza de anotación | | `Shorthand` | Nombre alternativo del lípido | Los nombres de columna son configurables mediante los argumentos `lipid_col`, `fc_col` y `pval_col`. --- ## Inicio rápido El pipeline completo se ejecuta con una sola llamada a `easyLSEA()`: ```{r quickstart} library(easyLSEA) resultado <- easyLSEA( data = mis_datos_lipidicos, lipid_col = "LipidName", fc_col = "logFC", pval_col = "P.Value", case_lbl = "NASH", ref_lbl = "Control", engine = "both", # ejecutar KS y fgsea min_rank = "E" # incluir todos los ranks excepto P y NA (por defecto) ) ``` Esto devuelve un objeto de clase `easyLSEA_result` con cinco slots descritos en la sección siguiente. --- ## Entendiendo el resultado ### `resultado$meta` Lista con metadatos del análisis: fecha, etiquetas de comparación, motor utilizado, número de lípidos y la llamada original a la función. ```{r meta} resultado$meta$date resultado$meta$case_lbl resultado$meta$n_lipids ``` ### `resultado$lsea` Contiene las estadísticas de enriquecimiento. Los sub-elementos principales son: ```{r lsea} # Resultados KS — una fila por conjunto lipídico por nivel de agrupación head(resultado$lsea$ks) # Resultados fgsea head(resultado$lsea$fgsea) # Tabla combinada con columna de Convergencia head(resultado$lsea$combined) ``` **Columnas principales en los resultados KS:** | Columna | Descripción | |---------|-------------| | `Group` | Nombre del conjunto lipídico (e.g. `PC`, `Glycerolipids`) | | `Level` | Nivel de agrupación (`LipidClass`, `LipidCategory_LMAPS`, `LipidCategory_functional`) | | `N_group` | Número de lípidos en el conjunto | | `DirectionalScore` | Diferencia de medias estandarizada (análogo al *d* de Cohen). Positivo = aumentado en el caso. | | `KS_pval` | p-valor KS bilateral | | `FDR_LSEA` | FDR ajustado por BH | | `DS_perm_pval` | p-valor de permutación para el DirectionalScore | | `ContributingLipids_KS` | Lípidos en el lado enriquecido del punto de máxima divergencia CDF | **Columnas principales en los resultados fgsea:** | Columna | Descripción | |---------|-------------| | `NES` | Puntuación de Enriquecimiento Normalizada. Positivo = enriquecido hacia el tope de la lista (aumentado en el caso). | | `FDR_fgsea` | FDR ajustado por BH de fgsea | | `N_leading` | Tamaño del leading edge | | `LeadingEdge` | Lípidos en el leading edge | | `rank_metric` | Métrica de ranking utilizada (`pi_value`, `logFC` o `t_stat`) | **La columna `Convergence`** en la tabla combinada clasifica cada conjunto como: | Valor | Significado | |-------|-------------| | `KS+fgsea [strongest]` | Significativo por ambos motores — máxima confianza | | `KS only [distributed effect]` | Desplazamiento moderado distribuido en muchos lípidos | | `fgsea only [extreme-driven]` | Pocos lípidos fuertemente regulados impulsan la señal | | `Neither` | No significativo por ningún motor | ### `resultado$chains` Resultados del análisis de cadenas de ácidos grasos, disponible cuando `run_chains = TRUE`: ```{r chains} # Long format — una fila por cadena acilo por lípido head(resultado$chains$parsed) # Resumen del estado de parseo — una fila por lípido head(resultado$chains$summary) # Wide format — una fila por lípido con posiciones sn y totales head(resultado$chains$wide) ``` La tabla `wide` es la más conveniente para reportes. Cada fila es un lípido, con columnas `sn1`, `sn2`, `sn3`, `sn4` con las cadenas individuales (e.g. `"18:1"`), y `total_carbons` / `total_unsat` con los totales sumados. La columna `chain_type` indica cómo interpretar las posiciones sn: | `chain_type` | `sn1` | `sn2` | `sn3` | `sn4` | |---|---|---|---|---| | `sn2` (PC, PE, PS...) | cadena sn-1 | cadena sn-2 | NA | NA | | `nacyl` (Cer, SM...) | base esfingoidea | cadena N-acilo | NA | NA | | `long_format` (TG) | cadena 1 | cadena 2 | cadena 3 | NA | | `long_format` (CL) | cadena 1 | cadena 2 | cadena 3 | cadena 4 | | `single` (CAR, LPC) | la cadena | NA | NA | NA | ### `resultado$plots` Lista de objetos `ggplot2`, disponible cuando `plots = TRUE`: ```{r plots-list} # Ver todos los plots disponibles names(resultado$plots$lsea) names(resultado$plots$chains) ``` Convención de nombres para los bubble plots de LSEA: | Nombre | Descripción | |--------|-------------| | `bubble_ks_01_Class` | Bubble plot KS — nivel de clase lipídica | | `bubble_ks_sig_01_Class` | Bubble plot KS — solo conjuntos significativos | | `bubble_fgsea_01_Class` | Bubble plot fgsea — nivel de clase lipídica | | `bubble_fgsea_sig_01_Class` | Bubble plot fgsea — solo conjuntos significativos | | `dist_01_Class` | Distribución (boxplot) — nivel de clase lipídica | Niveles: `01_Class` (clase lipídica), `02_LMAPS` (categoría LIPID MAPS), `03_Functional` (categoría funcional). ### `resultado$input` Los datos de entrada anotados y las columnas de agrupación utilizadas: ```{r input} # Datos anotados con LipidClass, LipidCategory_LMAPS, etc. head(resultado$input$data) # Columnas de agrupación evaluadas resultado$input$group_cols ``` --- ## Visualización de los gráficos Los gráficos individuales se pueden mostrar directamente: ```{r view-plots} # Bubble plot KS — todas las clases lipídicas resultado$plots$lsea$bubble_ks_01_Class # Bubble plot fgsea — solo conjuntos significativos resultado$plots$lsea$bubble_fgsea_sig_01_Class # Gráfico de distribución — nivel de clase lipídica resultado$plots$lsea$dist_01_Class ``` Para personalizar las etiquetas del bubble plot: ```{r bubble-label} # Regenerar plots mostrando solo FDR y n plots <- plot_lsea( resultado$lsea, case_lbl = "NASH", ref_lbl = "Control", bubble_label = c("FDR", "n") ) ``` --- ## Exportación de resultados `export_lsea()` guarda todos los resultados en una carpeta con marca de tiempo. Indica el directorio de salida explícitamente mediante `dir` (aquí un directorio temporal; para un análisis real usa una carpeta de tu elección): ```{r export} export_lsea( resultado, dir = tempdir(), format = c("csv", "excel", "pdf") ) ``` Esto genera la siguiente estructura: ``` easyLSEA_NASH_vs_Control_2024-01-15_1430/ tables/ lsea_results_ks.csv lsea_results_fgsea.csv lsea_combined.csv chain_results.csv plots/ lsea/ 01_Class/ bubble_ks_01_Class.pdf bubble_ks_sig_01_Class.pdf bubble_fgsea_01_Class.pdf bubble_fgsea_sig_01_Class.pdf dist_01_Class.pdf 02_LMAPS/ ... 03_Functional/ ... chains/ tile/ ... trend/ ... results.xlsx ``` --- ## Uso avanzado ### Ejecutar los motores por separado ```{r advanced-separate} # Paso 1: anotar anotado <- annotate_lipids(mis_datos_lipidicos, lipid_col = "LipidName") # Paso 2: ejecutar el enriquecimiento lsea_res <- run_lsea( data = anotado, fc_col = "logFC", engine = "both", case_lbl = "NASH", ref_lbl = "Control" ) # Paso 3: generar plots manualmente plots <- plot_lsea( lsea_res, case_lbl = "NASH", ref_lbl = "Control", fdr_thresh = 0.05, bubble_label = c("FDR", "DS", "NES", "n") ) # Paso 4: gráfico de distribución para un nivel específico p_dist <- plot_distribution( data = anotado, lsea_result = lsea_res, group_col = "LipidClass", case_lbl = "NASH", ref_lbl = "Control" ) ``` ### Cambiar la métrica de ranking de fgsea ```{r fgsea-rank} # Por defecto: pi-valor = signo(logFC) × −log10(P.Value) # Combina magnitud del efecto y significancia estadística # Alternativa: solo logFC resultado_fc <- easyLSEA( data = mis_datos_lipidicos, engine = "fgsea", fgsea_rank = "logFC" ) # Alternativa: estadístico t de LIMMA (requiere columna 't') resultado_t <- easyLSEA( data = mis_datos_lipidicos, engine = "fgsea", fgsea_rank = "t_stat" ) ``` ### Ajustar umbrales de significancia ```{r thresholds} resultado <- easyLSEA( data = mis_datos_lipidicos, min_n = 5L, # mínimo 5 lípidos por conjunto n_perm = 5000L, # más permutaciones para DS_perm_pval fgsea_nperm = 20000L # más permutaciones para fgsea ) ``` ### Filtrar por nivel de confianza de anotación Cuando las anotaciones lipídicas incluyen un rank de confianza (A > B > C > D > E > P), el parámetro `min_rank` controla qué lípidos entran al análisis de cadenas: ```{r min-rank} # Por defecto: incluye todos excepto P y NA resultado_todos <- easyLSEA(data = mis_datos_lipidicos, min_rank = "E") # Estricto: solo anotaciones de alta confianza (A y B) resultado_estricto <- easyLSEA(data = mis_datos_lipidicos, min_rank = "B") # O directamente en parse_lipid_chains cadenas_estrictas <- parse_lipid_chains(anotado, min_rank = "B") table(cadenas_estrictas$summary$status) ``` Los lípidos excluidos por `min_rank` aparecen en `resultado$chains$summary` con status `excluded_rank_below_X` (donde X es el umbral elegido), facilitando auditar qué lípidos fueron filtrados. --- ## Interpretación de los resultados ### KS vs fgsea — ¿cuál usar? Ambos motores evalúan la misma hipótesis nula (ausencia de enriquecimiento sistemático) pero son sensibles a patrones de señal distintos: - **KS** es potente cuando muchos lípidos de una clase se desplazan moderadamente en la misma dirección. Un resultado KS significativo con `DirectionalScore ≈ 0` sugiere una diferencia en varianza o forma de la distribución, no un desplazamiento neto — interpretar con precaución. - **fgsea** es potente cuando un número reducido de lípidos genera una señal extrema. Un resultado fgsea significativo sin respaldo del KS sugiere que el enriquecimiento es impulsado por pocos lípidos, no por la clase en su conjunto. Los **resultados convergentes** (significativos por ambos motores) proporcionan la evidencia más sólida de remodelación coordinada de una clase lipídica. ### El DirectionalScore El `DirectionalScore` es una diferencia de medias estandarizada (análogo al *d* de Cohen): ``` DS = (media_logFC_conjunto − media_logFC_fondo) / DS_combinada ``` Cuantifica la **dirección y magnitud** del desplazamiento, independientemente del p-valor KS. Un conjunto puede tener un p-valor KS significativo con un DirectionalScore cercano a cero — este patrón sugiere regulación heterogénea dentro del conjunto. ### La métrica pi-valor Por defecto, fgsea ordena los lípidos por: ``` pi-valor = signo(logFC) × −log10(P.Value) ``` Esta métrica combina la dirección del cambio con la confianza estadística, dando mayor peso a los lípidos que están regulados de forma tanto intensa como significativa. Se prefiere al logFC solo cuando los p-valores están disponibles. --- ## Información de la sesión ```{r session, eval = TRUE} sessionInfo() ```