Análisis de Expresión Diferencial

Autor/a

Mario Pascual González

1 Datos y Directorio de Trabajo

En esta sección, se importa y organiza la información de los datos de expresión diferencial, estableciendo una base para el análisis posterior. Esto incluye la lectura de los archivos de datos, la creación de un objeto adecuado para el análisis y la asignación de los nombres de las muestras y grupos experimentales.

Se importan los datos de expresión diferencial en R utilizando el paquete edgeR. Este código se encarga de leer los datos desde archivos y almacenarlos en un objeto adecuado para su posterior análisis.

Código
### Importamos los datos al objeto DGE###

## Del primer fichero se leen las primeras cinco filas para inspeccionar la estructura del archivo ###
knitr::kable(read.delim(files[1], nrow=5))
EntrezID GeneLength Count
497097 3634 1
100503874 3259 0
100038431 1634 0
19888 9747 0
20671 3130 1
Código
## Se crea el objeto DGEList con todos los archivos y se incluye toda la información necesaria, como el nombre de muestra y el grupo al que pertenece (factor) ###
x <- readDGE(files, columns=c(1,3))

## Se inspecciona el objeto DGEList para confirmar su correcta creación ###
knitr::kable(x$samples)
files group lib.size norm.factors
GSM1545535_10_6_5_11 GSM1545535_10_6_5_11.txt 1 32863052 1
GSM1545536_9_6_5_11 GSM1545536_9_6_5_11.txt 1 35335491 1
GSM1545538_purep53 GSM1545538_purep53.txt 1 57160817 1
GSM1545539_JMS8-2 GSM1545539_JMS8-2.txt 1 51368625 1
GSM1545540_JMS8-3 GSM1545540_JMS8-3.txt 1 75795034 1
GSM1545541_JMS8-4 GSM1545541_JMS8-4.txt 1 60517657 1
GSM1545542_JMS8-5 GSM1545542_JMS8-5.txt 1 55086324 1
GSM1545544_JMS9-P7c GSM1545544_JMS9-P7c.txt 1 21311068 1
GSM1545545_JMS9-P8c GSM1545545_JMS9-P8c.txt 1 19958838 1

En este código, se realiza la lectura preliminar de las primeras cinco filas del primer archivo para comprender su estructura. Luego, se utiliza la función readDGE para crear un objeto DGEList que contiene los datos de todos los archivos especificados en la variable files, incluyendo las columnas que contienen los identificadores de las muestras y los valores de expresión. Finalmente, se inspecciona el objeto DGEList creado para verificar su tipo, dimensiones y contenido.

Posteriormente, se organiza la información del diseño experimental para preparar los datos de expresión diferencial para su análisis en R. Este código se encarga de extraer y asignar nombres de muestras y de definir los grupos experimentales a los que pertenecen las muestras.

Código
### Organizamos la información del diseño experimental ###

## Se extraen los nombres de las muestras eliminando caracteres innecesarios de los nombres de las columnas ###
samplenames <- substring(colnames(x), 12, nchar(colnames(x)))

## Se actualizan los nombres de las columnas del objeto con los nombres de las muestras ###
colnames(x) <- samplenames

## Se crea un factor que representa las condiciones experimentales de cada muestra ###
group <- as.factor(c("LP", "ML", "Basal",
                     "Basal", "ML", "LP",
                     "Basal", "ML", "LP"))

## Se incorpora la información de las condiciones experimentales en el objeto DGEList ###
x$samples$group <- group
knitr::kable(x$samples)
files group lib.size norm.factors
10_6_5_11 GSM1545535_10_6_5_11.txt LP 32863052 1
9_6_5_11 GSM1545536_9_6_5_11.txt ML 35335491 1
purep53 GSM1545538_purep53.txt Basal 57160817 1
JMS8-2 GSM1545539_JMS8-2.txt Basal 51368625 1
JMS8-3 GSM1545540_JMS8-3.txt ML 75795034 1
JMS8-4 GSM1545541_JMS8-4.txt LP 60517657 1
JMS8-5 GSM1545542_JMS8-5.txt Basal 55086324 1
JMS9-P7c GSM1545544_JMS9-P7c.txt ML 21311068 1
JMS9-P8c GSM1545545_JMS9-P8c.txt LP 19958838 1

En el código superior, se procesan los nombres de las muestras al eliminar caracteres innecesarios, asignando nombres claros y concisos a las columnas del objeto DGEList. Luego, se crea un factor que indica a qué grupo experimental pertenece cada muestra. Finalmente, se añade esta información de los grupos experimentales al objeto DGEList, integrando así todos los datos necesarios para el análisis.

2 Anotación Génica y Transformación de los Datos de Expresión

En esta sección, se añade información de anotación génica a los datos de expresión y se transforman las lecturas a cuentas por millón (CPM), en base logarítmica. Adicionalmente, se filtran los genes con baja expresión para asegurar que solo los genes relevantes sean considerados en el análisis y se generan representaciones gráficas de las cuentas por millón (CPM) antes y después del filtrado para visualizar y comparar la distribución de los datos de expresión.

Primero se incorpora un fichero de anotación génica para aportar información adicional sobre los genes a los datos de expresión diferencial. Este código se encarga de crear objetos con los identificadores y nombres de los genes, y de eliminar duplicados para asegurar la unicidad de los IDs.

Código
### Incorporamos fichero de anotación génica ###

## Se crea un objeto que contiene los IDs de los genes a partir de las filas del objeto DGEList ###
geneid <- rownames(x)
knitr::kable(head(geneid))
x
497097
100503874
100038431
19888
20671
27395
Código
## Se crea un objeto que contiene los nombres de los genes y su cromosoma utilizando el paquete Mus.musculus ###
genes <- select(Mus.musculus, keys=geneid, columns=c("SYMBOL", "TXCHROM"), keytype="ENTREZID")
knitr::kable(head(genes))
ENTREZID SYMBOL TXCHROM
497097 Xkr4 chr1
100503874 Gm19938 NA
100038431 Gm10568 NA
19888 Rp1 chr1
20671 Sox17 chr1
27395 Mrpl15 chr1
Código
## Se eliminan los genes duplicados para asegurar que cada ID de gen sea único ###
genes <- genes[!duplicated(genes$ENTREZID),]

## Se incorpora la anotación génica al objeto DGEList ###
x$genes <- genes
knitr::kable(x$samples)
files group lib.size norm.factors
10_6_5_11 GSM1545535_10_6_5_11.txt LP 32863052 1
9_6_5_11 GSM1545536_9_6_5_11.txt ML 35335491 1
purep53 GSM1545538_purep53.txt Basal 57160817 1
JMS8-2 GSM1545539_JMS8-2.txt Basal 51368625 1
JMS8-3 GSM1545540_JMS8-3.txt ML 75795034 1
JMS8-4 GSM1545541_JMS8-4.txt LP 60517657 1
JMS8-5 GSM1545542_JMS8-5.txt Basal 55086324 1
JMS9-P7c GSM1545544_JMS9-P7c.txt ML 21311068 1
JMS9-P8c GSM1545545_JMS9-P8c.txt LP 19958838 1

En este código, se extraen los identificadores de los genes de las filas del objeto DGEList y se almacenan en un nuevo objeto. Luego, se utiliza la función select del paquete Mus.musculus para obtener los nombres y los cromosomas de los genes asociados a estos identificadores. Los duplicados se eliminan para asegurar que cada identificador de gen sea único. Finalmente, se integra esta información de anotación génica en el objeto DGEList, enriqueciendo los datos de expresión con información adicional sobre los genes.

Se transforman las lecturas mapeadas a cuentas por millón (CPM) y se filtran los genes con baja expresión para preparar los datos de expresión diferencial para un análisis más preciso.

Código
## Transformamos las lecturas mapeadas a cuentas por millón, también en base logarítmica ###
cpm.raw <- cpm(x)
lcpm.raw <- cpm(x, log=TRUE)

## Se cuentan los genes que no tienen valor de expresión en ninguna de las muestras ###
knitr::kable(table(rowSums(x$counts == 0) == 9))
Var1 Freq
FALSE 22026
TRUE 5153
Código
## Se filtran los genes con baja expresión, manteniendo aquellos que tienen una expresión mayor a 1 CPM en al menos 3 muestras ###
keep.exprs <- rowSums(cpm.raw > 1) >= 3
x.filt <- x[keep.exprs, , keep.lib.sizes=FALSE]

## Se muestran las dimensiones del objeto filtrado ###
print(paste("Dimensiones del objeto filtrado:", sep=" "))
[1] "Dimensiones del objeto filtrado:"
Código
print(dim(x.filt))
[1] 14165     9

En este código, se transforman las lecturas de los datos de expresión a cuentas por millón (CPM) y se calculan también en escala logarítmica para normalizar los datos. Luego, se cuenta el número de genes que no tienen ningún valor de expresión en todas las muestras. Para mejorar la calidad del análisis, se filtran los genes con baja expresión, reteniendo solo aquellos genes que tienen una expresión mayor a 1 CPM en al menos tres muestras. Finalmente, se verifica la cantidad de genes y muestras en el objeto filtrado x.filt para asegurarse de que el filtrado se haya realizado correctamente.

Código
### Representación gráfica de las cpm antes y después de filtrar ###
dev.new()
nsamples <- ncol(x.filt)
col <- brewer.pal(nsamples, "Paired")

# Gráfica para los datos en bruto
par(mfrow=c(1,1))

Gráficas 2.1: Comparación de la Distribución de CPM en Datos en Bruto y Filtrados

Código
plot(density(lcpm.raw[,1]), col=col[1], lwd=2, ylim=c(0,0.21), las=2,
     main="", xlab="", ylab="Densidad")
title(main="A. Datos en bruto", xlab="Log-cpm") # Se cambia el nombre por defecto del eje Y
abline(v=0, lty=3) # Se marca el umbral del filtrado
for (i in 2:nsamples){
    den <- density(lcpm.raw[,i])
    lines(den$x, den$y, col=col[i], lwd=2)
}
legend("topright", samplenames, text.col=col, bty="n")

Código
# Gráfico con los datos filtrados
lcpm.filt <- cpm(x.filt, log=TRUE)
plot(density(lcpm.filt[,1]), col=col[1], lwd=2, ylim=c(0,0.21), las=2,
     main="", xlab="", ylab="")
title(main="B. Filtrado", xlab="Log-cpm", ylab="Densidad") # Se cambia el nombre por defecto del eje Y
abline(v=0, lty=3) # Se marca el umbral del filtrado
for (i in 2:nsamples){
    den <- density(lcpm.filt[,i])
    lines(den$x, den$y, col=col[i], lwd=2)
}
legend("topright", samplenames, text.col=col, bty="n")

Las Gráficas 2.1, presentan dos gráficos de densidad que muestran la distribución de las cuentas por millón (CPM) en escala logarítmica antes (superior, A. Datos en bruto) y después (inferior, B. Filtrado) del filtrado de genes con baja expresión.

En el panel A, que representa los datos en bruto, se observa una alta densidad de valores de expresión cercanos a cero, indicando la presencia de muchos genes con baja o nula expresión en las muestras. Después del filtrado, en el panel B, la distribución se vuelve más uniforme y centrada, eliminando la mayoría de los genes con baja expresión. Este proceso de filtrado mejora la calidad de los datos al excluir genes no informativos, permitiendo un análisis más robusto de la expresión diferencial.

La leyenda en ambos gráficos identifica las muestras, coloreadas para facilitar la comparación visual. La línea vertical punteada en ambos gráficos marca el umbral de filtrado, mostrando que el filtrado ha removido adecuadamente los genes con valores de CPM por debajo de este umbral.

2.1 Normalización de los Datos

Se normalizan los datos de expresión para ajustar las diferencias en la profundidad de secuenciación entre las muestras. Además, se representa gráficamente la distribución de los factores de normalización para evaluar la eficacia del proceso de normalización.

Código
### Normalización de datos de expresión ###

## Se calculan los factores de normalización utilizando el método TMM (Trimmed Mean of M-values) ###
x.norm <- calcNormFactors(x.filt, method = "TMM")

## Se muestran los factores de normalización calculados para cada muestra ###
x.norm$samples$norm.factors
[1] 0.8957309 1.0349196 1.0439552 1.0405040 1.0323599 0.9223424 0.9836603
[8] 1.0827381 0.9792607
Código
### Representación de los factores de normalización ###

dev.new()
par(mfrow=c(1,2))

Gráficas 2.2: Boxplot de Factores de Normalización

Código
## Se crea un boxplot de los factores de normalización para todas las muestras ###
boxplot(x.norm$samples$norm.factors, xlab="Todas las muestras", ylab="Valor de norm.factors", main="Distribución de todos los norm.factors")

Código
## Se crea un boxplot de los factores de normalización para cada muestra individualmente ###
boxplot(x.norm$samples$norm.factors ~ rownames(x.norm$samples), ylab="Valor de norm.factors", main="B. Norm.factors por muestra", las=2)

## Se añade una línea horizontal que marca el valor 1.0, indicando el valor de referencia para los factores de normalización ###
abline(h=1.0, lty=3)

En este código, se realiza la normalización de los datos de expresión utilizando el método TMM (Trimmed Mean of M-values), que ajusta las diferencias en la profundidad de secuenciación entre las muestras para obtener datos comparables. Los factores de normalización calculados para cada muestra se muestran para verificar que la normalización se ha aplicado correctamente. Luego, se generan dos gráficos de caja (boxplots) para representar la distribución de estos factores de normalización. El primer gráfico muestra la distribución de los factores de normalización para todas las muestras en conjunto, mientras que el segundo gráfico presenta estos factores para cada muestra individualmente, facilitando la identificación de posibles discrepancias.

Se representan gráficamente los datos de expresión en estado bruto y después de la normalización para comparar la distribución de los datos. Además, se generan gráficos MDS (Multidimensional Scaling) para visualizar las relaciones entre las muestras antes y después del filtrado y la normalización.

Código
## Boxplot de los datos en bruto ###
boxplot(lcpm.raw, las=2, col=col, main="")
title(main="A. Datos brutos", ylab="Log-cpm")

Código
## Boxplot de los datos normalizados ###
lcpm.norm <- cpm(x.norm, log=TRUE)
boxplot(lcpm.norm, las=2, col=col, main="")
title(main="B. Datos normalizados", ylab="Log-cpm")

Comparando las Gráficas 2.3 y 2.4, se puede concluir que los boxplots muestran que las distribuciones de las CPM logarítmicas son más consistentes entre las muestras después de la normalización en comparación con los datos en bruto. Esta uniformidad indica que la normalización ha ajustado eficazmente las diferencias en la profundidad de secuenciación, mejorando la comparabilidad de los datos de expresión entre las muestras. Además, la presencia de más valores atípicos en los datos normalizados sugiere una mayor precisión en la detección de variaciones genuinas en los niveles de expresión génica.

Código
### Gráficos MDS para datos brutos, filtrados y normalizados ###

dev.new()
par(mfrow=c(1,3))

## Definición de colores por grupo experimental ###
col.group <- group
levels(col.group) <- brewer.pal(nlevels(col.group), "Set1")
col.group <- as.character(col.group)
Código
## Gráfico MDS para datos en bruto ###
plotMDS(lcpm.raw, labels=group, col=col.group)
title(main="Raw: by sample groups")

Código
## Gráfico MDS para datos filtrados ###
plotMDS(lcpm.filt, labels=group, col=col.group)
title(main="Filtered: by sample groups")

Código
## Gráfico MDS para datos normalizados ###
plotMDS(lcpm.norm, labels=group, col=col.group)
title(main="Normalised: by sample groups")

En la Gráfica 2.5 (Raw: by sample groups), se observa que las muestras presentan una dispersión significativa, indicando variabilidad en las lecturas originales sin ningún procesamiento adicional. En la Gráfica 2.6 (Filtered: by sample groups), después del filtrado de genes con baja expresión, las muestras muestran una agrupación más clara, reflejando una reducción en el ruido de los datos. Finalmente, en la Gráfica 2.7 (Normalised: by sample groups), tras la normalización, las muestras se agrupan más estrechamente dentro de sus respectivos grupos experimentales. Esta progresión desde los datos en bruto hasta los datos normalizados evidencia cómo el filtrado y la normalización mejoran la claridad y precisión de la discriminación entre los grupos experimentales, permitiendo un análisis diferencial más robusto.

3 Diseño Experimental y Comparaciones

Se establece el diseño experimental para el análisis diferencial de expresión y se definen las comparaciones específicas a realizar entre los grupos experimentales. Esto incluye la creación de una matriz de diseño y una matriz de contrastes que especifica las comparaciones de interés.

Código
### Diseño experimental ###

## Se crea la matriz de diseño basada en los grupos experimentales ###
design <- model.matrix(~0 + group)

## Se simplifican los nombres de las columnas eliminando el prefijo "group" ###
colnames(design) <- gsub("group", "", colnames(design))
design
  Basal LP ML
1     0  1  0
2     0  0  1
3     1  0  0
4     1  0  0
5     0  0  1
6     0  1  0
7     1  0  0
8     0  0  1
9     0  1  0
attr(,"assign")
[1] 1 1 1
attr(,"contrasts")
attr(,"contrasts")$group
[1] "contr.treatment"
Código
### Comparaciones a realizar ###

## Se crea una matriz de contrastes para especificar las comparaciones entre los grupos experimentales ###
contr.matrix <- makeContrasts(
    BasalvsLP = Basal - LP,
    BasalvsML = Basal - ML,
    LPvsML = LP - ML,
    levels = colnames(design)
)
contr.matrix
       Contrasts
Levels  BasalvsLP BasalvsML LPvsML
  Basal         1         1      0
  LP           -1         0      1
  ML            0        -1     -1

Se establece el diseño experimental creando una matriz de diseño que incluye los grupos experimentales, eliminando el prefijo “group” de los nombres de las columnas para simplificar. Posteriormente, se define una matriz de contrastes que especifica las comparaciones a realizar entre los grupos experimentales: “Basal” versus “LP”, “Basal” versus “ML” y “LP” versus “ML”.

Se aplican modificaciones al modelo lineal para analizar los datos de expresión diferencial utilizando el método voom del paquete limma. Este proceso incluye la transformación de los datos en bruto y normalizados, así como la aplicación de ajustes de modelos lineales y el análisis bayesiano para determinar la significancia de las comparaciones.

Código
# Transformación de datos en bruto utilizando voom
v.raw <- voom(x, design, plot=TRUE)
title(sub="Datos brutos")

Código
# Transformación de datos normalizados utilizando voom
v.norm <- voom(x.norm, design, plot=TRUE)
title(sub="Datos filtrados y normalizados")

En la Gráfica 3.1 (Datos brutos), se observa una tendencia decreciente en la relación entre la media y la varianza de los datos de expresión, con una alta dispersión en las desviaciones estándar para los valores de cuenta más bajos. Esto indica una gran variabilidad en los datos en bruto. Por otro lado, en la Gráfica 3.2 (Datos filtrados y normalizados), la tendencia media-varianza muestra una relación más estable y ajustada, con una menor dispersión en las desviaciones estándar, especialmente para los valores de cuenta intermedios y altos. La reducción de la variabilidad después del filtrado y la normalización sugiere que estos pasos han mejorado la calidad de los datos.

Código
### Comparación en el modelo lineal ###
# Ajuste del modelo lineal para datos en bruto
vfit.raw <- lmFit(v.raw, design)
vfit.raw <- contrasts.fit(vfit.raw, contrasts=contr.matrix)
efit.raw <- eBayes(vfit.raw)

# Ajuste del modelo lineal para datos normalizados
vfit.norm <- lmFit(v.norm, design)
vfit.norm <- contrasts.fit(vfit.norm, contrasts=contr.matrix)
efit.norm <- eBayes(vfit.norm)

Se han realizado entonces varias etapas de análisis para permitir identificar los genes diferencialmente expresados entre los diversos grupos experimentales.:

  1. Transformación con voom: Se transforman los datos en bruto y normalizados utilizando el método voom, que ajusta la media-variancia de los datos para hacerlos aptos para el análisis lineal. Se generan gráficos de los datos transformados para visualización.

  2. Ajuste del modelo lineal: Se aplica el modelo lineal a los datos transformados, tanto en bruto como normalizados. Esto se hace mediante la función lmFit que ajusta el modelo lineal a los datos.

  3. Contrastes y ajuste bayesiano: Se aplican los contrastes especificados en la matriz de contrastes utilizando contrasts.fit, y luego se realiza un ajuste bayesiano con eBayes para determinar la significancia estadística de las comparaciones entre los grupos experimentales.

Se va a proceder inspeccionando la normalización de los datos de expresión diferencial mediante la visualización de la relación media-varianza utilizando el modelo final ajustado.

Código
# Datos brutos
plotSA(efit.raw, main="Final model: Mean−variance trend")
title(sub="Datos brutos")

Código
# Datos normalizados
plotSA(efit.norm, main="Final model: Mean−variance trend")
title(sub="Datos filtrados y normalizados")

En las Gráficas 3.3 y 3.4, se compara la tendencia media-varianza para los datos en bruto y los datos filtrados y normalizados, respectivamente. La Gráfica 3.3 muestra una considerable dispersión en la desviación estándar en función de la expresión media logarítmica, con muchos puntos desviándose significativamente de la línea de referencia de 1.0, especialmente en los valores de expresión más bajos y más altos. Esto indica una gran variabilidad inherente en los datos originales. En contraste, la Gráfica 3.4 presenta una dispersión mucho menor y más consistente a lo largo de diferentes niveles de expresión media logarítmica, con la mayoría de los puntos más cercanos a la línea de referencia de 1.0. Esta menor variabilidad después del filtrado y la normalización sugiere que estos pasos han mejorado significativamente la calidad de los datos, haciendo que las mediciones de expresión sean más comparables y precisas para el análisis diferencial.

4 Test de Múltiples Comparaciones

Finalmente, se utilizará este código para identificar y resumir el número de genes expresados diferencialmente en diferentes comparaciones basadas en el valor p y el cambio de pliegue logarítmico (logFC) en datos normalizados y en datos en bruto.

Código
### Esta función muestra el número de genes que se expresa de forma diferencial por pvalue en cada comparación ###

# Sobre los datos normalizados
knitr::kable(summary(decideTests(efit.norm)))
BasalvsLP BasalvsML LPvsML
Down 4019 4312 2490
NotSig 5859 5595 9639
Up 4287 4258 2036
Código
# Sobre los datos brutos
knitr::kable(summary(decideTests(efit.raw)))
BasalvsLP BasalvsML LPvsML
Down 3877 5004 3472
NotSig 17519 17182 22163
Up 5783 4993 1544
Código
### Otro filtro muy utilizado es las veces de cambio en base logarítmica, logFC ###

# lfc: logarithm of fold change; 1 significa un FC 2^1 = 2
# treat() es una función alternativa a eBayes() para tener en cuenta el logFC
tfit <- treat(vfit.norm, lfc=1)
dt <- decideTests(tfit)
knitr::kable(summary(dt))
BasalvsLP BasalvsML LPvsML
Down 1298 1455 152
NotSig 11153 10917 13899
Up 1714 1793 114
Código
# Veamos lo mismo con los datos sin filtrar ni normalizar
tfit.raw <- treat(vfit.raw, lfc=1)
dt.raw <- decideTests(tfit.raw)
knitr::kable(summary(dt.raw))
BasalvsLP BasalvsML LPvsML
Down 1397 1779 277
NotSig 23539 23229 26792
Up 2243 2171 110

En este código, se realizan las siguientes acciones:

  1. Identificación de genes expresados diferencialmente por valor p:
    • Datos normalizados: Se utiliza la función decideTests sobre el objeto efit.norm para identificar los genes que se expresan de forma diferencial en las comparaciones especificadas en la matriz de diseño. El resumen de estos resultados se muestra con summary.
    • Datos brutos: Se realiza el mismo procedimiento sobre los datos en bruto utilizando el objeto efit.raw.
  2. Filtrado por cambio de pliegue logarítmico (logFC):
    • Datos normalizados: Se utiliza la función treat en lugar de eBayes para tener en cuenta el logFC. Un logFC de 1 significa un cambio de pliegue de 2^1 = 2. El objeto resultante tfit se pasa a decideTests para identificar los genes diferencialmente expresados, y se muestra un resumen de estos resultados.
    • Datos brutos: Se repite el mismo procedimiento para los datos en bruto utilizando el objeto vfit.raw.

Finalmente, se va a proceder a comparar la expresión diferencial de genes entre las condiciones “BasalvsLP” y “BasalvsML”, identificándose la intersección de genes diferencialmente expresados en ambas comparaciones, y se visualizan y guardan los resultados.

Código
# Dibujamos un diagrama de Venn para representar las comparaciones
vennDiagram(dt[,1:2], circle.col=c("turquoise", "salmon"))

El diagrama de Venn muestra la comparación de genes con expresión diferencial entre las condiciones “BasalvsLP” y “BasalvsML”. En este diagrama, el círculo izquierdo representa los genes diferencialmente expresados en la comparación “BasalvsLP”, mientras que el círculo derecho representa los genes diferencialmente expresados en la comparación “BasalvsML”. Se observa que 672 genes son exclusivos de la comparación “BasalvsLP”, 908 genes son exclusivos de la comparación “BasalvsML”, y 2340 genes son comunes a ambas comparaciones. El número total de genes analizados es 10245. Estos resultados indican que hay una considerable superposición de genes con expresión diferencial entre las dos condiciones comparadas, lo que sugiere que existen cambios comunes en la expresión génica cuando se comparan las condiciones Basal con LP y Basal con ML.

Código
### Comparamos los genes con expresión diferencial entre las condiciones BasalvsLP y BasalvsML ###

# Identificación de genes expresados diferencialmente en ambas comparaciones
de.common <- which(dt[,1] != 0 & dt[,2] != 0)

# ¿Cuántos son?
length(de.common)
[1] 2340
Código
# ¿Cómo se llaman los 20 primeros?
head(tfit$genes$SYMBOL[de.common], n=20)
 [1] "Xkr4"     "Rgs20"    "Cpa6"     "Sulf1"    "Eya1"     "Msc"     
 [7] "Sbspon"   "Pi15"     "Crispld1" "Kcnq5"    "Ptpn18"   "Arhgef4" 
[13] "Cracdl"   "Aff3"     "Npas2"    "Tbc1d8"   "Creg2"    "Il1r1"   
[19] "Il18r1"   "Ecrg4"   
Código
### Escribimos los resultados ###
write.fit(tfit, dt, file="all_genes_results.txt")

En este código, se realizan las siguientes acciones:

  1. Identificación de genes con expresión diferencial común:
    • Se determina qué genes están expresados diferencialmente en ambas comparaciones (“BasalvsLP” y “BasalvsML”) utilizando la función which y la condición dt[,1] != 0 & dt[,2] != 0. Los índices de estos genes se almacenan en de.common.
  2. Conteo y visualización de genes:
    • Se cuenta el número de genes en común utilizando length(de.common).
    • Se muestran los nombres de los primeros 20 genes comunes utilizando head(tfit$genes$SYMBOL[de.common], n=20).
  3. Visualización con diagrama de Venn:
    • Se genera un diagrama de Venn para representar visualmente la superposición de genes expresados diferencialmente en las dos comparaciones.